Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
sensors_hitl.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Gautier Hattenberger <gautier.hattenberger@enac.fr>
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
22 #include "modules/imu/imu.h"
23 #include "modules/gps/gps.h"
24 #include "modules/core/abi.h"
26 #include "generated/airframe.h"
29 #include "nps_sensors_params_common.h"
30 #if USE_BATTERY_MONITOR
32 #endif
33 
34 struct ImuHitl {
38 
39  struct Int32Rates gyro;
40  struct Int32Vect3 accel;
41  struct Int32Vect3 mag;
42 };
43 
44 struct ImuHitl imu_hitl;
45 struct GpsState gps_hitl;
47 
48 static bool sensors_hitl_msg_available = false;
49 static uint8_t sensors_hitl_dl_buffer[MSG_SIZE] __attribute__((aligned));
50 static struct pprz_transport sensors_hitl_tp;
51 
53 {
54  pprz_transport_init(&sensors_hitl_tp); // for receiving only
55 
56  gps_has_fix = true;
57 
58  imu_hitl.gyro_available = false;
59  imu_hitl.mag_available = false;
60  imu_hitl.accel_available = false;
61 
62  // Set the default scaling
63  const struct Int32Rates gyro_scale[2] = {
64  {NPS_GYRO_SENSITIVITY_PP_NUM, NPS_GYRO_SENSITIVITY_QQ_NUM, NPS_GYRO_SENSITIVITY_RR_NUM},
65  {NPS_GYRO_SENSITIVITY_PP_DEN, NPS_GYRO_SENSITIVITY_QQ_DEN, NPS_GYRO_SENSITIVITY_RR_DEN}
66  };
67  const struct Int32Rates gyro_neutral = {
68  NPS_GYRO_NEUTRAL_P, NPS_GYRO_NEUTRAL_Q, NPS_GYRO_NEUTRAL_R
69  };
70  const struct Int32Vect3 accel_scale[2] = {
71  {NPS_ACCEL_SENSITIVITY_XX_NUM, NPS_ACCEL_SENSITIVITY_YY_NUM, NPS_ACCEL_SENSITIVITY_ZZ_NUM},
72  {NPS_ACCEL_SENSITIVITY_XX_DEN, NPS_ACCEL_SENSITIVITY_YY_DEN, NPS_ACCEL_SENSITIVITY_ZZ_DEN}
73  };
74  const struct Int32Vect3 accel_neutral = {
75  NPS_ACCEL_NEUTRAL_X, NPS_ACCEL_NEUTRAL_Y, NPS_ACCEL_NEUTRAL_Z
76  };
77  const struct Int32Vect3 mag_scale[2] = {
78  {NPS_MAG_SENSITIVITY_XX_NUM, NPS_MAG_SENSITIVITY_YY_NUM, NPS_MAG_SENSITIVITY_ZZ_NUM},
79  {NPS_MAG_SENSITIVITY_XX_DEN, NPS_MAG_SENSITIVITY_YY_DEN, NPS_MAG_SENSITIVITY_ZZ_DEN}
80  };
81  const struct Int32Vect3 mag_neutral = {
82  NPS_MAG_NEUTRAL_X, NPS_MAG_NEUTRAL_Y, NPS_MAG_NEUTRAL_Z
83  };
84  imu_set_defaults_gyro(IMU_NPS_ID, NULL, &gyro_neutral, gyro_scale);
86  imu_set_defaults_mag(IMU_NPS_ID, NULL, &mag_neutral, mag_scale);
87 }
88 
90 #if USE_BATTERY_MONITOR
91 #ifdef MAX_BAT_LEVEL
92  // init vsupply to MAX_BAT in case battery voltage is not available
93  electrical.vsupply = MAX_BAT_LEVEL;
94 #else
95  electrical.vsupply = 12.f; // 3S battery
96 #endif
97 #endif
98 }
99 
101 {
102  if (DL_HITL_IMU_ac_id(buf) != AC_ID) {
103  return;
104  }
105 
107  NPS_GYRO_SIGN_P * DL_HITL_IMU_gp(buf),
108  NPS_GYRO_SIGN_Q * DL_HITL_IMU_gq(buf),
109  NPS_GYRO_SIGN_R * DL_HITL_IMU_gr(buf));
111  NPS_ACCEL_SIGN_X * DL_HITL_IMU_ax(buf),
112  NPS_ACCEL_SIGN_Y * DL_HITL_IMU_ay(buf),
113  NPS_ACCEL_SIGN_Z * DL_HITL_IMU_az(buf));
115  NPS_MAG_SIGN_X * DL_HITL_IMU_mx(buf),
116  NPS_MAG_SIGN_Y * DL_HITL_IMU_my(buf),
117  NPS_MAG_SIGN_Z * DL_HITL_IMU_mz(buf));
118 
119  imu_hitl.accel_available = true;
120  imu_hitl.gyro_available = true;
121  imu_hitl.mag_available = true;
122 }
123 
125 {
126  if (DL_HITL_GPS_ac_id(buf) != AC_ID) {
127  return;
128  }
129 
130  gps_hitl.week = 1794;
131  gps_hitl.tow = DL_HITL_GPS_time(buf) * 1000;
132 
133  gps_hitl.ecef_vel.x = DL_HITL_GPS_ecef_vel_x(buf) * 100.;
134  gps_hitl.ecef_vel.y = DL_HITL_GPS_ecef_vel_y(buf) * 100.;
135  gps_hitl.ecef_vel.z = DL_HITL_GPS_ecef_vel_z(buf) * 100.;
137 
138  gps_hitl.lla_pos.lat = DL_HITL_GPS_lat(buf) * 1e7;
139  gps_hitl.lla_pos.lon = DL_HITL_GPS_lon(buf) * 1e7;
140  gps_hitl.lla_pos.alt = DL_HITL_GPS_alt(buf) * 1000.;
142 
143  gps_hitl.hmsl = DL_HITL_GPS_hmsl(buf) * 1000.;
145 
146  /* calc NED speed from ECEF */
147  struct LtpDef_i ref_ltp;
148  ltp_def_from_lla_i(&ref_ltp, &gps_hitl.lla_pos);
149  struct NedCoor_i ned_vel_i;
150  ned_of_ecef_vect_i(&ned_vel_i, &ref_ltp, &gps_hitl.ecef_vel);
151  gps_hitl.ned_vel.x = ned_vel_i.x;
152  gps_hitl.ned_vel.y = ned_vel_i.y;
153  gps_hitl.ned_vel.z = ned_vel_i.z;
155  struct NedCoor_f ned_vel_f;
156  VECT3_FLOAT_OF_CM(ned_vel_f, gps_hitl.ned_vel);
157 
158  /* horizontal and 3d ground speed in cm/s */
159  gps_hitl.gspeed = sqrtf(ned_vel_f.x * ned_vel_f.x + ned_vel_f.y * ned_vel_f.y) * 100;
160  gps_hitl.speed_3d = sqrtf(ned_vel_f.x * ned_vel_f.x + ned_vel_f.y * ned_vel_f.y + ned_vel_f.z * ned_vel_f.z) * 100;
161 
162  /* ground course in radians * 1e7 */
163  gps_hitl.course = atan2f(ned_vel_f.y, ned_vel_f.x) * 1e7;
165 
166  gps_hitl.pacc = 650;
167  gps_hitl.hacc = 450;
168  gps_hitl.vacc = 200;
169  gps_hitl.sacc = 100;
170  gps_hitl.pdop = 650;
171 
172  if (gps_has_fix) {
173  gps_hitl.num_sv = 11;
175  } else {
176  gps_hitl.num_sv = 1;
178  }
179 
180  // publish gps data
181  uint32_t now_ts = get_sys_time_usec();
184  if (gps_hitl.fix == GPS_FIX_3D) {
187  }
188  AbiSendMsgGPS(GPS_SIM_ID, now_ts, &gps_hitl);
189 }
190 
192  if (DL_HITL_AIR_DATA_ac_id(buf) != AC_ID) {
193  return;
194  }
195 
196  uint8_t flag = DL_HITL_AIR_DATA_update_flag(buf);
197  if (bit_is_set(flag, 0)) {
198  uint32_t now_ts = get_sys_time_usec();
199  float pressure = DL_HITL_AIR_DATA_baro(buf);
200  AbiSendMsgBARO_ABS(BARO_SIM_SENDER_ID, now_ts, pressure);
201  }
202  if (bit_is_set(flag, 1)) {
203  AbiSendMsgAIRSPEED(AIRSPEED_NPS_ID, DL_HITL_AIR_DATA_airspeed(buf));
204  }
205  if (bit_is_set(flag, 2) || bit_is_set(flag, 3)) {
206  uint8_t incidence_flag = (flag >> 2) & (0x3);
207  float aoa = DL_HITL_AIR_DATA_aoa(buf);
208  float sideslip = DL_HITL_AIR_DATA_sideslip(buf);
209  AbiSendMsgINCIDENCE(INCIDENCE_NPS_ID, incidence_flag, aoa, sideslip);
210  }
211 }
212 
213 
215 {
216  uint32_t now_ts = get_sys_time_usec();
217  if (imu_hitl.gyro_available) {
218  AbiSendMsgIMU_GYRO_RAW(IMU_NPS_ID, now_ts, &imu_hitl.gyro, 1, NPS_PROPAGATE, NAN);
219  imu_hitl.gyro_available = false;
220  }
222  AbiSendMsgIMU_ACCEL_RAW(IMU_NPS_ID, now_ts, &imu_hitl.accel, 1, NPS_PROPAGATE, NAN);
223  imu_hitl.accel_available = false;
224  }
225  if (imu_hitl.mag_available) {
226  AbiSendMsgIMU_MAG_RAW(IMU_NPS_ID, now_ts, &imu_hitl.mag);
227  imu_hitl.mag_available = false;
228  }
229 
230  // parse incoming messages
231  pprz_check_and_parse(&HITL_DEVICE.device, &sensors_hitl_tp, sensors_hitl_dl_buffer, &sensors_hitl_msg_available);
232  DlCheckAndParse(&HITL_DEVICE.device, &sensors_hitl_tp.trans_tx, sensors_hitl_dl_buffer, &sensors_hitl_msg_available, false);
233 }
234 
235 void imu_feed_gyro_accel(void) {}
236 void imu_feed_mag(void) {}
237 void gps_feed_value(void) {}
238 
Main include for ABI (AirBorneInterface).
#define BARO_SIM_SENDER_ID
#define IMU_NPS_ID
#define INCIDENCE_NPS_ID
#define GPS_SIM_ID
#define AIRSPEED_NPS_ID
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:71
struct Electrical electrical
Definition: electrical.c:92
Interface for electrical status: supply voltage, current, battery status, etc.
float vsupply
supply voltage in V
Definition: electrical.h:45
Device independent GPS code (interface)
uint32_t tow
GPS time of week in ms.
Definition: gps.h:107
int32_t hmsl
height above mean sea level (MSL) in mm
Definition: gps.h:92
struct LlaCoor_i lla_pos
position in LLA (lat,lon: deg*1e7; alt: mm over ellipsoid)
Definition: gps.h:90
uint32_t sacc
speed accuracy in cm/s
Definition: gps.h:101
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
Definition: gps.h:97
#define GPS_VALID_VEL_ECEF_BIT
Definition: gps.h:49
#define GPS_VALID_VEL_NED_BIT
Definition: gps.h:50
uint32_t hacc
horizontal accuracy in cm
Definition: gps.h:99
#define GPS_VALID_POS_LLA_BIT
Definition: gps.h:47
uint32_t last_3dfix_ticks
cpu time ticks at last valid 3D fix
Definition: gps.h:112
struct EcefCoor_i ecef_vel
speed ECEF in cm/s
Definition: gps.h:93
uint16_t pdop
position dilution of precision scaled by 100
Definition: gps.h:103
#define GPS_FIX_NONE
No GPS fix.
Definition: gps.h:40
#define GPS_VALID_HMSL_BIT
Definition: gps.h:51
struct NedCoor_i ned_vel
speed NED in cm/s
Definition: gps.h:94
uint32_t last_msg_time
cpu time in sec at last received GPS message
Definition: gps.h:115
uint32_t last_3dfix_time
cpu time in sec at last valid 3D fix
Definition: gps.h:113
uint32_t pacc
position accuracy in cm
Definition: gps.h:98
uint16_t gspeed
norm of 2d ground speed in cm/s
Definition: gps.h:95
uint8_t valid_fields
bitfield indicating valid fields (GPS_VALID_x_BIT)
Definition: gps.h:86
uint32_t vacc
vertical accuracy in cm
Definition: gps.h:100
#define GPS_FIX_3D
3D GPS fix
Definition: gps.h:42
uint16_t speed_3d
norm of 3d speed in cm/s
Definition: gps.h:96
#define GPS_VALID_COURSE_BIT
Definition: gps.h:52
uint32_t last_msg_ticks
cpu time ticks at last received GPS message
Definition: gps.h:114
uint8_t num_sv
number of sat in fix
Definition: gps.h:104
uint16_t week
GPS week.
Definition: gps.h:106
uint8_t fix
status of fix
Definition: gps.h:105
data structure for GPS information
Definition: gps.h:85
#define RATES_ASSIGN(_ra, _p, _q, _r)
Definition: pprz_algebra.h:330
#define VECT3_ASSIGN(_a, _x, _y, _z)
Definition: pprz_algebra.h:125
angular rates
int32_t lat
in degrees*1e7
int32_t alt
in millimeters above WGS84 reference ellipsoid
int32_t z
Down.
int32_t z
in centimeters
int32_t x
in centimeters
int32_t y
East.
int32_t y
in centimeters
int32_t lon
in degrees*1e7
int32_t x
North.
void ned_of_ecef_vect_i(struct NedCoor_i *ned, struct LtpDef_i *def, struct EcefCoor_i *ecef)
Rotate a vector from ECEF to NED.
#define VECT3_FLOAT_OF_CM(_o, _i)
void ltp_def_from_lla_i(struct LtpDef_i *def, struct LlaCoor_i *lla)
definition of the local (flat earth) coordinate system
vector in North East Down coordinates
void imu_set_defaults_mag(uint8_t abi_id, const struct Int32RMat *imu_to_sensor, const struct Int32Vect3 *neutral, const struct Int32Vect3 *scale)
Set the defaults for a mag sensor WARNING: Should be called before sensor is publishing messages to e...
Definition: imu.c:551
void imu_set_defaults_accel(uint8_t abi_id, const struct Int32RMat *imu_to_sensor, const struct Int32Vect3 *neutral, const struct Int32Vect3 *scale)
Set the defaults for a accel sensor WARNING: Should be called before sensor is publishing messages to...
Definition: imu.c:521
void imu_set_defaults_gyro(uint8_t abi_id, const struct Int32RMat *imu_to_sensor, const struct Int32Rates *neutral, const struct Int32Rates *scale)
Set the defaults for a gyro sensor WARNING: Should be called before sensor is publishing messages to ...
Definition: imu.c:491
Inertial Measurement Unit interface.
#define MSG_SIZE
Definition: main_demo5.c:62
static const struct Int32Vect3 accel_neutral
Definition: navdata.c:104
static const struct Int32Vect3 mag_scale[2]
Default mag scale.
Definition: navdata.c:111
static const struct Int32Rates gyro_scale[2]
Default gyro scale.
Definition: navdata.c:92
static const struct Int32Vect3 accel_scale[2]
Default accel scale/neutral.
Definition: navdata.c:100
float z
in meters
float x
in meters
float y
in meters
vector in North East Down coordinates Units: meters
static bool sensors_hitl_msg_available
Definition: sensors_hitl.c:48
void imu_feed_mag(void)
Definition: sensors_hitl.c:236
uint8_t accel_available
Definition: sensors_hitl.c:36
void sensors_hitl_event(void)
Definition: sensors_hitl.c:214
struct ImuHitl imu_hitl
Definition: sensors_hitl.c:44
void sensors_hitl_periodic(void)
Definition: sensors_hitl.c:89
void imu_feed_gyro_accel(void)
Definition: sensors_hitl.c:235
void gps_feed_value(void)
Definition: sensors_hitl.c:237
bool gps_has_fix
Definition: sensors_hitl.c:46
uint8_t mag_available
Definition: sensors_hitl.c:35
struct Int32Vect3 accel
Definition: sensors_hitl.c:40
static uint8_t sensors_hitl_dl_buffer[MSG_SIZE]
Definition: sensors_hitl.c:49
uint8_t gyro_available
Definition: sensors_hitl.c:37
void sensors_hitl_parse_HITL_AIR_DATA(uint8_t *buf)
Definition: sensors_hitl.c:191
void sensors_hitl_parse_HITL_GPS(uint8_t *buf)
Definition: sensors_hitl.c:124
struct Int32Vect3 mag
Definition: sensors_hitl.c:41
struct Int32Rates gyro
Definition: sensors_hitl.c:39
struct GpsState gps_hitl
Definition: sensors_hitl.c:45
void sensors_hitl_parse_HITL_IMU(uint8_t *buf)
Definition: sensors_hitl.c:100
void sensors_hitl_init(void)
Definition: sensors_hitl.c:52
static struct pprz_transport sensors_hitl_tp
Definition: sensors_hitl.c:50
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:72
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition: sys_time.h:73
Periodic telemetry system header (includes downlink utility and generated code).
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98