37 #include "generated/flight_plan.h"
38 #include "generated/airframe.h"
44 #if defined(FIXEDWING_FIRMWARE)
47 #elif defined(ROTORCRAFT_FIRMWARE)
58 #define OSD_STRING_SIZE 31
59 #define osd_sprintf _osd_sprintf
61 #if !defined(OSD_USE_FLOAT_LOW_PASS_FILTERING)
62 #define OSD_USE_FLOAT_LOW_PASS_FILTERING
66 #if !defined(AMPS_LOW_PASS_FILTER_STRENGTH) || AMPS_LOW_PASS_FILTER_STRENGTH == 0
67 #define AMPS_LOW_PASS_FILTER_STRENGTH 6
70 #if !defined(SPEED_LOW_PASS_FILTER_STRENGTH) || SPEED_LOW_PASS_FILTER_STRENGTH == 0
71 #define SPEED_LOW_PASS_FILTER_STRENGTH 6
74 #if !defined(BAT_CAPACITY)
75 #pragma message "BAT_CAPACITY not defined, 5000 mah will be used."
76 #define BAT_CAPACITY 5000.0
79 #if defined(FIXEDWING_FIRMWARE)
81 #if !defined(LOITER_BAT_CURRENT)
82 #pragma message "LOITER_BAT_CURRENT not defined, 10 Amps will be used for LOITER current draw."
83 #define LOITER_BAT_CURRENT 10.0
86 #if !defined(STALL_AIRSPEED)
87 #pragma message "STALL_AIRSPEED not defined, 10 m/s will be used."
88 #define STALL_AIRSPEED 10.0
91 #if !defined(MINIMUM_AIRSPEED)
92 #pragma message "MINIMUM_AIRSPEED not defined, 1.3 * STALL_SPEED will be used"
93 #define MINIMUM_AIRSPEED (1.3f * STALL_AIRSPEED)
98 #if !defined(IMU_MAG_X_SIGN)
99 #define IMU_MAG_X_SIGN 1
101 #if !defined(IMU_MAG_X_SIGN)
102 #define IMU_MAG_Y_SIGN 1
104 #if !defined(IMU_MAG_X_SIGN)
105 #define IMU_MAG_Z_SIGN 1
116 float fx1;
float fx2;
float fx3;
117 float fy1;
float fy2;
float fy3;
118 float fz1;
float fz2;
float fz3;
121 #if defined(FIXEDWING_FIRMWARE)
122 static void mag_compass(
void);
179 #if defined(FIXEDWING_FIRMWARE)
181 void mag_compass(
void)
185 float cos_roll;
float sin_roll;
float cos_pitch;
float sin_pitch;
float mag_x;
float mag_y;
186 static float mag_declination = 0;
187 static bool declination_calculated =
false;
193 cos_roll = cosf(att->
phi);
194 sin_roll = sinf(att->
phi);
195 cos_pitch = cosf(att->
theta);
196 sin_pitch = sinf(att->
theta);
203 #if defined(AHRS_MAG_DECLINATION)
204 if (AHRS_MAG_DECLINATION != 0.0) {
213 if (declination_calculated ==
false) {
214 #if defined(NOMINAL_AIRSPEED)
220 if (mag_declination > M_PI) {
221 mag_declination -= (2.0 * M_PI);
222 }
else if (mag_declination < -M_PI) { mag_declination += (2.0 * M_PI); }
224 declination_calculated =
true;
225 if (fabs(mag_declination) > RadOfDeg(10.)) { mag_declination = 0; declination_calculated =
false; }
258 svA->
fx = svB.
fx - svC.
fx;
259 svA->
fy = svB.
fy - svC.
fy;
260 svA->
fz = svB.
fz - svC.
fz;
279 static VECTOR svPlanePosition, Home_Position, Home_PositionForPlane, Home_PositionForPlane2;
297 #if defined(FIXEDWING_FIRMWARE)
304 Home_Position.
fz = 0;
314 smRotation.
fy1 = -smRotation.
fx2;
315 smRotation.
fy2 = smRotation.
fx1;
347 home_dir = atan2(Home_PositionForPlane2.
fy, Home_PositionForPlane2.
fx);
348 if (home_dir > M_PI) {
349 home_dir -= (2.0 * M_PI);
350 }
else if (home_dir < -M_PI) { home_dir += (2.0 * M_PI); }
361 #if defined USE_MATEK_TYPE_OSD_CHIP && USE_MATEK_TYPE_OSD_CHIP == 1
369 if (c >=
'0' && c <=
'9') {
370 if (c ==
'0') { c -= 38; }
else { c -= 48; }
371 }
else if (c >=
'A' && c <=
'Z') {
373 }
else if (c >=
'a' && c <=
'z') {
378 case (
'('): c = 0x3f;
break;
379 case (
')'): c = 0x40;
break;
380 case (
'.'): c = 0x41;
break;
381 case (
'?'): c = 0x42;
break;
382 case (
';'): c = 0x43;
break;
383 case (
':'): c = 0x44;
break;
384 case (
','): c = 0x45;
break;
386 case (
'/'): c = 0x47;
break;
387 case (
'"'): c = 0x48;
break;
388 case (
'-'): c = 0x49;
break;
389 case (
'<'): c = 0x4A;
break;
390 case (
'>'): c = 0x4B;
break;
391 case (
'@'): c = 0x4C;
break;
392 case (
' '): c = 0x00;
break;
393 case (
'\0'): c = 0xFF;
break;
405 float current_amps = 0;
406 float horizontal_speed = 0;
407 float bat_capacity_left = 0;
408 static float bat_capacity_used = 0;
412 bat_capacity_used += (current_amps * 1000.) / (3600. * (
float)MAX7456_PERIODIC_FREQ);
413 bat_capacity_left = (float)
BAT_CAPACITY - bat_capacity_used;
414 if (bat_capacity_left < 0) { bat_capacity_left = 0; }
417 #if defined(FIXEDWING_FIRMWARE)
419 current_amps = LOITER_BAT_CURRENT;
420 horizontal_speed = MINIMUM_AIRSPEED;
424 horizontal_speed = 10.0;
427 #if defined(OSD_USE_FLOAT_LOW_PASS_FILTERING)
429 static double current_amps_sum = 0;
430 static double horizontal_speed_sum = 0;
431 static float current_amps_filtered = 0;
432 static float horizontal_speed_filtered = 0;
434 current_amps_sum = (current_amps_sum - current_amps_filtered) + current_amps;
436 current_amps = current_amps_filtered;
438 horizontal_speed_sum = (horizontal_speed_sum - horizontal_speed_filtered) + horizontal_speed;
440 horizontal_speed = horizontal_speed_filtered;
446 static uint64_t current_amps_sum = 0;
447 static uint64_t horizontal_speed_sum = 0;
448 static uint32_t current_amps_filtered = 0;
449 static uint32_t horizontal_speed_filtered = 0;
452 current_amps_int = (
uint32_t)(current_amps * 1000.0);
453 horizontal_speed_int = (
uint32_t)(horizontal_speed * 1000.0);
455 current_amps_sum = (current_amps_sum - current_amps_filtered) + current_amps_int;
459 horizontal_speed_sum = (horizontal_speed_sum - horizontal_speed_filtered) + horizontal_speed_int;
463 current_amps = (float)(current_amps_filtered) / 1000.;
464 horizontal_speed = (float)(horizontal_speed_filtered) / 1000.;
477 int8_t x = 0,
idx = 0, post_offset = 0, aft_offset = 0, string_len = 0;
480 if (row > 15) { column = 15; }
481 if (column > 29) { column = 29; }
490 if (attributes &
C_JUST) {
491 if (char_nb % 2 == 0) { char_nb++; }
492 post_offset = (char_nb - string_len) / 2;
493 aft_offset = char_nb - string_len;
494 if (((
int8_t)column - (char_nb / 2)) >= 0) { column -= (char_nb / 2); }
495 for (x = 0; x < 30; x++) { osd_buf[x] = 0; }
497 for (x = 0; x < string_len; x++) { osd_buf[post_offset + x] =
osd_string[x]; }
498 osd_buf[string_len + aft_offset] = 0xFF;
501 do {
osd_string[x] = osd_buf[x]; }
while (osd_buf[x++] != 0xFF);
502 }
else if (attributes &
R_JUST) {
505 if (((
int8_t)column - char_nb) >= 0) { column -= char_nb; }
506 if (((
int8_t)char_nb - string_len) >= 0) { post_offset = char_nb - string_len; }
else {post_offset = 0; }
517 for (; x < char_nb; x++) {
osd_string[x] = 0; }
548 char to_asc[10] = {48, 48, 48, 48, 48, 48, 48, 48, 48, 48};
553 for (x = 0; x <
sizeof(string_buf); x++) { string_buf[x] = 0; }
556 for (x = 0; x <
sizeof(string_buf); x++) { string_buf[x] = *(
string + x);
if (string_buf[x] ==
'\0') {
break; } }
562 while (string_buf[x] !=
'\0') {
564 if (string_buf[x] ==
'%') {
if (string_buf[x + 4] ==
'c') { (param_start = x + 1); param_end = x + 3;
break; } }
567 if (param_end - param_start) {
569 string_buf[x] = ((string_buf[param_start] - 48) * 100) + ((string_buf[param_start + 1] - 48) * 10) +
570 (string_buf[param_start + 2] - 48);
575 for (y = (x + 4); y <=
sizeof(string_buf); y++) { string_buf[x++] = string_buf[y]; }
577 }
while ((param_end - param_start > 0));
585 while (string_buf[x] !=
'\0') {
586 if (string_buf[x] ==
'%') {
589 }
else if (string_buf[x] ==
'f') { param_end = x;
break; }
592 if (param_end - param_start) {
594 frac_nb = string_buf[param_end - 1] - 48;
595 if (frac_nb > 3) { frac_nb = 3; }
597 y = (
sizeof(to_asc) - 1);
600 if (frac_nb > 0 && frac_nb <= 3) {
606 digit = (i_frac / x);
607 to_asc[y + z] = digit + 48;
621 to_asc[y] = (i_dec % 10) + 48;
624 if (value < 0) { y--; to_asc[y] =
'-'; }
632 for (x = 0; x < param_start; x++) { *(buffer + x) = string_buf[x]; }
636 while (y <
sizeof(to_asc)) { *(buffer + x) = to_asc[y]; x++; y++; }
641 *(buffer + x++) = string_buf[param_end];
643 }
while (string_buf[param_end] !=
'\0');
647 for (x = 0; x <
sizeof(string_buf); x++) {
648 *(buffer + x) = string_buf[x];
649 if (*(buffer + x) ==
'\0') {
break; }
660 float distance_to_home = 0;
661 static float home_direction_degrees = 0;
662 #if defined(BARO_ALTITUDE_VAR)
663 static float baro_alt_correction = 0;
668 #if defined(FIXEDWING_FIRMWARE)
677 distance_to_home = (float)(sqrt(ph_x * ph_x + ph_y * ph_y));
679 #if defined(FIXEDWING_FIRMWARE)
691 #if defined(FIXEDWING_FIRMWARE)
707 if (home_direction_degrees < 0) { home_direction_degrees += 360; }
708 if (home_direction_degrees >= 360) { home_direction_degrees -= 360; }
710 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
734 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
742 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
754 #if defined(FIXEDWING_FIRMWARE)
767 #if defined(FIXEDWING_FIRMWARE)
777 #if defined(FIXEDWING_FIRMWARE)
778 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
798 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
810 #if defined(BARO_ALTITUDE_VAR)
812 RunOnceEvery((MAX7456_PERIODIC_FREQ * 300), { baro_alt_correction =
GetPosAlt() - BARO_ALTITUDE_VAR;});
815 altitude = BARO_ALTITUDE_VAR + baro_alt_correction;
820 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
830 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
844 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
857 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
875 if (DegOfRad(att->
theta) > 3) {
884 if (DegOfRad(att->
theta) < -3) {
893 if (DegOfRad(att->
phi) > 3) {
897 }
else {
osd_put_s(
" ",
false, 5, 8, 18); }
902 if (DegOfRad(att->
phi) < -3) {
911 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
920 default:
step = 0;
break;
1020 #if USE_PAL_FOR_OSD_VIDEO
1021 #pragma message "Camera and OSD must be both PAL or NTSC otherwise only the camera picture will be visible."
#define ABI_BROADCAST
Broadcast address.
struct pprz_autopilot autopilot
Global autopilot structure.
Core autopilot interface common to all firmwares.
bool launch
request launch
uint8_t mode
current autopilot mode
Hardware independent code for commands handling.
struct point waypoints[NB_WAYPOINT]
size == nb_waypoint, waypoint 0 is a dummy waypoint
struct Electrical electrical
Interface for electrical status: supply voltage, current, battery status, etc.
#define LOW_BAT_LEVEL
low battery level in Volts (for 3S LiPo)
float current
current in A
float vsupply
supply voltage in V
Some architecture independent helper functions for GPIOs.
struct GpsState gps
global GPS state
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
uint16_t pdop
position dilution of precision scaled by 100
#define GPS_FIX_3D
3D GPS fix
enum SPIClockPolarity cpol
clock polarity control
enum SPIClockPhase cpha
clock phase control
enum SPISlaveSelect select
slave selection behavior
SPICallback before_cb
NULL or function called before the transaction.
SPICallback after_cb
NULL or function called after the transaction.
enum SPIDataSizeSelect dss
data transfer word size
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
uint16_t input_length
number of data words to read
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
volatile uint8_t * input_buf
pointer to receive buffer for DMA
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
enum SPIBitOrder bitorder
MSB/LSB order.
uint16_t output_length
number of data words to write
enum SPITransactionStatus status
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
@ SPICpolIdleLow
CPOL = 0.
@ SPISelectUnselect
slave is selected before transaction and unselected after
SPI transaction structure.
static struct FloatEulers * stateGetNedToBodyEulers_f(void)
Get vehicle body attitude euler angles (float).
static struct EnuCoor_f * stateGetPositionEnu_f(void)
Get position in local ENU coordinates (float).
static struct UtmCoor_f * stateGetPositionUtm_f(void)
Get position in UTM coordinates (float).
static float stateGetHorizontalSpeedNorm_f(void)
Get norm of horizontal ground speed (float).
static float stateGetHorizontalSpeedDir_f(void)
Get dir of horizontal ground speed (float).
static struct EnuCoor_f * stateGetSpeedEnu_f(void)
Get ground speed in local ENU coordinates (float).
struct imu_mag_t * imu_get_mag(uint8_t sender_id, bool create)
Find or create the mag in the imu structure.
uint8_t abi_id
ABI sensor ID.
struct Int32Vect3 scaled
Last scaled values in body frame.
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
static void draw_osd(void)
#define SPEED_LOW_PASS_FILTER_STRENGTH
uint8_t max7456_osd_status
void max7456_periodic(void)
static bool _osd_sprintf(char *buffer, char *string, float value)
static void osd_put_s(char *string, uint8_t attributes, uint8_t char_nb, uint8_t row, uint8_t column)
static void calc_flight_time_left(void)
static void vSubtractVectors(VECTOR *svA, VECTOR svB, VECTOR svC)
static void vMultiplyMatrixByVector(VECTOR *svA, MATRIX smB, VECTOR svC)
struct spi_transaction max7456_trans
char osd_str_buf[OSD_STRING_SIZE]
uint32_t max_flyable_distance_left
static char ascii_to_osd_c(char c)
static void send_mag_heading(struct transport_tx *trans, struct link_device *dev)
char osd_string[OSD_STRING_SIZE]
uint16_t osd_char_address
#define AMPS_LOW_PASS_FILTER_STRENGTH
uint8_t osd_spi_rx_buffer[2]
uint8_t osd_spi_tx_buffer[2]
static float home_direction(void)
Maxim MAX7456 single-channel monochrome on-screen display driver.
Maxim MAX7456 single-channel monochrome on-screen display driver.
#define OSD_AUTO_INCREMENT_MODE
#define OSD_NVRAM_BUSY_FLAG
#define OSD_RESET_BUSY_FLAG
#define OSD_INVERT_PIXELS
#define OSD_VIDEO_MODE_PAL
float waypoint_get_x(uint8_t wp_id)
Get X/East coordinate of waypoint in meters.
float waypoint_get_y(uint8_t wp_id)
Get Y/North coordinate of waypoint in meters.
#define GetPosAlt()
Get current altitude above MSL.
#define GetAltRef()
Get current altitude reference for local coordinates.
float alt
in meters (above WGS84 reference ellipsoid or above MSL)
vector in East North Up coordinates Units: meters
Rotorcraft navigation functions.
Architecture independent SPI (Serial Peripheral Interface) API.
struct Stabilization stabilization
int32_t cmd[COMMANDS_NB]
output command vector, range from [-MAX_PPRZ:MAX_PPRZ] (store for messages)
API to get/set the generic vehicle states.
static const struct usb_device_descriptor dev
Architecture independent timing functions.
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
short int16_t
Typedef defining 16 bit short type.
unsigned long long uint64_t
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
signed char int8_t
Typedef defining 8 bit char type.