2023-11-28 06:24:44 -04:00
|
|
|
#include "SIM_config.h"
|
|
|
|
|
|
|
|
#if AP_SIM_GPS_MSP_ENABLED
|
|
|
|
|
|
|
|
#include "SIM_GPS_MSP.h"
|
|
|
|
|
|
|
|
#include <SITL/SITL.h>
|
|
|
|
|
2023-11-30 19:17:39 -04:00
|
|
|
#include <time.h>
|
2024-08-12 19:25:51 -03:00
|
|
|
#include <sys/time.h>
|
2023-11-30 19:17:39 -04:00
|
|
|
|
2023-11-28 06:24:44 -04:00
|
|
|
using namespace SITL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
send MSP GPS data
|
|
|
|
*/
|
|
|
|
void GPS_MSP::publish(const GPS_Data *d)
|
|
|
|
{
|
|
|
|
struct PACKED {
|
|
|
|
// header
|
|
|
|
struct PACKED {
|
|
|
|
uint8_t dollar = '$';
|
|
|
|
uint8_t magic = 'X';
|
|
|
|
uint8_t code = '<';
|
|
|
|
uint8_t flags;
|
|
|
|
uint16_t cmd = 0x1F03; // GPS
|
|
|
|
uint16_t size = 52;
|
|
|
|
} hdr;
|
|
|
|
uint8_t instance;
|
|
|
|
uint16_t gps_week;
|
|
|
|
uint32_t ms_tow;
|
|
|
|
uint8_t fix_type;
|
|
|
|
uint8_t satellites_in_view;
|
|
|
|
uint16_t horizontal_pos_accuracy; // [cm]
|
|
|
|
uint16_t vertical_pos_accuracy; // [cm]
|
|
|
|
uint16_t horizontal_vel_accuracy; // [cm/s]
|
|
|
|
uint16_t hdop;
|
|
|
|
int32_t longitude;
|
|
|
|
int32_t latitude;
|
|
|
|
int32_t msl_altitude; // cm
|
|
|
|
int32_t ned_vel_north; // cm/s
|
|
|
|
int32_t ned_vel_east;
|
|
|
|
int32_t ned_vel_down;
|
|
|
|
uint16_t ground_course; // deg * 100, 0..36000
|
|
|
|
uint16_t true_yaw; // deg * 100, values of 0..36000 are valid. 65535 = no data available
|
|
|
|
uint16_t year;
|
|
|
|
uint8_t month;
|
|
|
|
uint8_t day;
|
|
|
|
uint8_t hour;
|
|
|
|
uint8_t min;
|
|
|
|
uint8_t sec;
|
|
|
|
|
|
|
|
// footer CRC
|
|
|
|
uint8_t crc;
|
|
|
|
} msp_gps {};
|
|
|
|
|
|
|
|
auto t = gps_time();
|
|
|
|
struct timeval tv;
|
|
|
|
simulation_timeval(&tv);
|
2024-02-06 21:22:53 -04:00
|
|
|
struct tm tvd {};
|
|
|
|
auto *tm = gmtime_r(&tv.tv_sec, &tvd);
|
2023-11-28 06:24:44 -04:00
|
|
|
|
|
|
|
msp_gps.gps_week = t.week;
|
|
|
|
msp_gps.ms_tow = t.ms;
|
|
|
|
msp_gps.fix_type = d->have_lock?3:0;
|
2024-08-24 03:35:01 -03:00
|
|
|
msp_gps.satellites_in_view = d->have_lock ? d->num_sats : 3;
|
|
|
|
msp_gps.horizontal_pos_accuracy = d->horizontal_acc*100;
|
|
|
|
msp_gps.vertical_pos_accuracy = d->vertical_acc*100;
|
2023-11-28 06:24:44 -04:00
|
|
|
msp_gps.horizontal_vel_accuracy = 30;
|
|
|
|
msp_gps.hdop = 100;
|
|
|
|
msp_gps.longitude = d->longitude * 1.0e7;
|
|
|
|
msp_gps.latitude = d->latitude * 1.0e7;
|
|
|
|
msp_gps.msl_altitude = d->altitude * 100;
|
|
|
|
msp_gps.ned_vel_north = 100 * d->speedN;
|
|
|
|
msp_gps.ned_vel_east = 100 * d->speedE;
|
|
|
|
msp_gps.ned_vel_down = 100 * d->speedD;
|
|
|
|
msp_gps.ground_course = ToDeg(atan2f(d->speedE, d->speedN)) * 100;
|
|
|
|
msp_gps.true_yaw = wrap_360(d->yaw_deg)*100U; // can send 65535 for no yaw
|
|
|
|
msp_gps.year = tm->tm_year;
|
|
|
|
msp_gps.month = tm->tm_mon;
|
|
|
|
msp_gps.day = tm->tm_mday;
|
|
|
|
msp_gps.hour = tm->tm_hour;
|
|
|
|
msp_gps.min = tm->tm_min;
|
|
|
|
msp_gps.sec = tm->tm_sec;
|
|
|
|
|
|
|
|
// CRC is over packet without first 3 bytes and trailing CRC byte
|
|
|
|
msp_gps.crc = crc8_dvb_s2_update(0, (uint8_t *)&msp_gps.hdr.flags, sizeof(msp_gps)-4);
|
|
|
|
|
|
|
|
write_to_autopilot((const char *)&msp_gps, sizeof(msp_gps));
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // AP_SIM_GPS_MSP_ENABLED
|