From 78dff2fd3da2a88438c85f4b08c1eac87631685b Mon Sep 17 00:00:00 2001 From: Jason <83615043+JJassonn69@users.noreply.github.com> Date: Wed, 15 Apr 2026 11:35:36 +0300 Subject: [PATCH] =?UTF-8?q?Revert=20"Add=20UM982=20GPS=20driver=20(um982?= =?UTF-8?q?=5Fgps.h/.cpp)=20for=20NMEA=20sentence=20parsing=20and=E2=80=A6?= =?UTF-8?q?"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../9_1_3_C_Cpp_Code/main.cpp | 95 +-- .../9_1_3_C_Cpp_Code/um982_gps.cpp | 684 ------------------ .../9_1_3_C_Cpp_Code/um982_gps.h | 146 ---- 3 files changed, 24 insertions(+), 901 deletions(-) delete mode 100755 9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.cpp delete mode 100755 9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.h diff --git a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp b/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp index e5dabca..09468d0 100644 --- a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp +++ b/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp @@ -24,7 +24,6 @@ #include "adar1000.h" #include "ADAR1000_Manager.h" #include "ADAR1000_AGC.h" -#include "um982_gps.h" extern "C" { #include "ad9523.h" } @@ -122,8 +121,8 @@ UART_HandleTypeDef huart5; UART_HandleTypeDef huart3; /* USER CODE BEGIN PV */ -// Global UM982 instance -UM982_GPS* um982_gps = nullptr; +// The TinyGPSPlus object +TinyGPSPlus gps; // Global data structures GPS_Data_t current_gps_data = {0}; @@ -323,52 +322,6 @@ void delay_ns(uint32_t nanoseconds) while ((DWT->CYCCNT - start_cycles) < cycles); } -////////////////////////////////////////////// -////////////////////UM982GPS////////////////// -////////////////////////////////////////////// -void initUM982GPS() { - // Initialize UM982 on UART5 (same as your current GPS) - um982_gps = new UM982_GPS(&huart5); - - if (um982_gps->init(true, true, 1.0f, 10)) { - uint8_t msg[] = "UM982 GPS initialized successfully\r\n"; - HAL_UART_Transmit(&huart3, msg, sizeof(msg)-1, 1000); - - } else { - uint8_t msg[] = "UM982 GPS initialization failed\r\n"; - HAL_UART_Transmit(&huart3, msg, sizeof(msg)-1, 1000); - } -} - -void updateGPSData() { - if (um982_gps) { - um982_gps->process(); - - if (um982_gps->isDataUpdated()) { - RADAR_Latitude = um982_gps->getLatitude(); - RADAR_Longitude = um982_gps->getLongitude(); - - // Update heading for stepper motor alignment - float heading = um982_gps->getHeading(); - - // Use heading for North alignment - if (um982_gps->hasRTKFix()) { - // Use RTK heading for precise alignment - // Adjust stepper motor based on true heading - } - - // Update GPS data structure for GUI - current_gps_data.latitude = RADAR_Latitude; - current_gps_data.longitude = RADAR_Longitude; - current_gps_data.altitude = um982_gps->getAltitude(); - current_gps_data.pitch = Pitch_Sensor; // From IMU - current_gps_data.timestamp = HAL_GetTick(); - - // Send to GUI - GPS_SendBinaryToGUI(¤t_gps_data); - } - } -} ////////////////////////////////////////////// //////////////////////RADAR/////////////////// ////////////////////////////////////////////// @@ -794,7 +747,7 @@ SystemError_t checkSystemHealth(void) { DIAG_ERR("SYS", "checkSystemHealth returning error code %d", current_error); } return current_error; -} +} // Error recovery function void attemptErrorRecovery(SystemError_t error) { @@ -1502,10 +1455,8 @@ int main(void) HAL_GPIO_WritePin(EN_P_3V3_FPGA_GPIO_Port,EN_P_3V3_FPGA_Pin,GPIO_PIN_SET); HAL_Delay(100); DIAG("PWR", "FPGA power sequencing complete -- 1.0V -> 1.8V -> 3.3V"); - - // Initialize module UM982GPS - initUM982GPS(); - + + // Initialize module IMU DIAG_SECTION("IMU INIT (GY-85)"); DIAG("IMU", "Initializing GY-85 IMU..."); @@ -1514,12 +1465,12 @@ int main(void) Error_Handler(); } DIAG("IMU", "GY-85 initialized OK, running 10 calibration samples"); - for(int i=0; i<10;i++){ - if (!GY85_Update(&imu)) { - Error_Handler(); - } - - ax = imu.ax; + for(int i=0; i<10;i++){ + if (!GY85_Update(&imu)) { + Error_Handler(); + } + + ax = imu.ax; ay = imu.ay; az = imu.az; gx = -imu.gx; @@ -1612,7 +1563,7 @@ int main(void) float magRawX = mx*cos(Pitch_Sensor*PI/180.0f) - mz*sin(Pitch_Sensor*PI/180.0f); float magRawY = mx*sin(Roll_Sensor*PI/180.0f)*sin(Pitch_Sensor*PI/180.0f) + my*cos(Roll_Sensor*PI/180.0f)- mz*sin(Roll_Sensor*PI/180.0f)*cos(Pitch_Sensor*PI/180.0f); - Yaw_Sensor = heading - Mag_Declination; + Yaw_Sensor = (180*atan2(magRawY,magRawX)/PI) - Mag_Declination; if(Yaw_Sensor<0)Yaw_Sensor+=360; RxEst_0 = RxEst_1; @@ -1791,7 +1742,9 @@ int main(void) //////////////////////////////////////////GPS///////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// for(int i=0; i<10;i++){ - updateGPSData(); + smartDelay(1000); + RADAR_Longitude = gps.location.lng(); + RADAR_Latitude = gps.location.lat(); } //move Stepper to position 1 = 0° @@ -1808,14 +1761,14 @@ int main(void) /**********wait for GUI start flag and Send Lat/Long/alt********/ /***************************************************************/ - GPS_Data_t gps_data; - // Binary packet structure: - // [Header 4 bytes][Latitude 8 bytes][Longitude 8 bytes][Altitude 4 bytes][Pitch 4 bytes][CRC 2 bytes] - gps_data = {RADAR_Latitude, RADAR_Longitude, RADAR_Altitude, Pitch_Sensor, HAL_GetTick()}; - if (!GPS_SendBinaryToGUI(&gps_data)) { - const uint8_t gps_send_error[] = "GPS binary send failed\r\n"; - HAL_UART_Transmit(&huart3, (uint8_t*)gps_send_error, sizeof(gps_send_error) - 1, 1000); - } + GPS_Data_t gps_data; + // Binary packet structure: + // [Header 4 bytes][Latitude 8 bytes][Longitude 8 bytes][Altitude 4 bytes][Pitch 4 bytes][CRC 2 bytes] + gps_data = {RADAR_Latitude, RADAR_Longitude, RADAR_Altitude, Pitch_Sensor, HAL_GetTick()}; + if (!GPS_SendBinaryToGUI(&gps_data)) { + const uint8_t gps_send_error[] = "GPS binary send failed\r\n"; + HAL_UART_Transmit(&huart3, (uint8_t*)gps_send_error, sizeof(gps_send_error) - 1, 1000); + } // Check if start flag was received and settings are ready do{ @@ -2614,7 +2567,7 @@ static void MX_UART5_Init(void) /* USER CODE END UART5_Init 1 */ huart5.Instance = UART5; - huart5.Init.BaudRate = 115200; + huart5.Init.BaudRate = 9600; huart5.Init.WordLength = UART_WORDLENGTH_8B; huart5.Init.StopBits = UART_STOPBITS_1; huart5.Init.Parity = UART_PARITY_NONE; diff --git a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.cpp b/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.cpp deleted file mode 100755 index df249e2..0000000 --- a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.cpp +++ /dev/null @@ -1,684 +0,0 @@ -// um982_gps.cpp -#include "um982_gps.h" -#include - -// UM982 Default NMEA Commands -#define UM982_CMD_RESET "RESET" -#define UM982_CMD_SAVE_CONFIG "SAVECONFIG" -#define UM982_CMD_RATE_1HZ "GPTHS COM1 1" -#define UM982_CMD_RATE_5HZ "GPTHS COM1 0.2" -#define UM982_CMD_RATE_10HZ "GPTHS COM1 0.1" -#define UM982_CMD_RATE_20HZ "GPTHS COM1 0.05" -#define UM982_CMD_ENABLE_RTK "CONFIG RTK RELIABILITY 3 1" -#define UM982_CMD_DISABLE_RTK "CONFIG RTK DISABLE" -#define UM982_CMD_HEADING_FIXLENGTH "CONFIG HEADING FIXLENGTH" -#define UM982_CMD_HEADING_LENGTH "CONFIG HEADING LENGTH %.1f" - -// NMEA Sentence Starters -#define NMEA_GGA_START "GGA" -#define NMEA_RMC_START "RMC" -#define NMEA_GSA_START "GSA" -#define NMEA_VTG_START "VTG" -#define NMEA_GPTHS_START "GNTHS" // UM982 Heading/Track | "GNTHS" is correct, The Output Message is: $GNTHS,341.3065,A*1F - -// Constructor -UM982_GPS::UM982_GPS(UART_HandleTypeDef *huart) - : uart_(huart), buffer_index_(0), data_updated_(false), last_update_ms_(0) -{ - - if (uart_ == nullptr) - { - return; - } - - memset(&data_, 0, sizeof(UM982_Data_t)); - memset(&last_data_, 0, sizeof(UM982_Data_t)); - memset(rx_buffer_, 0, sizeof(rx_buffer_)); -} - -UM982_GPS::~UM982_GPS() -{ - // Cleanup if needed -} - -// Initialization -bool UM982_GPS::init(bool enable_rtk, bool enable_heading, float baseline_m, byte update_rate) -{ - // Clear buffer - resetBuffer(); - - // Wait for UM982 to stabilize - HAL_Delay(1000); - - if (enable_rtk) - { - sendCommand(UM982_CMD_ENABLE_RTK); - HAL_Delay(50); - } - else - { - sendCommand(UM982_CMD_DISABLE_RTK); - HAL_Delay(50); - } - - if (enable_heading) - { - sendCommand(UM982_CMD_HEADING_FIXLENGTH); - HAL_Delay(50); - - char len_cmd[64]; - snprintf(len_cmd, sizeof(len_cmd), UM982_CMD_HEADING_LENGTH, baseline_m); - sendCommand(len_cmd); - HAL_Delay(50); - } - - switch (update_rate) - { - case 1: - sendCommand(UM982_CMD_RATE_1HZ); - break; - case 5: - sendCommand(UM982_CMD_RATE_5HZ); - break; - case 10: - sendCommand(UM982_CMD_RATE_10HZ); - break; - case 20: - sendCommand(UM982_CMD_RATE_20HZ); - break; - default: - sendCommand(UM982_CMD_RATE_10HZ); - break; - } - HAL_Delay(100); - - sendCommand(UM982_CMD_SAVE_CONFIG); - HAL_Delay(300); - - return true; -} - -// Set update rate -bool UM982_GPS::setUpdateRate(uint8_t hz) -{ - const char *cmd; - - switch (hz) - { - case 1: - cmd = UM982_CMD_RATE_1HZ; - break; - case 5: - cmd = UM982_CMD_RATE_5HZ; - break; - case 10: - cmd = UM982_CMD_RATE_10HZ; - break; - case 20: - cmd = UM982_CMD_RATE_20HZ; - break; - default: - cmd = UM982_CMD_RATE_10HZ; - break; - } - - sendCommand(cmd); - HAL_Delay(100); - return true; -} - -// Set RTK mode -bool UM982_GPS::setRTKMode(bool enable) -{ - if (enable) - { - sendCommand(UM982_CMD_ENABLE_RTK); - } - else - { - sendCommand(UM982_CMD_DISABLE_RTK); - } - - HAL_Delay(100); - return true; -} - -// Save configuration to flash -bool UM982_GPS::saveConfiguration() -{ - sendCommand(UM982_CMD_SAVE_CONFIG); - HAL_Delay(500); - return true; -} - -// Send command to UM982 -void UM982_GPS::sendCommand(const char *command) -{ - if (command == nullptr || uart_ == nullptr) - return; - if (strlen(command) > 240) - return; - - HAL_UART_Transmit(uart_, (uint8_t *)command, strlen(command), 100); -} - -// Process incoming data (call in main loop) -void UM982_GPS::process() -{ - uint8_t data; - - // Read all available bytes - while (HAL_UART_Receive(uart_, &data, 1, 0) == HAL_OK) - { - processByte(data); - } -} - -bool UM982_GPS::processByte(uint8_t data) -{ - // Start of new sentence - if (data == '$') - { - resetBuffer(); - rx_buffer_[buffer_index_++] = data; - return true; - } - - // End of sentence (accept both \r\n and \n only) - if ((data == '\n' || data == '\r') && buffer_index_ > 0) - { - if (data == '\n') - { - rx_buffer_[buffer_index_] = '\0'; - - const char *sentence = rx_buffer_ + 1; // skip '$' - NMEA_SentenceType type = identifySentence(sentence); - - // Only parse if checksum is valid - if (verifyNMEAChecksum(rx_buffer_)) - { - switch (type) - { - case NMEA_GGA: - parseGGA(sentence); - break; - case NMEA_RMC: - parseRMC(sentence); - break; - case NMEA_GSA: - parseGSA(sentence); - break; - case NMEA_VTG: - parseVTG(sentence); - break; - case NMEA_GPTHS: - parseGPTHS(sentence); - break; - default: - break; - } - } - - resetBuffer(); - } - return true; - } - - // Store byte if buffer not full - if (buffer_index_ < sizeof(rx_buffer_) - 1) - { - rx_buffer_[buffer_index_++] = data; - } - - return true; -} - -bool UM982_GPS::verifyNMEAChecksum(const char *sentence) -{ - const char *asterisk = strchr(sentence, '*'); - if (!asterisk || asterisk[3] != '\0') - return false; // must have *XX - - uint8_t calculated = 0; - for (const char *p = sentence + 1; p < asterisk; ++p) - { - calculated ^= *p; - } - - uint8_t received = (uint8_t)strtol(asterisk + 1, NULL, 16); - return calculated == received; -} - -// Identify NMEA sentence type -NMEA_SentenceType UM982_GPS::identifySentence(const char *sentence) -{ - if (strncmp(sentence, NMEA_GGA_START, 3) == 0) - return NMEA_GGA; - if (strncmp(sentence, NMEA_RMC_START, 3) == 0) - return NMEA_RMC; - if (strncmp(sentence, NMEA_GSA_START, 3) == 0) - return NMEA_GSA; - if (strncmp(sentence, NMEA_VTG_START, 3) == 0) - return NMEA_VTG; - if (strncmp(sentence, NMEA_GPTHS_START, 5) == 0) - return NMEA_GPTHS; - return NMEA_UNKNOWN; -} - -// Parse GGA sentence (time, position, fix type) -bool UM982_GPS::parseGGA(const char *sentence) -{ - char buffer[32]; - int field = 0; - const char *ptr = sentence; - - while (*ptr && *ptr != '*') - { - if (*ptr == ',' || *ptr == '\r') - { - field++; - ptr++; - continue; - } - - // Extract field based on position - int i = 0; - while (*ptr && *ptr != ',' && *ptr != '\r' && i < 31) - { - buffer[i++] = *ptr++; - } - buffer[i] = '\0'; - - switch (field) - { - case 0: // Skip "GGA" - break; - case 1: // UTC Time (HHMMSS.SS) - if (strlen(buffer) >= 6) - { - data_.utc_hour = (buffer[0] - '0') * 10 + (buffer[1] - '0'); - data_.utc_minute = (buffer[2] - '0') * 10 + (buffer[3] - '0'); - data_.utc_second = (buffer[4] - '0') * 10 + (buffer[5] - '0'); - } - break; - case 2: // Latitude - { - char lat_str[16]; - strcpy(lat_str, buffer); - // Next field is hemisphere - while (*ptr && (*ptr == ',' || *ptr == '\r')) - ptr++; - char hem = *ptr; - data_.latitude = parseNMEACoordinate(lat_str, hem); - } - break; - case 3: // Skip hemisphere (already processed) - break; - case 4: // Longitude - { - char lon_str[16]; - strcpy(lon_str, buffer); - while (*ptr && (*ptr == ',' || *ptr == '\r')) - ptr++; - char hem = *ptr; - data_.longitude = parseNMEACoordinate(lon_str, hem); - } - break; - case 5: // Skip hemisphere - break; - case 6: // Fix quality - data_.fix_type = (RTK_FixType)parseNMEAInt(buffer); - break; - case 7: // Number of satellites - data_.sat_count = parseNMEAInt(buffer); - break; - case 8: // HDOP - data_.hdop = parseNMEAFloat(buffer); - break; - case 9: // Altitude - data_.altitude = parseNMEAFloat(buffer); - break; - default: - break; - } - - // Skip to next field - while (*ptr && *ptr != ',') - ptr++; - } - - data_.position_valid = (data_.fix_type >= RTK_SINGLE); - data_.time_valid = true; - updateData(); - - return true; -} - -// Parse RMC sentence (recommended minimum - includes heading) -bool UM982_GPS::parseRMC(const char *sentence) -{ - char buffer[32]; - int field = 0; - const char *ptr = sentence; - - while (*ptr && *ptr != '*') - { - if (*ptr == ',' || *ptr == '\r') - { - field++; - ptr++; - continue; - } - - int i = 0; - while (*ptr && *ptr != ',' && *ptr != '\r' && i < 31) - { - buffer[i++] = *ptr++; - } - buffer[i] = '\0'; - - switch (field) - { - case 0: // Skip "RMC" - break; - case 1: // UTC Time - if (strlen(buffer) >= 6) - { - data_.utc_hour = (buffer[0] - '0') * 10 + (buffer[1] - '0'); - data_.utc_minute = (buffer[2] - '0') * 10 + (buffer[3] - '0'); - data_.utc_second = (buffer[4] - '0') * 10 + (buffer[5] - '0'); - } - break; - case 2: // Status (A=valid, V=invalid) - data_.data_valid = (buffer[0] == 'A'); - break; - case 3: // Latitude - { - char lat_str[16]; - strcpy(lat_str, buffer); - while (*ptr && (*ptr == ',' || *ptr == '\r')) - ptr++; - char hem = *ptr; - data_.latitude = parseNMEACoordinate(lat_str, hem); - } - break; - case 4: // Skip hemisphere - break; - case 5: // Longitude - { - char lon_str[16]; - strcpy(lon_str, buffer); - while (*ptr && (*ptr == ',' || *ptr == '\r')) - ptr++; - char hem = *ptr; - data_.longitude = parseNMEACoordinate(lon_str, hem); - } - break; - case 6: // Skip hemisphere - break; - case 7: // Speed over ground (knots) - data_.ground_speed_knots = parseNMEAFloat(buffer); - data_.ground_speed_kmh = data_.ground_speed_knots * 1.852f; - data_.ground_speed_ms = data_.ground_speed_knots * 0.514444f; - break; - case 8: // Track angle (heading) - data_.heading = parseNMEAFloat(buffer); - data_.heading_valid = true; - break; - case 9: // Date (DDMMYY) - if (strlen(buffer) >= 6) - { - // Date is available but we may not need it - } - break; - default: - break; - } - - while (*ptr && *ptr != ',') - ptr++; - } - - data_.position_valid = data_.data_valid; - updateData(); - - return true; -} - -// Parse GSA sentence (DOP and active satellites) -bool UM982_GPS::parseGSA(const char *sentence) -{ - char buffer[32]; - int field = 0; - const char *ptr = sentence; - - while (*ptr && *ptr != '*') - { - if (*ptr == ',' || *ptr == '\r') - { - field++; - ptr++; - continue; - } - - int i = 0; - while (*ptr && *ptr != ',' && *ptr != '\r' && i < 31) - { - buffer[i++] = *ptr++; - } - buffer[i] = '\0'; - - switch (field) - { - case 0: // Skip "GSA" - break; - case 1: // Mode (M=manual, A=auto) - break; - case 2: // Fix type (1=no fix, 2=2D, 3=3D) - break; - case 15: // PDOP - data_.pdop = parseNMEAFloat(buffer); - break; - case 16: // HDOP - data_.hdop = parseNMEAFloat(buffer); - break; - case 17: // VDOP - data_.vdop = parseNMEAFloat(buffer); - break; - default: - break; - } - - while (*ptr && *ptr != ',') - ptr++; - } - - return true; -} - -// Parse VTG sentence (course and speed) -bool UM982_GPS::parseVTG(const char *sentence) -{ - char buffer[32]; - int field = 0; - const char *ptr = sentence; - - while (*ptr && *ptr != '*') - { - if (*ptr == ',' || *ptr == '\r') - { - field++; - ptr++; - continue; - } - - int i = 0; - while (*ptr && *ptr != ',' && *ptr != '\r' && i < 31) - { - buffer[i++] = *ptr++; - } - buffer[i] = '\0'; - - switch (field) - { - case 0: // Skip "VTG" - break; - case 1: // True track (heading) - data_.heading = parseNMEAFloat(buffer); - data_.heading_valid = true; - break; - case 2: // Skip "T" - break; - case 3: // Magnetic track (skip) - break; - case 4: // Skip "M" - break; - case 5: // Speed (knots) - data_.ground_speed_knots = parseNMEAFloat(buffer); - data_.ground_speed_kmh = data_.ground_speed_knots * 1.852f; - data_.ground_speed_ms = data_.ground_speed_knots * 0.514444f; - break; - default: - break; - } - - while (*ptr && *ptr != ',') - ptr++; - } - - return true; -} - -// Parse GPTHS sentence (UM982 proprietary heading) -bool UM982_GPS::parseGPTHS(const char *sentence) -{ - char buffer[32]; - int field = 0; - const char *ptr = sentence; - - while (*ptr && *ptr != '*') - { - if (*ptr == ',' || *ptr == '\r') - { - field++; - ptr++; - continue; - } - - int i = 0; - while (*ptr && *ptr != ',' && *ptr != '\r' && i < 31) - { - buffer[i++] = *ptr++; - } - buffer[i] = '\0'; - - switch (field) - { - case 0: // Skip "GNTHS" - break; - case 1: // Heading (True North) - data_.heading = parseNMEAFloat(buffer); - data_.heading_valid = true; - break; - case 2: // Status (A/V) - data_.data_valid = (buffer[0] == 'A'); - break; - default: - break; - } - - while (*ptr && *ptr != ',') - ptr++; - } - - updateData(); - return true; -} - -// Parse NMEA coordinate (DDMM.MMMMM format) -double UM982_GPS::parseNMEACoordinate(const char *coord, char hemisphere) -{ - if (coord == nullptr || strlen(coord) < 4) - return 0.0; - - // Find decimal point position - int dot_pos = 0; - while (coord[dot_pos] != '.' && dot_pos < (int)strlen(coord)) - { - dot_pos++; - } - - // Degrees are the first 2 digits before decimal - int degrees = 0; - if (dot_pos >= 2) - { - degrees = (coord[0] - '0') * 10 + (coord[1] - '0'); - } - - // Minutes are the rest - double minutes = atof(coord + 2); - - double decimal = degrees + minutes / 60.0; - - // Apply hemisphere (S or W = negative) - if (hemisphere == 'S' || hemisphere == 'W') - { - decimal = -decimal; - } - - return decimal; -} - -// Parse NMEA float value -float UM982_GPS::parseNMEAFloat(const char *str) -{ - if (str == NULL || strlen(str) == 0) - return 0.0f; - return atof(str); -} - -// Parse NMEA integer value -uint32_t UM982_GPS::parseNMEAInt(const char *str) -{ - if (str == NULL || strlen(str) == 0) - return 0; - return atoi(str); -} - -// Update data and mark as updated -void UM982_GPS::updateData() -{ - data_.timestamp_ms = HAL_GetTick(); - - // Check if data has changed significantly - if (fabs(data_.latitude - last_data_.latitude) > 1e-6 || - fabs(data_.longitude - last_data_.longitude) > 1e-6 || - fabs(data_.heading - last_data_.heading) > 0.1f) - { - - data_updated_ = true; - last_update_ms_ = data_.timestamp_ms; - memcpy(&last_data_, &data_, sizeof(UM982_Data_t)); - } -} - -// Check if data has been updated -bool UM982_GPS::isDataUpdated() -{ - bool updated = data_updated_; - data_updated_ = false; - return updated; -} - -// Get complete data structure -UM982_Data_t UM982_GPS::getData() -{ - return data_; -} - -// Reset receive buffer -void UM982_GPS::resetBuffer() -{ - memset(rx_buffer_, 0, sizeof(rx_buffer_)); - buffer_index_ = 0; -} \ No newline at end of file diff --git a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.h b/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.h deleted file mode 100755 index bfb8d4f..0000000 --- a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/um982_gps.h +++ /dev/null @@ -1,146 +0,0 @@ -// um982_gps.h -#ifndef UM982_GPS_H -#define UM982_GPS_H - -#include "main.h" -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// UM982 NMEA Sentence Types -typedef enum { - NMEA_UNKNOWN = 0, - NMEA_GGA, // Global Positioning System Fix Data - NMEA_RMC, // Recommended Minimum Specific GNSS Data - NMEA_GSA, // GNSS DOP and Active Satellites - NMEA_GSV, // GNSS Satellites in View - NMEA_VTG, // Course Over Ground and Ground Speed - NMEA_GLL, // Geographic Position - Latitude/Longitude - NMEA_ZDA, // Time and Date - NMEA_GPTHS, // Heading/Track from UM982 - NMEA_PASH // Proprietary UM982 messages -} NMEA_SentenceType; - -// UM982 RTK Status -typedef enum { - RTK_FIX_INVALID = 0, - RTK_SINGLE = 1, // Single point positioning - RTK_DGPS = 2, // Differential GPS (SBAS) - RTK_FLOAT = 4, // Float RTK - RTK_FIXED = 5, // Fixed RTK (centimeter precision) - RTK_DEAD_RECKON = 6 // Dead reckoning -} RTK_FixType; - -// UM982 Navigation Status -typedef struct { - // Position - double latitude; // Degrees (negative = South) - double longitude; // Degrees (negative = West) - float altitude; // Meters (MSL) - float geoid_separation; // Geoid separation (WGS84) - - // Time - uint32_t utc_hour; - uint32_t utc_minute; - uint32_t utc_second; - uint32_t utc_millisecond; - uint32_t timestamp_ms; // System timestamp when data was received - - // Course and Speed - float heading; // Degrees (0-360, True North) - float ground_speed_knots; // Speed over ground in knots - float ground_speed_kmh; // Speed over ground in km/h - float ground_speed_ms; // Speed over ground in m/s - - // Accuracy and Quality - RTK_FixType fix_type; // RTK fix type - uint8_t sat_count; // Number of satellites used - float hdop; // Horizontal Dilution of Precision - float vdop; // Vertical Dilution of Precision - float pdop; // Position Dilution of Precision - - // RTK specific - float age_of_differential; // Age of differential corrections (seconds) - uint32_t differential_ref_station_id; - - // Validity flags - bool data_valid; - bool heading_valid; - bool position_valid; - bool time_valid; - -} UM982_Data_t; - -// UM982 Handler Class -class UM982_GPS { -public: - UM982_GPS(UART_HandleTypeDef* huart); - ~UM982_GPS(); - - // Initialization and Configuration - bool init(bool enable_rtk, bool enable_heading, float baseline_m, byte update_rate); - bool setUpdateRate(uint8_t hz); - bool setRTKMode(bool enable); - bool saveConfiguration(); - - // Data Processing - void process(); // Call in main loop to parse incoming data - bool processByte(uint8_t data); - bool isDataUpdated(); - - // Data Access - UM982_Data_t getData(); - double getLatitude() const { return data_.latitude; } - double getLongitude() const { return data_.longitude; } - float getHeading() const { return data_.heading; } - float getAltitude() const { return data_.altitude; } - RTK_FixType getFixType() const { return data_.fix_type; } - uint8_t getSatelliteCount() const { return data_.sat_count; } - - // Status - bool hasFix() const { return (data_.fix_type >= RTK_SINGLE); } - bool hasRTKFix() const { return (data_.fix_type == RTK_FIXED); } - bool isDataValid() const { return data_.data_valid; } - - // Utility - static double parseNMEACoordinate(const char* coord, char hemisphere); - static float parseNMEAFloat(const char* str); - static uint32_t parseNMEAInt(const char* str); - -private: - UART_HandleTypeDef* uart_; - UM982_Data_t data_; - UM982_Data_t last_data_; - UM982_Config_t config_; - - // NMEA Parsing - char rx_buffer_[256]; - uint16_t buffer_index_; - bool data_updated_; - uint32_t last_update_ms_; - - // Sentence parsing - NMEA_SentenceType identifySentence(const char* sentence); - bool parseGGA(const char* sentence); - bool parseRMC(const char* sentence); - bool parseGSA(const char* sentence); - bool parseVTG(const char* sentence); - bool parseGPTHS(const char* sentence); // UM982 proprietary heading sentence - - // Command generation - void sendCommand(const char* command); - - // Helper methods - void updateData(); - void resetBuffer(); -}; - -#ifdef __cplusplus -} -#endif - -#endif // UM982_GPS_H \ No newline at end of file