|
Paparazzi UAS
v5.18.0_stable
Paparazzi is a free software Unmanned Aircraft System.
|
Go to the documentation of this file.
37 #include "generated/flight_plan.h"
38 #include "generated/airframe.h"
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
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;
122 static void mag_compass(
void);
132 static bool _osd_sprintf(
char *buffer,
char *
string,
float value);
181 void mag_compass(
void)
188 float cos_roll;
float sin_roll;
float cos_pitch;
float sin_pitch;
float mag_x;
float mag_y;
189 static float mag_declination = 0;
190 static bool declination_calculated =
false;
194 #if (defined(IMU_MAG_X_SENS) && defined(IMU_MAG_Y_SENS) && defined(IMU_MAG_Z_SENS)) && !defined(USE_MAGNETOMETER)
204 cos_roll = cosf(att->
phi);
205 sin_roll = sinf(att->
phi);
206 cos_pitch = cosf(att->
theta);
207 sin_pitch = sinf(att->
theta);
209 mag_x =
x * cos_pitch +
y * sin_roll * sin_pitch +
z * cos_roll * sin_pitch;
210 mag_y =
y * cos_roll -
z * sin_roll;
214 #if defined(AHRS_MAG_DECLINATION)
215 if (AHRS_MAG_DECLINATION != 0.0) {
224 if (declination_calculated ==
false) {
225 #if defined(NOMINAL_AIRSPEED)
231 if (mag_declination > M_PI) {
232 mag_declination -= (2.0 * M_PI);
233 }
else if (mag_declination < -M_PI) { mag_declination += (2.0 * M_PI); }
235 declination_calculated =
true;
236 if (fabs(mag_declination) > RadOfDeg(10.)) { mag_declination = 0; declination_calculated =
false; }
269 svA->
fx = svB.
fx - svC.
fx;
270 svA->
fy = svB.
fy - svC.
fy;
271 svA->
fz = svB.
fz - svC.
fz;
290 static VECTOR svPlanePosition, Home_Position, Home_PositionForPlane, Home_PositionForPlane2;
315 Home_Position.
fz = 0;
325 smRotation.
fy1 = -smRotation.
fx2;
326 smRotation.
fy2 = smRotation.
fx1;
358 home_dir = atan2(Home_PositionForPlane2.
fy, Home_PositionForPlane2.
fx);
359 if (home_dir > M_PI) {
360 home_dir -= (2.0 * M_PI);
361 }
else if (home_dir < -M_PI) { home_dir += (2.0 * M_PI); }
372 #if defined USE_MATEK_TYPE_OSD_CHIP && USE_MATEK_TYPE_OSD_CHIP == 1
380 if (
c >=
'0' &&
c <=
'9') {
381 if (
c ==
'0') {
c -= 38; }
else {
c -= 48; }
382 }
else if (
c >=
'A' &&
c <=
'Z') {
384 }
else if (
c >=
'a' &&
c <=
'z') {
389 case (
'('):
c = 0x3f;
break;
390 case (
')'):
c = 0x40;
break;
391 case (
'.'):
c = 0x41;
break;
392 case (
'?'):
c = 0x42;
break;
393 case (
';'):
c = 0x43;
break;
394 case (
':'):
c = 0x44;
break;
395 case (
','):
c = 0x45;
break;
397 case (
'/'):
c = 0x47;
break;
398 case (
'"'):
c = 0x48;
break;
399 case (
'-'):
c = 0x49;
break;
400 case (
'<'):
c = 0x4A;
break;
401 case (
'>'):
c = 0x4B;
break;
402 case (
'@'):
c = 0x4C;
break;
403 case (
' '):
c = 0x00;
break;
404 case (
'\0'):
c = 0xFF;
break;
416 float current_amps = 0;
417 float horizontal_speed = 0;
418 float bat_capacity_left = 0;
419 static float bat_capacity_used = 0;
423 bat_capacity_used += (current_amps * 1000.) / (3600. * (float)MAX7456_PERIODIC_FREQ);
424 bat_capacity_left = (float)
BAT_CAPACITY - bat_capacity_used;
425 if (bat_capacity_left < 0) { bat_capacity_left = 0; }
430 current_amps = LOITER_BAT_CURRENT;
431 horizontal_speed = MINIMUM_AIRSPEED;
435 horizontal_speed = 10.0;
438 #if defined(OSD_USE_FLOAT_LOW_PASS_FILTERING)
440 static double current_amps_sum = 0;
441 static double horizontal_speed_sum = 0;
442 static float current_amps_filtered = 0;
443 static float horizontal_speed_filtered = 0;
445 current_amps_sum = (current_amps_sum - current_amps_filtered) + current_amps;
447 current_amps = current_amps_filtered;
449 horizontal_speed_sum = (horizontal_speed_sum - horizontal_speed_filtered) + horizontal_speed;
451 horizontal_speed = horizontal_speed_filtered;
457 static uint64_t current_amps_sum = 0;
458 static uint64_t horizontal_speed_sum = 0;
459 static uint32_t current_amps_filtered = 0;
460 static uint32_t horizontal_speed_filtered = 0;
463 current_amps_int = (
uint32_t)(current_amps * 1000.0);
464 horizontal_speed_int = (
uint32_t)(horizontal_speed * 1000.0);
466 current_amps_sum = (current_amps_sum - current_amps_filtered) + current_amps_int;
470 horizontal_speed_sum = (horizontal_speed_sum - horizontal_speed_filtered) + horizontal_speed_int;
474 current_amps = (float)(current_amps_filtered) / 1000.;
475 horizontal_speed = (float)(horizontal_speed_filtered) / 1000.;
488 int8_t x = 0,
idx = 0, post_offset = 0, aft_offset = 0, string_len = 0;
491 if (row > 15) { column = 15; }
492 if (column > 29) { column = 29; }
501 if (attributes &
C_JUST) {
502 if (char_nb % 2 == 0) { char_nb++; }
503 post_offset = (char_nb - string_len) / 2;
504 aft_offset = char_nb - string_len;
505 if (((
int8_t)column - (char_nb / 2)) >= 0) { column -= (char_nb / 2); }
506 for (
x = 0;
x < 30;
x++) { osd_buf[
x] = 0; }
508 for (
x = 0;
x < string_len;
x++) { osd_buf[post_offset +
x] =
osd_string[
x]; }
509 osd_buf[string_len + aft_offset] = 0xFF;
512 do {
osd_string[
x] = osd_buf[
x]; }
while (osd_buf[
x++] != 0xFF);
513 }
else if (attributes &
R_JUST) {
516 if (((
int8_t)column - char_nb) >= 0) { column -= char_nb; }
517 if (((
int8_t)char_nb - string_len) >= 0) { post_offset = char_nb - string_len; }
else {post_offset = 0; }
559 char to_asc[10] = {48, 48, 48, 48, 48, 48, 48, 48, 48, 48};
564 for (
x = 0;
x <
sizeof(string_buf);
x++) { string_buf[
x] = 0; }
567 for (
x = 0;
x <
sizeof(string_buf);
x++) { string_buf[
x] = *(
string +
x);
if (string_buf[
x] ==
'\0') {
break; } }
573 while (string_buf[
x] !=
'\0') {
575 if (string_buf[
x] ==
'%') {
if (string_buf[
x + 4] ==
'c') { (param_start =
x + 1); param_end =
x + 3;
break; } }
578 if (param_end - param_start) {
580 string_buf[
x] = ((string_buf[param_start] - 48) * 100) + ((string_buf[param_start + 1] - 48) * 10) +
581 (string_buf[param_start + 2] - 48);
586 for (
y = (
x + 4);
y <=
sizeof(string_buf);
y++) { string_buf[
x++] = string_buf[
y]; }
588 }
while ((param_end - param_start > 0));
596 while (string_buf[
x] !=
'\0') {
597 if (string_buf[
x] ==
'%') {
600 }
else if (string_buf[
x] ==
'f') { param_end =
x;
break; }
603 if (param_end - param_start) {
605 frac_nb = string_buf[param_end - 1] - 48;
606 if (frac_nb > 3) { frac_nb = 3; }
608 y = (
sizeof(to_asc) - 1);
611 if (frac_nb > 0 && frac_nb <= 3) {
617 digit = (i_frac /
x);
618 to_asc[
y +
z] = digit + 48;
632 to_asc[
y] = (i_dec % 10) + 48;
635 if (value < 0) {
y--; to_asc[
y] =
'-'; }
643 for (
x = 0;
x < param_start;
x++) { *(buffer +
x) = string_buf[
x]; }
647 while (
y <
sizeof(to_asc)) { *(buffer +
x) = to_asc[
y];
x++;
y++; }
652 *(buffer +
x++) = string_buf[param_end];
654 }
while (string_buf[param_end] !=
'\0');
658 for (
x = 0;
x <
sizeof(string_buf);
x++) {
659 *(buffer +
x) = string_buf[
x];
660 if (*(buffer +
x) ==
'\0') {
break; }
671 float distance_to_home = 0;
672 static float home_direction_degrees = 0;
673 #if defined(BARO_ALTITUDE_VAR)
674 static float baro_alt_correction = 0;
683 #else // FOR ROTORCRAFTS
688 distance_to_home = (float)(sqrt(ph_x * ph_x + ph_y * ph_y));
718 if (home_direction_degrees < 0) { home_direction_degrees += 360; }
719 if (home_direction_degrees >= 360) { home_direction_degrees -= 360; }
721 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
745 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
753 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
789 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
809 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
821 #if defined(BARO_ALTITUDE_VAR)
823 RunOnceEvery((MAX7456_PERIODIC_FREQ * 300), { baro_alt_correction =
GetPosAlt() - BARO_ALTITUDE_VAR;});
826 altitude = BARO_ALTITUDE_VAR + baro_alt_correction;
831 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
841 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
855 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
868 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
886 if (DegOfRad(att->
theta) > 3) {
895 if (DegOfRad(att->
theta) < -3) {
904 if (DegOfRad(att->
phi) > 3) {
908 }
else {
osd_put_s(
" ",
false, 5, 8, 18); }
913 if (DegOfRad(att->
phi) < -3) {
922 #if defined(USE_MATEK_TYPE_OSD_CHIP) && USE_MATEK_TYPE_OSD_CHIP == 1
931 default:
step = 0;
break;
1031 #if USE_PAL_FOR_OSD_VIDEO
1032 #pragma message "Camera and OSD must be both PAL or NTSC otherwise only the camera picture will be visible."
VIC slots used for the LPC2148 define name e g gps UART1_VIC_SLOT e g modem SPI1_VIC_SLOT SPI1 in mcu_periph spi_arch c or spi_slave_hs_arch c(and some others not using the SPI peripheral yet..) I2C0_VIC_SLOT 8 mcu_periph/i2c_arch.c I2C1_VIC_SLOT 9 mcu_periph/i2c_arch.c USB_VIC_SLOT 10 usb
#define OSD_NVRAM_BUSY_FLAG
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
static float stateGetHorizontalSpeedDir_f(void)
Get dir of horizontal ground speed (float).
enum SPIClockPolarity cpol
clock polarity control
#define OSD_RESET_BUSY_FLAG
#define IMU_MAG_Y_SENS_DEN
uint16_t output_length
number of data words to write
uint8_t mode
current autopilot mode
SPI transaction structure.
#define GetPosAlt()
Get current altitude above MSL.
static struct EnuCoor_f * stateGetPositionEnu_f(void)
Get position in local ENU coordinates (float).
static struct FloatEulers * stateGetNedToBodyEulers_f(void)
Get vehicle body attitude euler angles (float).
struct Int32Vect3 mag_neutral
magnetometer neutral readings (bias) in raw/unscaled units
static void draw_osd(void)
#define IMU_MAG_Y_SENS_NUM
#define IMU_MAG_X_SENS_NUM
struct spi_transaction max7456_trans
#define IMU_MAG_Z_SENS_DEN
float waypoint_get_y(uint8_t wp_id)
Get Y/North coordinate of waypoint in meters.
static struct UtmCoor_f * stateGetPositionUtm_f(void)
Get position in UTM coordinates (float).
@ SPISelectUnselect
slave is selected before transaction and unselected after
struct point waypoints[NB_WAYPOINT]
size == nb_waypoint, waypoint 0 is a dummy waypoint
float vsupply
supply voltage in V
enum SPIBitOrder bitorder
MSB/LSB order.
#define LOW_BAT_LEVEL
low battery level in Volts (for 3S LiPo)
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
#define GetAltRef()
Get current altitude reference for local coordinates.
enum SPISlaveSelect select
slave selection behavior
static void calc_flight_time_left(void)
#define SPEED_LOW_PASS_FILTER_STRENGTH
#define OSD_AUTO_INCREMENT_MODE
@ SPICpolIdleLow
CPOL = 0.
static void vMultiplyMatrixByVector(VECTOR *svA, MATRIX smB, VECTOR svC)
struct pprz_autopilot autopilot
Global autopilot structure.
enum SPIClockPhase cpha
clock phase control
float alt
in meters (above WGS84 reference ellipsoid or above MSL)
SPICallback after_cb
NULL or function called after the transaction.
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
static const struct usb_device_descriptor dev
float waypoint_get_x(uint8_t wp_id)
Get X/East coordinate of waypoint in meters.
Architecture independent timing functions.
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
vector in East North Up coordinates Units: meters
void max7456_periodic(void)
#define AMPS_LOW_PASS_FILTER_STRENGTH
uint32_t max_flyable_distance_left
#define IMU_MAG_X_SENS_DEN
char osd_string[OSD_STRING_SIZE]
static bool _osd_sprintf(char *buffer, char *string, float value)
static void send_mag_heading(struct transport_tx *trans, struct link_device *dev)
#define IMU_MAG_Z_SENS_NUM
struct Imu imu
global IMU state
#define OSD_INVERT_PIXELS
#define OSD_VIDEO_MODE_PAL
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
int32_t course
GPS course over ground in rad*1e7, [0, 2*Pi]*1e7 (CW/north)
uint16_t input_length
number of data words to read
uint16_t osd_char_address
static float stateGetHorizontalSpeedNorm_f(void)
Get norm of horizontal ground speed (float).
uint8_t max7456_osd_status
static float home_direction(void)
enum SPIDataSizeSelect dss
data transfer word size
static void osd_put_s(char *string, uint8_t attributes, uint8_t char_nb, uint8_t row, uint8_t column)
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
static struct EnuCoor_f * stateGetSpeedEnu_f(void)
Get ground speed in local ENU coordinates (float).
volatile uint8_t * input_buf
pointer to receive buffer for DMA
int32_t stabilization_cmd[COMMANDS_NB]
Stabilization commands.
uint16_t pdop
position dilution of precision scaled by 100
struct Int32Vect3 mag_unscaled
unscaled magnetometer measurements
uint8_t osd_spi_tx_buffer[2]
uint8_t osd_spi_rx_buffer[2]
static char ascii_to_osd_c(char c)
struct ap_state * ap_state
struct Electrical electrical
SPICallback before_cb
NULL or function called before the transaction.
char osd_str_buf[OSD_STRING_SIZE]
static void vSubtractVectors(VECTOR *svA, VECTOR svB, VECTOR svC)
struct GpsState gps
global GPS state
enum SPITransactionStatus status
#define GPS_FIX_3D
3D GPS fix
#define DefaultPeriodic
Set default periodic telemetry.
bool launch
request launch
#define VECT3_COPY(_a, _b)
float current
current in A
unsigned long long uint64_t