Larus glider flight sensor system 3.9.2024
Software-In-The-Loop test and validation system
Loading...
Searching...
No Matches
CAN_output.cpp
Go to the documentation of this file.
1/***********************************************************************/
26#include "generic_CAN_driver.h"
27#include "CAN_output.h"
28#include "data_structures.h"
29#include "system_state.h"
30#include "CAN_gateway.h"
31
32#define DEGREE_2_RAD 1.7453292e-2f
33
34#ifdef CAN_FORMAT_2021
35
37{
38 c_CAN_Id_EulerAngles = 0x101,
39 c_CAN_Id_Airspeed = 0x102,
40 c_CAN_Id_Vario = 0x103,
42 c_CAN_Id_GPS_LatLon = 0x105,
43 c_CAN_Id_GPS_Alt = 0x106,
44 c_CAN_Id_GPS_Trk_Spd = 0x107,
45 c_CAN_Id_Wind = 0x108,
46 c_CAN_Id_Atmosphere = 0x109,
47 c_CAN_Id_GPS_Sats = 0x10a,
48 c_CAN_Id_Acceleration = 0x10b,
49 c_CAN_Id_TurnCoord = 0x10c,
50 c_CAN_Id_SystemState = 0x10d,
51 c_CID_KSB_Vdd = 0x112,
52};
53
54void CAN_output ( const output_data_t &x, bool horizon_activated)
55{
56 CANpacket p;
57
59 {
60 p.id=c_CAN_Id_EulerAngles; // 0x101
61 p.dlc=6;
62 p.data_sh[0] = (int16_t)(round(x.euler.r * 1000.0f)); // unit = 1/1000 RAD
63 p.data_sh[1] = (int16_t)(round(x.euler.p * 1000.0f));
64 p.data_sh[2] = (int16_t)(round(x.euler.y * 1000.0f));
65 CAN_send(p, 1);
66 }
67 else
68 {
69 p.id=c_CAN_Id_EulerAngles; // 0x101
70 p.dlc=6;
71 p.data_sh[0] = ZERO;
72 p.data_sh[1] = ZERO;
73 p.data_sh[2] = (int16_t)(round(x.euler.y * 1000.0f));
74 CAN_send(p, 1);
75 }
76
77 p.id=c_CAN_Id_Airspeed; // 0x102
78 p.dlc=4;
79 p.data_sh[0] = (int16_t)(round(x.TAS * 3.6f)); // m/s -> km/h
80 p.data_sh[1] = (int16_t)(round(x.IAS * 3.6f)); // m/s -> km/h
81 CAN_send(p, 1);
82
83 p.id=c_CAN_Id_Vario; // 0x103
84 p.dlc=4;
85 p.data_sh[0] = (int16_t)(round(x.vario * 1000.0f)); // mm/s
86 p.data_sh[1] = (int16_t)(round(x.integrator_vario * 1000.0f)); // mm/s
87 CAN_send(p, 1);
88
89 p.id=c_CAN_Id_GPS_Date_Time; // 0x104
90 p.dlc=6;
91 p.data_b[0] = x.c.year;
92 p.data_b[1] = x.c.month;
93 p.data_b[2] = x.c.day;
94 p.data_b[3] = x.c.hour;
95 p.data_b[4] = x.c.minute;
96 p.data_b[5] = x.c.second;
97 CAN_send(p, 1);
98
99 p.id=c_CAN_Id_GPS_LatLon; // 0x105
100 p.dlc=8;
101 p.data_sw[0] = (int32_t)(x.c.latitude * (double)1e7);
102 p.data_sw[1] = (int32_t)(x.c.longitude * (double)1e7); //
103 CAN_send(p, 1);
104
105 p.id=c_CAN_Id_GPS_Alt; // 0x106
106 p.dlc=8;
107 p.data_sw[0] = (int32_t)(x.c.position[DOWN] * -1e3f);// in mm
108 p.data_sw[1] = x.c.geo_sep_dm; // geo separation in 1/10 m
109 CAN_send(p, 1);
110
111 p.id=c_CAN_Id_GPS_Trk_Spd; // 0x107
112 p.dlc=4;
113 p.data_sh[0] = (int16_t)(round(x.c.heading_motion * 17.4533f)); // 1/1000 rad
114 p.data_h[1] = (int16_t)(round(x.c.speed_motion * 3.6f));
115 CAN_send(p, 1);
116
117 p.id=c_CAN_Id_Wind; // 0x108
118 p.dlc =8;
119
120 float wind_direction = ATAN2( - x.wind[EAST], - x.wind[NORTH]);
121 if( wind_direction < 0.0f)
122 wind_direction += 6.2832f;
123 p.data_sh[0] = (int16_t)(round(wind_direction * 1000.0f)); // 1/1000 rad
124 p.data_h[1] = (int16_t)(round(SQRT( SQR(x.wind[EAST])+ SQR(x.wind[NORTH])) * 3.6f));
125
127 if( wind_direction < 0.0f)
128 wind_direction += 6.2832f;
129 p.data_sh[2] = (int16_t)(round(wind_direction * 1000.0f)); // 1/1000 rad
130 p.data_h[3] = (int16_t)(round(SQRT( SQR(x.wind_average[EAST])+ SQR(x.wind_average[NORTH])) * 3.6f));
131
132 CAN_send(p, 1);
133
134 p.id=c_CAN_Id_Atmosphere; // 0x109
135 p.dlc=8;
136 p.data_w[0] = (uint32_t)(x.m.static_pressure);
137 p.data_w[1] = (uint32_t)(x.air_density * 1000.0f);
138 CAN_send(p, 1);
139
140 p.id=c_CAN_Id_GPS_Sats; // 0x10a
141 p.dlc=2;
142 p.data_b[0] = x.c.SATS_number;
143 p.data_b[1] = x.c.sat_fix_type;
144 CAN_send(p, 1);
145
146 p.id=c_CAN_Id_Acceleration; // 0x10b
147 p.dlc=7;
148 p.data_sh[0] = (int16_t)(round(x.G_load * 1000.0f)); // G-load mm/s^2
149 p.data_sh[1] = (int16_t)(round(x.effective_vertical_acceleration * -1000.0f)); // mm/s^2
150 p.data_sh[2] = (int16_t)(round(x.vario_uncompensated * -1000.0f)); // mm/s
151 p.data_sb[6] = (int8_t)(x.circle_mode);
152 CAN_send(p, 1);
153
154 p.id=c_CID_KSB_Vdd; // 0x112
155 p.dlc=2;
156 p.data_h[0] = (uint16_t)(round(x.m.supply_voltage * 10.0f)); // 1/10 V
157 CAN_send(p, 1);
158
159 p.id=c_CAN_Id_TurnCoord; // 0x10c
160 p.dlc=6;
161 p.data_sh[0] = (int16_t)(round(x.slip_angle * 1000.0f)); // slip angle in radiant from body acceleration
162 p.data_sh[1] = (int16_t)(round(x.turn_rate * 1000.0f)); // turn rate rad/s
163 p.data_sh[2] = (int16_t)(round(x.pitch_angle * 1000.0f)); // nick angle in radiant from body acceleration
164 if( CAN_send(p, 1)) // check CAN for timeout this time
166 else
167 system_state &= ~CAN_OUTPUT_ACTIVE;
168
169#ifndef GIT_TAG_DEC
170#define GIT_TAG_DEC 0xffffffff
171#endif
172
173 while( CAN_gateway_poll( p, 0) )
174 CAN_send(p,1);
175
176 p.id=c_CAN_Id_SystemState; // 0x10d
177 p.dlc=8;
178 p.data_w[0] = system_state;
179 p.data_w[1] = GIT_TAG_DEC;
180 CAN_send(p, 1);
181}
182
183#else
184
186{
187 // all values in SI-STD- (metric) units, angles in radians
188 // format IEEE float32 little-endian
192 CAN_Id_Vario = 0x403,
193
199
200 CAN_Id_Wind = 0x409,
207};
208
209void CAN_output ( const output_data_t &x)
210{
211 CANpacket p;
212
213#if HORIZON_DATA_SECRET == 0
215 p.dlc=8;
216 p.data_f[0] = x.euler.r;
217 p.data_f[1] = x.euler.n;
218 CAN_send(p, 1);
219#endif
221 p.dlc=4;
222 p.data_f[0] = x.euler.y;
223 CAN_send(p, 1);
224
226 p.dlc=8;
227 p.data_f[0] = x.TAS;
228 p.data_f[1] = x.IAS;
229 CAN_send(p, 1);
230
232 p.dlc=8;
233 p.data_f[0] = x.vario;
234 p.data_f[1] = x.integrator_vario;
235 CAN_send(p, 1);
236
237 p.id=CAN_Id_Wind;
238 p.dlc=8;
239 p.data_f[0] = ATAN2( - x.wind[EAST], - x.wind[NORTH]);
240 p.data_f[1] = x.wind.abs();
241 CAN_send(p, 1);
242
244 p.dlc=8;
245 p.data_f[0] = ATAN2( - x.wind_average[EAST], - x.wind_average[NORTH]);
246 p.data_f[1] = x.wind.abs();
247 CAN_send(p, 1);
248
250 p.dlc=8;
251 p.data_f[0] = x.m.static_pressure;
252 p.data_f[1] = x.air_density;
253 CAN_send(p, 1);
254
256 p.dlc=7;
257 p.data_f[0] = x.G_load;
258 p.data_f[1] = x.slip_angle;
259 CAN_send(p, 1);
260
262 p.dlc=5;
263 p.data_f[0] = x.turn_rate;
264 p.data_b[4] = (uint8_t)(x.circle_mode);
265
266
268 p.dlc=6;
269 p.data_b[0] = x.c.year;
270 p.data_b[1] = x.c.month;
271 p.data_b[2] = x.c.day;
272 p.data_b[3] = x.c.hour;
273 p.data_b[4] = x.c.minute;
274 p.data_b[5] = x.c.second;
275 CAN_send(p, 1);
276
278 p.dlc=8;
279 p.data_f[0] = (float)(x.c.latitude); // -> 4m of accuracy
280 p.data_f[1] = (float)(x.c.longitude);
281 CAN_send(p, 1);
282
283 p.id=CAN_Id_GPS_Alt; // 0x106
284 p.dlc=8;
285 p.data_f[0] = x.c.position[DOWN] * -1.0f;
286 p.data_f[1] = x.c.geo_sep_dm * 0.1f; // dm -> m
287 CAN_send(p, 1);
288
290 p.dlc=8;
292 p.data_f[1] = x.c.speed_motion;
293 CAN_send(p, 1);
294
296 p.dlc=2;
297 p.data_b[0] = x.c.SATS_number;
298 p.data_b[1] = x.c.sat_fix_type;
299 CAN_send(p, 1);
300
302 p.dlc=4;
303 p.data_f[0] = x.m.supply_voltage;
304
305 if( CAN_send(p, 1)) // check CAN for timeout this time
307 else
308 system_state &= ~CAN_OUTPUT_ACTIVE;
309
310#ifndef GIT_TAG_DEC
311#define GIT_TAG_DEC 0xffffffff
312#endif
313
315 p.dlc=8;
316 p.data_w[0] = system_state;
317 p.data_w[1] = GIT_TAG_DEC;
318 CAN_send(p, 1);
319}
320
321
322#endif
@ DOWN
Definition AHRS.h:42
@ EAST
Definition AHRS.h:42
@ NORTH
Definition AHRS.h:42
bool CAN_send(const CANpacket &p, unsigned)
Global CAN send procedure.
bool CAN_gateway_poll(CANpacket &p, unsigned max_wait)
#define DEGREE_2_RAD
void CAN_output(const output_data_t &x)
CAN_ID_SENSOR
@ CAN_Id_GPS_Date_Time
uint8_t year-2000, month, day, hour, mins, secs
@ CAN_Id_GPS_Alt
float MSL altitude,float geo separation
@ CAN_Id_Wind_Average
float average wind direction, float average wind speed m/s
@ CAN_Id_Vario
float vario, float vario-average / m/s
@ CAN_Id_Wind
float wind direction (where from), float wind speed
@ CAN_Id_GPS_Sats
uin8_t No of Sats, (uint8_t)bool SAT FIX valid, (uint8_t)bool SAT HEADING available
@ CAN_Id_Heading
float true heading, [OPTIONAL float magnetic declination]
@ CAN_Id_GPS_LatLon
float latitude, float longitude / degrees(!)
@ CAN_Id_Acceleration
float body-frame G-load m/s^2, body acceleration angle roll-axis
@ CAN_Id_TurnRate
float turn rate to the right, (uint8_t) (enum { STRAIGHT_FLIGHT, TRANSITION, CIRCLING} )
@ CAN_Id_Atmosphere
float ambient pressure / Pa, float air density / kg/m^3
@ CAN_Id_Voltage
float supply voltage
@ CAN_Id_SystemState
u32 system_state, u32 git_tag_dec
@ CAN_Id_Roll_Nick
float roll-angle, float nick-angle (FRONT-RIGHT-DOWN-system)
@ CAN_Id_Airspeed
float TAS, float IAS / m/s
@ CAN_Id_GPS_Trk_Spd
float ground track, float groundspeed / m/s
#define GIT_TAG_DEC
Portable interface to some CAN-bus driver.
basic CAN packet type
uint16_t data_h[4]
data seen as 4 times uint16_t
uint16_t dlc
data length code
int16_t data_sh[4]
data seen as 4 times int16_t
float data_f[2]
data seen as 2 times 32-bit floats
int32_t data_sw[2]
data seen as 2 times int32_t
int8_t data_sb[8]
data seen as 8 times int8_t
uint16_t id
identifier
uint32_t data_w[2]
data seen as 2 times uint32_t
uint8_t data_b[8]
data seen as 8 times uint8_t
datatype p
Definition euler.h:17
datatype y
Definition euler.h:17
datatype r
Definition euler.h:17
mathematical vector of arbitrary type and size
Definition vector.h:40
datatype abs(void) const
vector abs operator returns absolute value
Definition vector.h:77
#define ZERO
#define SQRT(x)
#define ATAN2(y, x)
Portable interface to some CAN-bus driver.
#define SQR(x)
float heading_motion
ground track in degrees
Definition GNSS.h:108
float speed_motion
ground speed m/s
Definition GNSS.h:109
uint8_t second
Definition GNSS.h:122
uint8_t day
Definition GNSS.h:118
uint8_t hour
Definition GNSS.h:119
float3vector position
NED / meters.
Definition GNSS.h:105
uint8_t SATS_number
number of tracked satellites
Definition GNSS.h:123
uint8_t year
Definition GNSS.h:116
double latitude
latitude / degrees
Definition GNSS.h:113
int16_t geo_sep_dm
(WGS ellipsoid height - elevation MSL) in 0.1m units
Definition GNSS.h:130
uint8_t month
Definition GNSS.h:117
double longitude
longitude / degrees
Definition GNSS.h:114
uint8_t sat_fix_type
bit 0: SAT FIX, bit 1: SAT HEADING availale
Definition GNSS.h:124
uint8_t minute
Definition GNSS.h:121
combination of all input and output data in one structure
measurement_data_t m
float3vector wind_average
coordinates_t c
float3vector wind
uint32_t circle_mode
float effective_vertical_acceleration
eulerangle< float > euler
float vario_uncompensated
collection of system tuning parameters
@ CAN_OUTPUT_ACTIVE
uint32_t system_state
bits collected from availability_bits