#include "bleService.h"
#include "chip_system_time.h"
-#include <custom_save_runtime.h>
#include "cmath"
+#include "system/include/SystemLogModel.h"
+#include <custom_save_runtime.h>
-extern "C" errcode_t uapi_get_timestampe_ms(uint32_t *tm);
-extern "C" errcode_t uapi_get_timestampe_ss(uint32_t *tm);
+#if defined(SUPPORT_GNSS)
+#include "NMEA0183.h"
+#include "gnss_ctl.h"
+#include "gnss_sample.h"
+#include "graphic_service.h"
+gps_data_t send_gps_data = {0};
+#endif
#ifdef __cplusplus
extern "C" {
delete traingbleInfo;
}
//增加训练runtime控制
- if (uapi_dev_runtime_get_train_status() == 0 || TraingModel::GetInstance()->GetSportState() == ExerciseState::End) {
+ if (uapi_dev_runtime_get_train_status() == 0 ||
+ TraingModel::GetInstance()->GetSportState() == ExerciseState::End) {
return;
}
//训练基本信息更新
uint8_t heart = *((u_int8_t *)(request->data)); // 进行类型转换
TraingModel::GetInstance()->AnalysisHeartData(heart);
}
+ //训练GPS
+ gps_data_t *gps_data = getGPSGlobaldata();
+ if (gps_data == NULL) {
+ PRINT("gps_data == NULL \n");
+ return;
+ }
+ //判断是否为第一次定位
+ if (gps_data->last_gps_time_ms > 0) {
+ memcpy_s(&send_gps_data, sizeof(gps_data_t), gps_data, sizeof(gps_data_t));
+ }
+ //判断是否定位成功
+ if (send_gps_data.status > 1) {
+ //添加经纬度 时间戳?
+ TraingModel::GetInstance()->AddGPSData(send_gps_data.location.lat,
+ send_gps_data.location.lng);
+ }
}
#ifdef __cplusplus
}
}
//最快配速
if (cyweeInfo->max_pace != 0) {
- sportdata->fpc =cyweeInfo->max_pace;
+ sportdata->fpc = cyweeInfo->max_pace;
}
//平均步频
if (cyweeInfo->avg_step_freq != 0) {
sportdata->spc = data->spc;
sportdata->std = data->std;
sportdata->cdc = data->cdc;
- printf_data(data);//打印该运动数据
+ printf_data(data); //打印该运动数据
IsSpecialSport(sportdata->sportId); // 配置训练特殊性
}
}
shock_count = 0; //重置震动计数
- gpsData.clear();// 清空gps数据
- canvasData.clear();// 清空画布数据
+ gpsData.clear(); // 清空gps数据
+ canvasData.clear(); // 清空画布数据
}
uint32_t TraingModel::get_current_time() {
//配置最后的训练强度(平均心率为标准)
SetIntensity(sportdata->avgheart);
+ //更新gps点位
+ GetPointData();
+
do_custom_fileoperate_service_check_msg(
CUSTOM_FILEOPERATE_MSG_TYPE_SPORTDATA_SAVE, nullptr, 0);
/*
Latitude(纬度):范围:-90° 至 +90°(或南纬 90° 至北纬 90°);
Longitude(经度):范围:-180° 至 +180°(或西经 180° 至东经 180°);
-
+
-画布数据集最多是100个定位坐标,超过按比例进行拿取100个点位;
-通过映射关系,将经纬度转换为400*400画布上的坐标;
-但是不能靠近400,以免显示不全等问题,350*350;
-如果有正数又有负数,应该怎么处理?
*/
-static double getmin(double a, double b)
-{
- return a < b ? a : b;
-}
+static double getmin(double a, double b) { return a < b ? a : b; }
-static double getmax(double a, double b)
-{
- return a > b ? a : b;
-}
+static double getmax(double a, double b) { return a > b ? a : b; }
// 通过经纬度数据集映射画布绘制轨迹坐标集
-void TraingModel::GetPointData()
-{
- // 1. 按比例采样最多100个点位
- std::vector<GPSData> sampledData;
- if (gpsData.size() > 100) {
- double step = static_cast<double>(gpsData.size() - 1) / 99;
- for (int i = 0; i < 100; i++) {
- int index = static_cast<int>(i * step);
- sampledData.push_back(gpsData[index]);
- }
- } else {
- sampledData = gpsData;
+void TraingModel::GetPointData() {
+ // 1. 按比例采样最多100个点位
+ std::vector<GPSData> sampledData;
+ if (gpsData.size() > 100) {
+ double step = static_cast<double>(gpsData.size() - 1) / 99;
+ for (int i = 0; i < 100; i++) {
+ int index = static_cast<int>(i * step);
+ sampledData.push_back(gpsData[index]);
}
+ } else {
+ sampledData = gpsData;
+ }
- // 2. 计算经纬度的最小值和最大值
- double minLat = 90.0, maxLat = -90.0;
- double minLon = 180.0, maxLon = -180.0;
- for (const auto& point : sampledData) {
- minLat = getmin(minLat, point.latitude);
- maxLat = getmax(maxLat, point.latitude);
- minLon = getmin(minLon, point.longitude);
- maxLon = getmax(maxLon, point.longitude);
- }
+ // 2. 计算经纬度的最小值和最大值
+ double minLat = 90.0, maxLat = -90.0;
+ double minLon = 180.0, maxLon = -180.0;
+ for (const auto &point : sampledData) {
+ minLat = getmin(minLat, point.latitude);
+ maxLat = getmax(maxLat, point.latitude);
+ minLon = getmin(minLon, point.longitude);
+ maxLon = getmax(maxLon, point.longitude);
+ }
- // 3. 将经纬度映射到350×350画布区域(居中在400×400画布)
- canvasData.clear();
- const double canvasSize = 350.0;
- const double offset = 25.0; // 400 - 350 = 50,两边各留25的边距
-
- for (const auto& point : sampledData) {
- // 归一化处理(0-1范围)
- double normLat = (point.latitude - minLat) / (maxLat - minLat);
- double normLon = (point.longitude - minLon) / (maxLon - minLon);
-
- // 映射到画布坐标(考虑偏移)
- double x = normLon * canvasSize + offset;
- double y = (1.0 - normLat) * canvasSize + offset; // 注意:y轴需要反转(屏幕坐标系向下为正)
-
- canvasData.push_back({x, y});
- }
+ // 3. 将经纬度映射到350×350画布区域(居中在400×400画布)
+ canvasData.clear();
+ const double canvasSize = 300.0;
+ const double offset = 50.0; // 400 - 300 = 100,两边各留50的边距
+
+ for (const auto &point : sampledData) {
+ // 归一化处理(0-1范围)
+ double normLat = (point.latitude - minLat) / (maxLat - minLat);
+ double normLon = (point.longitude - minLon) / (maxLon - minLon);
+
+ // 映射到画布坐标(考虑偏移)
+ double x = normLon * canvasSize + offset;
+ double y = (1.0 - normLat) * canvasSize +
+ offset; // 注意:y轴需要反转(屏幕坐标系向下为正)
+
+ canvasData.push_back({x, y});
+ }
+
+ //修改起点与终点
}
// 添加经纬度数据集
-void TraingModel::AddGPSData(double latitude, double longitude)
-{
- // 判断数据是否合理
- if (latitude < -90 || latitude > 90 || longitude < -180 || longitude > 180) {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid GPS data");
- return;
- }
- // 添加数据
- gpsData.push_back({latitude, longitude});
+void TraingModel::AddGPSData(uint32_t timestamp, double latitude,
+ double longitude) {
+ // 判断数据是否合理
+ if (latitude < -90 || latitude > 90 || longitude < -180 || longitude > 180) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid GPS data");
+ return;
+ }
+ // 添加数据
+ gpsData.push_back({latitude, longitude});
}
+// //保存
+// bool SaveCanvasData()
+// {
+
+// }
+
+// void ClearCanvasData()
+
+// std::string GetGPSDataPath(uint32_t timestamp)
+
// 获取轨迹点集
-std::vector<CanvasPoint> TraingModel::GetCanvasData() const
-{
- return canvasData;
-}
+std::vector<Point> TraingModel::GetCanvasData() const { return canvasData; }
//获取GPS连接状态
-bool TraingModel::GetGPSConnectState()
-{
- return gpsconnect;
-}
+bool TraingModel::GetGPSConnectState() { return gpsconnect; }
//设置GPS连接状态
-void TraingModel::SetGPSConnectState(bool state)
-{
+void TraingModel::SetGPSConnectState(bool state) {
+ if (gpsconnect != state) {
gpsconnect = state;
+ //状态改变记录
+ SystemLogModel::GetInstance()->save_gps_status_log_type(gpsconnect);
+ }
+}
+//开启gps
+void TraingModel::OpenGPS() {
+ // 开启GPS的代码逻辑
+ gnss_start();
+}
+//关闭gps
+void TraingModel::CloseGPS() {
+ // 关闭GPS的代码逻辑
+ gnss_stop();
+}
+//运动心率、gps开启准备
+void TraingModel::start_heart_gps() { OpenGPS(); }
+//运动心率、gps关闭
+void TraingModel::stop_heart_gps() { CloseGPS(); }
+
+/////////////////////////////////////gps定时器/////////////////////////////////////
+static osTimerId_t g_timer = nullptr;
+static int Time = 30;
+/*定时器到期时的处理*/
+static void Traing_TimerCallbackProc(int data) {
+ // 倒计时
+ Time--;
+ // 到时的处理
+ if (Time < 0) {
+ // TraingModel::GetInstance()->Traing_timer_callback_out();
+ // return;
+ }
+ gps_data_t *gps_data = getGPSGlobaldata();
+ if (gps_data == NULL) {
+ PRINT("gps_data == NULL \n");
+ return;
+ }
+ //判断是否为第一次定位
+ if (gps_data->last_gps_time_ms > 0) {
+ memcpy_s(&send_gps_data, sizeof(gps_data_t), gps_data, sizeof(gps_data_t));
+ }
+ //判断是否定位成功
+ if (send_gps_data.status > 1) {
+ //定位成功
+ TraingModel::GetInstance()->SetGPSConnectState(true);
+ } else {
+ TraingModel::GetInstance()->SetGPSConnectState(false);
+ }
+}
+/*
+ * @brief 回调函数
+ */
+static void Traing_TimerCallback(int data) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Traing_TimerCallback %d", data);
+ GraphicService::GetInstance()->PostGraphicEvent(
+ std::bind(Traing_TimerCallbackProc, data));
+}
+
+/*
+ * @brief 开启定时器函数
+ * @param interval 时间间隔,单位ms
+ */
+void TraingModel::Traing_StartTimer(uint32_t interval) {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "TraingModel::Traing_StartTimer");
+ /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回
+ * ------------------------- */
+ if (g_timer != nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer already exists!!");
+ return;
+ }
+
+ /* --------------------------------- 2.创建定时器
+ * -------------------------------- */
+ g_timer = osTimerNew((osTimerFunc_t)Traing_TimerCallback, osTimerPeriodic,
+ nullptr, nullptr);
+ // 检查定时器创建是否成功
+ if (g_timer == nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timer create failed!!");
+ return;
+ }
+
+ /* ----------------------------- 3.将毫秒转换为系统时钟节拍数
+ * ---------------------------- */
+ int tick = osMs2Tick(interval);
+
+ /* --------------------------------- 4.启动定时器
+ * -------------------------------- */
+ osStatus_t ret = osTimerStart(g_timer, tick);
+ /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为
+ * nullptr -------------------- */
+ if (ret != osOK) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!",
+ ret);
+ if (g_timer != nullptr) {
+ ret = osTimerDelete(g_timer);
+ }
+ g_timer = nullptr;
+ return;
+ }
+}
+/*
+ * @brief 停止定时器
+ */
+void TraingModel::Traing_StopTimer(void) {
+ // 检查定时器是否存在
+ if (g_timer != nullptr) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TraingModel::Traing_StopTimer");
+ osTimerStop(g_timer);
+ // 删除定时器并置为 nullptr
+ osStatus_t ret = osTimerDelete(g_timer);
+ if (ret != osOK) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+ "osTimerDelete failed, ret = %lx!!", ret);
+ }
+ g_timer = nullptr;
+ }
}
} // namespace OHOS