175 changes: 0 additions & 175 deletions sw/airborne/fms/overo_test_spi_link.c

This file was deleted.

69 changes: 0 additions & 69 deletions sw/airborne/fms/overo_test_telemetry.c

This file was deleted.

142 changes: 0 additions & 142 deletions sw/airborne/fms/overo_test_telemetry2.c

This file was deleted.

39 changes: 0 additions & 39 deletions sw/airborne/fms/packet_header.h

This file was deleted.

13 changes: 0 additions & 13 deletions sw/airborne/fms/test_telemetry.c

This file was deleted.

63 changes: 0 additions & 63 deletions sw/airborne/fms/test_telemetry_2.c

This file was deleted.

16 changes: 0 additions & 16 deletions sw/airborne/fms/udp_transport.c

This file was deleted.

194 changes: 0 additions & 194 deletions sw/airborne/fms/udp_transport.h

This file was deleted.

113 changes: 0 additions & 113 deletions sw/airborne/fms/udp_transport2.c

This file was deleted.

103 changes: 0 additions & 103 deletions sw/airborne/fms/udp_transport2.h

This file was deleted.

2 changes: 1 addition & 1 deletion sw/airborne/math/pprz_algebra_float.c
Expand Up @@ -398,7 +398,7 @@ void float_quat_integrate(struct FloatQuat *q, struct FloatRates *omega, float d
}
}

void float_quat_vmult(struct FloatVect3 *v_out, struct FloatQuat *q, struct FloatVect3 *v_in)
void float_quat_vmult(struct FloatVect3 *v_out, struct FloatQuat *q, const struct FloatVect3 *v_in)
{
const float qi2_M1_2 = q->qi * q->qi - 0.5;
const float qiqx = q->qi * q->qx;
Expand Down
2 changes: 1 addition & 1 deletion sw/airborne/math/pprz_algebra_float.h
Expand Up @@ -433,7 +433,7 @@ extern void float_quat_integrate(struct FloatQuat *q, struct FloatRates *omega,
/** rotate 3D vector by quaternion.
* vb = q_a2b * va * q_a2b^-1
*/
extern void float_quat_vmult(struct FloatVect3 *v_out, struct FloatQuat *q, struct FloatVect3 *v_in);
extern void float_quat_vmult(struct FloatVect3 *v_out, struct FloatQuat *q, const struct FloatVect3 *v_in);

/// Quaternion from Euler angles.
extern void float_quat_of_eulers(struct FloatQuat *q, struct FloatEulers *e);
Expand Down
Expand Up @@ -232,8 +232,8 @@ void opticflow_calc_frame(struct opticflow_t *opticflow, struct opticflow_state_
opticflow->prev_theta = state->theta;

// Velocity calculation
result->vel_x = -result->flow_der_x * result->fps / opticflow->subpixel_factor * img->w / OPTICFLOW_FX;
result->vel_y = result->flow_der_y * result->fps / opticflow->subpixel_factor * img->h / OPTICFLOW_FY;
result->vel_x = -result->flow_der_x * result->fps * state->agl/ opticflow->subpixel_factor * img->w / OPTICFLOW_FX;
result->vel_y = result->flow_der_y * result->fps * state->agl/ opticflow->subpixel_factor * img->h / OPTICFLOW_FY;

// *************************************************************************************
// Next Loop Preparation
Expand Down
Expand Up @@ -19,11 +19,11 @@
* Boston, MA 02111-1307, USA.
*/

/** @file gain_scheduling.c
/** @file modules/ctrl/gain_scheduling.c
* Module that interpolates gainsets in flight based on a scheduling variable
*/

#include "gain_scheduling.h"
#include "modules/ctrl/gain_scheduling.h"

//Include for scheduling on transition_status
#include "firmwares/rotorcraft/guidance/guidance_h.h"
Expand Down Expand Up @@ -131,4 +131,4 @@ void gain_scheduling_periodic(void)
void set_gainset(int gainset)
{
stabilization_gains = gainlibrary[gainset];
}
}
Expand Up @@ -20,7 +20,7 @@
*/

/**
* @file gain_scheduling.h
* @file modules/ctrl/gain_scheduling.h
*
* Module that interpolates between gain sets, depending on the scheduling variable.
*/
Expand Down
68 changes: 0 additions & 68 deletions sw/airborne/modules/deploy_sonar_buoy/deploy_sonar_buoy.c

This file was deleted.

2 changes: 1 addition & 1 deletion sw/airborne/modules/digital_cam/atmega_i2c_cam_ctrl.c
Expand Up @@ -65,7 +65,7 @@ void atmega_i2c_cam_ctrl_init(void)
void atmega_i2c_cam_ctrl_periodic(void)
{
atmega_i2c_cam_ctrl_just_sent_command = 0;
dc_periodic_4Hz();
dc_periodic();

// Request Status
if (atmega_i2c_cam_ctrl_just_sent_command == 0) {
Expand Down
32 changes: 17 additions & 15 deletions sw/airborne/modules/digital_cam/dc.c
Expand Up @@ -41,9 +41,11 @@
#include "firmwares/rotorcraft/navigation.h"
#endif

/** default quartersec perioid = 0.5s */
#ifndef DC_AUTOSHOOT_QUARTERSEC_PERIOD
#define DC_AUTOSHOOT_QUARTERSEC_PERIOD 2
#include "mcu_periph/sys_time.h"

/** default time interval for periodic mode: 1sec */
#ifndef DC_AUTOSHOOT_PERIOD
#define DC_AUTOSHOOT_PERIOD 1.0
#endif

/** default distance interval for distance mode: 50m */
Expand Down Expand Up @@ -74,8 +76,7 @@ float dc_gps_y = 0;

static struct FloatVect2 last_shot_pos = {0.0, 0.0};
float dc_distance_interval;

uint8_t dc_autoshoot_quartersec_period;
float dc_autoshoot_period;

/** by default send DC_SHOT message when photo was taken */
#ifndef DC_SHOT_SYNC_SEND
Expand Down Expand Up @@ -131,7 +132,7 @@ void dc_send_shot_position(void)
void dc_init(void)
{
dc_autoshoot = DC_AUTOSHOOT_STOP;
dc_autoshoot_quartersec_period = DC_AUTOSHOOT_QUARTERSEC_PERIOD;
dc_autoshoot_period = DC_AUTOSHOOT_PERIOD;
dc_distance_interval = DC_AUTOSHOOT_DISTANCE_INTERVAL;
}

Expand All @@ -140,6 +141,7 @@ uint8_t dc_info(void)
#ifdef DOWNLINK_SEND_DC_INFO
float course = DegOfRad(stateGetNedToBodyEulers_f()->psi);
int16_t mode = dc_autoshoot;
uint8_t shutter = dc_autoshoot_period * 10;
DOWNLINK_SEND_DC_INFO(DefaultChannel, DefaultDevice,
&mode,
&stateGetPositionLla_i()->lat,
Expand All @@ -155,7 +157,7 @@ uint8_t dc_info(void)
&dc_circle_interval,
&dc_circle_last_block,
&dc_gps_count,
&dc_autoshoot_quartersec_period);
&shutter);
#endif
return 0;
}
Expand Down Expand Up @@ -235,20 +237,20 @@ static float dim_mod(float a, float b, float m)
return fminf(a - b, b + m - a);
}

void dc_periodic_4Hz(void)
void dc_periodic(void)
{
static uint8_t dc_shutter_timer = 0;
static float last_shot_time = 0.;

switch (dc_autoshoot) {

case DC_AUTOSHOOT_PERIODIC:
if (dc_shutter_timer) {
dc_shutter_timer--;
} else {
dc_shutter_timer = dc_autoshoot_quartersec_period;
case DC_AUTOSHOOT_PERIODIC: {
float now = get_sys_time_float();
if (now - last_shot_time > dc_autoshoot_period) {
last_shot_time = now;
dc_send_command(DC_SHOOT);
}
break;
}
break;

case DC_AUTOSHOOT_DISTANCE: {
struct FloatVect2 cur_pos;
Expand Down
8 changes: 4 additions & 4 deletions sw/airborne/modules/digital_cam/dc.h
Expand Up @@ -52,8 +52,8 @@ extern uint16_t dc_gps_count;
/*
* Variables for PERIODIC mode.
*/
/** AutoShoot photos every X quarter_second */
extern uint8_t dc_autoshoot_quartersec_period;
/** AutoShoot photos every X seconds */
extern float dc_autoshoot_period;


/*
Expand Down Expand Up @@ -151,8 +151,8 @@ void dc_send_shot_position(void);
/** initialize settings */
extern void dc_init(void);

/** periodic 4Hz function */
extern void dc_periodic_4Hz(void);
/** periodic function */
extern void dc_periodic(void);

/**
* Sets the dc control in distance mode.
Expand Down
14 changes: 9 additions & 5 deletions sw/airborne/modules/digital_cam/gpio_cam_ctrl.c
Expand Up @@ -35,6 +35,7 @@

#include "gpio_cam_ctrl.h"
#include "generated/airframe.h"
#include "generated/modules.h"

// Include Standard Camera Control Interface
#include "dc.h"
Expand All @@ -49,12 +50,14 @@
#define DC_RELEASE gpio_clear
#endif

/** how long to push shutter in seconds */
#ifndef DC_SHUTTER_DELAY
#define DC_SHUTTER_DELAY 2 /* 4Hz -> 0.5s */
#define DC_SHUTTER_DELAY 0.5
#endif

/** how long to send power off in seconds */
#ifndef DC_POWER_OFF_DELAY
#define DC_POWER_OFF_DELAY 3
#define DC_POWER_OFF_DELAY 0.75
#endif

#ifdef DC_SHUTTER_LED
Expand Down Expand Up @@ -123,13 +126,14 @@ void gpio_cam_ctrl_periodic(void)
}

// Common DC Periodic task
dc_periodic_4Hz();
dc_periodic();
}

/* Command The Camera */
void dc_send_command(uint8_t cmd)
{
dc_timer = DC_SHUTTER_DELAY;
dc_timer = DC_SHUTTER_DELAY * GPIO_CAM_CTRL_PERIODIC_FREQ;

switch (cmd) {
case DC_SHOOT:
DC_PUSH(DC_SHUTTER_GPIO);
Expand All @@ -155,7 +159,7 @@ void dc_send_command(uint8_t cmd)
#ifdef DC_POWER_OFF_GPIO
case DC_OFF:
DC_PUSH(DC_POWER_OFF_GPIO);
dc_timer = DC_POWER_OFF_DELAY;
dc_timer = DC_POWER_OFF_DELAY * GPIO_CAM_CTRL_PERIODIC_FREQ;
break;
#endif
default:
Expand Down
4 changes: 2 additions & 2 deletions sw/airborne/modules/digital_cam/gpio_cam_ctrl.h
Expand Up @@ -25,15 +25,15 @@
* Provides the control of the shutter and the zoom of a digital camera
* through standard binary IOs of the board.
*
* The required initialization (dc_init()) and periodic (4Hz) process.
* The required initialization (dc_init()) and periodic process.
*/

#ifndef GPIO_CAM_CTRL_H
#define GPIO_CAM_CTRL_H

extern void gpio_cam_ctrl_init(void);

/** 4Hz Periodic */
/** Periodic */
extern void gpio_cam_ctrl_periodic(void);

#endif // GPIO_CAM_CTRL_H
74 changes: 70 additions & 4 deletions sw/airborne/modules/digital_cam/servo_cam_ctrl.c
Expand Up @@ -20,15 +20,83 @@
*
*/

/** @file modules/digital_cam/servo_cam_ctrl.c
* @brief Digital Camera Control
*
* Provides the control of the shutter and the zoom of a digital camera
* via servos.
*
*/

#include "servo_cam_ctrl.h"
#include "generated/modules.h"

// Include Servo and airframe servo channels
#include "std.h"
#include "inter_mcu.h"
#include "generated/airframe.h"

#define DC_PUSH(X) ap_state->commands[X] = -MAX_PPRZ;
#define DC_RELEASE(X) ap_state->commands[X] = MAX_PPRZ;

/** how long to push shutter in seconds */
#ifndef DC_SHUTTER_DELAY
#define DC_SHUTTER_DELAY 0.5
#endif

#ifndef DC_SHUTTER_SERVO
#error DC: Please specify at least a DC_SHUTTER_SERVO
#endif


// Button Timer
uint8_t dc_timer;
static uint8_t dc_timer;


void servo_cam_ctrl_init(void)
{
// Call common DC init
dc_init();

// Do Servo specific DC init
dc_timer = 0;
}


/* Periodic */
void servo_cam_ctrl_periodic(void)
{
#ifdef DC_SHOOT_ON_BUTTON_RELEASE
if (dc_timer == 1) {
dc_send_shot_position();
}
#endif

if (dc_timer) {
dc_timer--;
} else {
DC_RELEASE(DC_SHUTTER_SERVO);
#ifdef DC_ZOOM_IN_SERVO
DC_RELEASE(DC_ZOOM_IN_SERVO);
#endif
#ifdef DC_ZOOM_OUT_SERVO
DC_RELEASE(DC_ZOOM_OUT_SERVO);
#endif
#ifdef DC_POWER_SERVO
DC_RELEASE(DC_POWER_SERVO);
#endif
}

// Common DC Periodic task
dc_periodic();
}


/* Command The Camera */
void dc_send_command(uint8_t cmd)
{
dc_timer = DC_SHUTTER_DELAY;
dc_timer = DC_SHUTTER_DELAY * SERVO_CAM_CTRL_PERIODIC_FREQ;

switch (cmd) {
case DC_SHOOT:
DC_PUSH(DC_SHUTTER_SERVO);
Expand Down Expand Up @@ -56,5 +124,3 @@ void dc_send_command(uint8_t cmd)
}
}



58 changes: 4 additions & 54 deletions sw/airborne/modules/digital_cam/servo_cam_ctrl.h
Expand Up @@ -33,7 +33,7 @@
* <define name="DC_POWER_SERVO" value="9"/>
* @endcode
*
* Provides the required initialization (dc_init()) and periodic (4Hz) process.
* Provides the required initialization (dc_init()) and periodic process.
*/

#ifndef SERVO_CAM_CTRL_H
Expand All @@ -42,60 +42,10 @@
// Include Standard Camera Control Interface
#include "dc.h"

// Include Servo and airframe servo channels
#include "std.h"
#include "inter_mcu.h"
#include "generated/airframe.h"

extern uint8_t dc_timer;
extern void servo_cam_ctrl_init(void);

static inline void servo_cam_ctrl_init(void)
{
// Call common DC init
dc_init();

// Do LED specific DC init
dc_timer = 0;
}

#define DC_PUSH(X) ap_state->commands[X] = -MAX_PPRZ;
#define DC_RELEASE(X) ap_state->commands[X] = MAX_PPRZ;

#ifndef DC_SHUTTER_DELAY
#define DC_SHUTTER_DELAY 2 /* 4Hz -> 0.5s */
#endif

#ifndef DC_SHUTTER_SERVO
#error DC: Please specify at least a DC_SHUTTER_SERVO
#endif


/* 4Hz Periodic */
static inline void servo_cam_ctrl_periodic(void)
{
#ifdef DC_SHOOT_ON_BUTTON_RELEASE
if (dc_timer == 1) {
dc_send_shot_position();
}
#endif

if (dc_timer) {
dc_timer--;
} else {
DC_RELEASE(DC_SHUTTER_SERVO);
#ifdef DC_ZOOM_IN_SERVO
DC_RELEASE(DC_ZOOM_IN_SERVO);
#endif
#ifdef DC_ZOOM_OUT_SERVO
DC_RELEASE(DC_ZOOM_OUT_SERVO);
#endif
#ifdef DC_POWER_SERVO
DC_RELEASE(DC_POWER_SERVO);
#endif
}

// Common DC Periodic task
dc_periodic_4Hz();
}
/* Periodic */
extern void servo_cam_ctrl_periodic(void);

#endif // SERVO_CAM_CONTROL_H
2 changes: 1 addition & 1 deletion sw/airborne/modules/digital_cam/sim_i2c_cam_ctrl.c
Expand Up @@ -43,7 +43,7 @@ void atmega_i2c_cam_ctrl_init(void)

void atmega_i2c_cam_ctrl_periodic(void)
{
dc_periodic_4Hz();
dc_periodic();

// Request Status
dc_send_command(DC_GET_STATUS);
Expand Down
2 changes: 1 addition & 1 deletion sw/airborne/modules/digital_cam/uart_cam_ctrl.c
Expand Up @@ -140,7 +140,7 @@ void digital_cam_uart_init(void)
void digital_cam_uart_periodic(void)
{
// Common DC Periodic task
dc_periodic_4Hz();
dc_periodic();
}


Expand Down
3 changes: 1 addition & 2 deletions sw/airborne/modules/digital_cam/uart_cam_ctrl.h
Expand Up @@ -25,7 +25,7 @@
* Provides the control of a camera over serial, typically connected to a computer which has
* full control of all camera functions via USB, including downloading of digital thumbnails
*
* The required initialization (digital_cam_uart_init()) and periodic (4Hz) process.
* The required initialization (digital_cam_uart_init()) and periodic process.
*/

#ifndef DIGITAL_CAM_UART_H
Expand All @@ -35,7 +35,6 @@

extern void digital_cam_uart_init(void);

/** 4Hz Periodic */
extern void digital_cam_uart_periodic(void);
extern void digital_cam_uart_event(void);

Expand Down
Expand Up @@ -20,7 +20,7 @@
*/

/**
* @file modules/max7456/max7456.c
* @file modules/display/max7456.c
* Maxim MAX7456 single-channel monochrome on-screen display driver.
*
*/
Expand All @@ -46,8 +46,8 @@
#endif

// Peripherials
#include "max7456.h"
#include "max7456_regs.h"
#include "modules/display/max7456.h"
#include "modules/display/max7456_regs.h"

#define OSD_STRING_SIZE 31
#define osd_sprintf _osd_sprintf
Expand Down
Expand Up @@ -20,6 +20,12 @@
*
*/

/**
* @file modules/display/max7456.h
* Maxim MAX7456 single-channel monochrome on-screen display driver.
*
*/

#ifndef MAX7456_H
#define MAX7456_H

Expand Down
@@ -1,3 +1,32 @@
/*
* Copyright (C) 2013 Chris
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/

/**
* @file modules/display/max7456_regs.h
* Maxim MAX7456 single-channel monochrome on-screen display driver.
*
* Registers definition
*/

#ifndef MAX7456_REGS_H
#define MAX7456_REGS_H

Expand Down
Expand Up @@ -21,13 +21,13 @@
*/

/**
* @file modules/MPPT/MPPT.c
* @file modules/energy/MPPT.c
* @brief Solar cells MPTT monitoring
*
*/

#include <stdbool.h>
#include "MPPT.h"
#include "modules/energy/MPPT.h"
#include "firmwares/fixedwing/main_fbw.h"
#include "mcu_periph/i2c.h"

Expand Down
Expand Up @@ -21,7 +21,7 @@
*/

/**
* @file modules/MPPT/MPPT.h
* @file modules/energy/MPPT.h
* @brief Solar cells MPTT monitoring
*
*/
Expand Down
Expand Up @@ -20,14 +20,14 @@
*/

/**
* @file modules/bat_checker/bat_checker.c
* @file modules/energy/bat_checker.c
*
* Activate a buzzer/LED periodically or periodically to warn of low/critical battery level.
* At LOW_BAT_LEVEL the buzzer will be activated periodically.
* At CRITIC_BAT_LEVEL the buzzer will be activated permanently.
*/

#include "bat_checker.h"
#include "modules/energy/bat_checker.h"
#include "generated/airframe.h"
#include "generated/modules.h"
#include "subsystems/electrical.h"
Expand Down
Expand Up @@ -20,7 +20,7 @@
*/

/**
* @file modules/bat_checker/bat_checker.c
* @file modules/energy/bat_checker.c
*
* Activate a buzzer/LED periodically or periodically to warn of low/critical battery level.
* At LOW_BAT_LEVEL the buzzer will be activated periodically.
Expand Down
Expand Up @@ -21,7 +21,7 @@
*/


#include "MPPT.h"
#include "modules/energy/MPPT.h"
#include "messages.h"
#include "subsystems/datalink/downlink.h"

Expand Down
Expand Up @@ -20,7 +20,7 @@
*
*/

#include "gps_i2c.h"
#include "modules/gps/gps_i2c.h"
#include "mcu_periph/i2c.h"
#include "subsystems/gps.h"

Expand Down
File renamed without changes.
Expand Up @@ -19,6 +19,13 @@
* Boston, MA 02111-1307, USA.
*/

/**
* @file modules/light/led_safety_status.c
*
* Simple module to blink LEDs when battery voltage drops below a certain
* level, radio control is lost or when takeoff safety conditions are not met.
*/

#include "led.h"
#include "generated/airframe.h"
#include "subsystems/electrical.h"
Expand All @@ -27,7 +34,7 @@
#include "subsystems/ahrs/ahrs_aligner.h"
#include "autopilot_rc_helpers.h"

#include "led_safety_status.h"
#include "modules/light/led_safety_status.h"

#ifndef SAFETY_WARNING_LED
#error You must define SAFETY_WARNING_LED to use this module!
Expand Down
@@ -1,4 +1,3 @@

/*
* Copyright (C) 2012 Pranay Sinha <psinha@transition-robotics.com>
*
Expand All @@ -21,7 +20,7 @@
*/

/**
* @file led_safety_status.h
* @file modules/light/led_safety_status.h
*
* Simple module to blink LEDs when battery voltage drops below a certain
* level, radio control is lost or when takeoff safety conditions are not met.
Expand Down
@@ -1,4 +1,29 @@
#include "modules/poles/nav_poles.h"
/*
* Copyright (C) 2009-2015 ENAC
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/

/**
* @file modules/nav/nav_poles.c
*
*/

#include "modules/nav/nav_poles.h"
#include "subsystems/navigation/common_nav.h"

uint8_t nav_poles_count = 0;
Expand Down Expand Up @@ -29,3 +54,4 @@ bool nav_poles_init(uint8_t wp1, uint8_t wp2,

return false;
}

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 Antoine Drouin <poinix@gmail.com>
* Copyright (C) 2009-2015 ENAC
*
* This file is part of paparazzi.
*
Expand All @@ -14,16 +14,30 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* along with paparazzi; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/

/**
* @file modules/nav/nav_poles.h
*
*/

#ifndef NAV_POLES_H
#define NAV_POLES_H

#include <stdbool.h>
#include "std.h"

extern uint8_t nav_poles_count;
extern float nav_poles_time;
extern int8_t nav_poles_land;

bool nav_poles_init(uint8_t wp1, uint8_t wp2,
uint8_t wp1c, uint8_t wp2c,
float radius);

#ifndef FMS_PERIODIC_H
#define FMS_PERIODIC_H
#define nav_poles_SetLandDir(_d) { if (_d < 0) _d = -1; else _d = 1; }

extern int fms_periodic_init(void(*periodic_handler)(int));
#endif

#endif /* FMS_PERIODIC_H */
375 changes: 375 additions & 0 deletions sw/airborne/modules/nav/nav_survey_rectangle_rotorcraft.c
@@ -0,0 +1,375 @@
/*
* Copyright (C) 2007-2009 ENAC, Pascal Brisset, Antoine Drouin
* 2015 NAC-VA, Eduardo Lavratti
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/

/**
* @file modules/nav/nav_survey_rectangle_rotorcraft.c
*
* Automatic survey of a rectangle for rotorcraft.
*
* Rectangle is defined by two points, sweep can be south-north or west-east.
*/

#ifndef RECTANGLE_SURVEY_DEFAULT_SWEEP
#define RECTANGLE_SURVEY_DEFAULT_SWEEP 25
#endif

#ifdef RECTANGLE_SURVEY_USE_INTERLEAVE
#define USE_INTERLEAVE TRUE
#else
#define USE_INTERLEAVE FALSE
#endif

#include "mcu_periph/uart.h"
#include "messages.h"
#include "subsystems/datalink/downlink.h"

#if PERIODIC_TELEMETRY
#include "subsystems/datalink/telemetry.h"
#endif

#include "firmwares/rotorcraft/navigation.h"

#include "modules/nav/nav_survey_rectangle_rotorcraft.h"
#include "state.h"

float sweep = RECTANGLE_SURVEY_DEFAULT_SWEEP;
static bool_t nav_survey_rectangle_active = FALSE;
uint16_t rectangle_survey_sweep_num;
bool_t nav_in_segment = FALSE;
bool_t nav_in_circle = FALSE;
bool_t interleave = USE_INTERLEAVE;

static struct EnuCoor_f survey_from, survey_to;
static struct EnuCoor_i survey_from_i, survey_to_i;

static bool_t survey_uturn __attribute__((unused)) = FALSE;
static survey_orientation_t survey_orientation = NS;

float nav_survey_shift;
float nav_survey_west, nav_survey_east, nav_survey_north, nav_survey_south;

#define SurveyGoingNorth() ((survey_orientation == NS) && (survey_to.y > survey_from.y))
#define SurveyGoingSouth() ((survey_orientation == NS) && (survey_to.y < survey_from.y))
#define SurveyGoingEast() ((survey_orientation == WE) && (survey_to.x > survey_from.x))
#define SurveyGoingWest() ((survey_orientation == WE) && (survey_to.x < survey_from.x))

#include "generated/flight_plan.h"

#ifndef LINE_START_FUNCTION
#define LINE_START_FUNCTION {}
#endif
#ifndef LINE_STOP_FUNCTION
#define LINE_STOP_FUNCTION {}
#endif

static void send_survey(struct transport_tx *trans, struct link_device *dev)
{
if (nav_survey_active) {
pprz_msg_send_SURVEY(trans, dev, AC_ID,
&nav_survey_east, &nav_survey_north, &nav_survey_west, &nav_survey_south);
}
}

void nav_survey_rectangle_rotorcraft_init(void)
{
#if PERIODIC_TELEMETRY
register_periodic_telemetry(DefaultPeriodic, "SURVEY", send_survey);
#endif
}

bool_t nav_survey_rectangle_rotorcraft_setup(uint8_t wp1, uint8_t wp2, float grid, survey_orientation_t so)
{
rectangle_survey_sweep_num = 0;
nav_survey_west = Min(WaypointX(wp1), WaypointX(wp2));
nav_survey_east = Max(WaypointX(wp1), WaypointX(wp2));
nav_survey_south = Min(WaypointY(wp1), WaypointY(wp2));
nav_survey_north = Max(WaypointY(wp1), WaypointY(wp2));
survey_orientation = so;

if (survey_orientation == NS) {
if (fabsf(stateGetPositionEnu_f()->x - nav_survey_west) < fabsf(stateGetPositionEnu_f()->x - nav_survey_east)) {
survey_from.x = survey_to.x = nav_survey_west + grid / 4.;
} else {
survey_from.x = survey_to.x = nav_survey_east - grid / 4.;
grid = -grid;
}

if (fabsf(stateGetPositionEnu_f()->y - nav_survey_south) > fabsf(stateGetPositionEnu_f()->y - nav_survey_north)) {
survey_to.y = nav_survey_south;
survey_from.y = nav_survey_north;
} else {
survey_from.y = nav_survey_south;
survey_to.y = nav_survey_north;
}
} else { /* survey_orientation == WE */
if (fabsf(stateGetPositionEnu_f()->y - nav_survey_south) < fabsf(stateGetPositionEnu_f()->y - nav_survey_north)) {
survey_from.y = survey_to.y = nav_survey_south + grid / 4.;
} else {
survey_from.y = survey_to.y = nav_survey_north - grid / 4.;
grid = -grid;
}

if (fabsf(stateGetPositionEnu_f()->x - nav_survey_west) > fabsf(stateGetPositionEnu_f()->x - nav_survey_east)) {
survey_to.x = nav_survey_west;
survey_from.x = nav_survey_east;
} else {
survey_from.x = nav_survey_west;
survey_to.x = nav_survey_east;
}
}
nav_survey_shift = grid;
survey_uturn = FALSE;
nav_survey_rectangle_active = FALSE;

//go to start position
ENU_BFP_OF_REAL(survey_from_i, survey_from);
horizontal_mode = HORIZONTAL_MODE_ROUTE;
VECT3_COPY(navigation_target, survey_from_i);
LINE_STOP_FUNCTION;
NavVerticalAltitudeMode(waypoints[wp1].enu_f.z, 0.);
if (survey_orientation == NS) {
nav_set_heading_deg(0);
} else {
nav_set_heading_deg(90);
}
return FALSE;
}


bool_t nav_survey_rectangle_rotorcraft_run(uint8_t wp1, uint8_t wp2)
{
static bool_t is_last_half = FALSE;
static float survey_radius;
nav_survey_active = TRUE;

/* entry scan */ // wait for start position and altitude be reached
if (!nav_survey_rectangle_active && ((!nav_approaching_from(&survey_from_i, NULL, 0))
|| (fabsf(stateGetPositionEnu_f()->z - waypoints[wp1].enu_f.z)) > 1.)) {
} else {
if (!nav_survey_rectangle_active) {
nav_survey_rectangle_active = TRUE;
LINE_START_FUNCTION;
}

nav_survey_west = Min(WaypointX(wp1), WaypointX(wp2));
nav_survey_east = Max(WaypointX(wp1), WaypointX(wp2));
nav_survey_south = Min(WaypointY(wp1), WaypointY(wp2));
nav_survey_north = Max(WaypointY(wp1), WaypointY(wp2));

/* Update the current segment from corners' coordinates*/
if (SurveyGoingNorth()) {
survey_to.y = nav_survey_north;
survey_from.y = nav_survey_south;
} else if (SurveyGoingSouth()) {
survey_to.y = nav_survey_south;
survey_from.y = nav_survey_north;
} else if (SurveyGoingEast()) {
survey_to.x = nav_survey_east;
survey_from.x = nav_survey_west;
} else if (SurveyGoingWest()) {
survey_to.x = nav_survey_west;
survey_from.x = nav_survey_east;
}

if (!survey_uturn) { /* S-N, N-S, W-E or E-W straight route */
/* if you like to use position croos instead of approaching uncoment this line
if ((stateGetPositionEnu_f()->y < nav_survey_north && SurveyGoingNorth()) ||
(stateGetPositionEnu_f()->y > nav_survey_south && SurveyGoingSouth()) ||
(stateGetPositionEnu_f()->x < nav_survey_east && SurveyGoingEast()) ||
(stateGetPositionEnu_f()->x > nav_survey_west && SurveyGoingWest())) {
*/
/* Continue ... */
ENU_BFP_OF_REAL(survey_to_i, survey_to);

if (!nav_approaching_from(&survey_to_i, NULL, 0)) {
ENU_BFP_OF_REAL(survey_from_i, survey_from);

horizontal_mode = HORIZONTAL_MODE_ROUTE;
nav_route(&survey_from_i, &survey_to_i);

} else {
if (survey_orientation == NS) {
/* North or South limit reached, prepare turn and next leg */
float x0 = survey_from.x; /* Current longitude */
if ((x0 + nav_survey_shift < nav_survey_west)
|| (x0 + nav_survey_shift > nav_survey_east)) { // not room for full sweep
if (((x0 + (nav_survey_shift / 2)) < nav_survey_west)
|| ((x0 + (nav_survey_shift / 2)) > nav_survey_east)) { //not room for half sweep
if (is_last_half) {// was last sweep half?
nav_survey_shift = -nav_survey_shift;
if (interleave) {
survey_radius = nav_survey_shift;
}else {
survey_radius = nav_survey_shift /2.;
}
is_last_half = FALSE;
} else { // last sweep not half
nav_survey_shift = -nav_survey_shift;
if (interleave) {
survey_radius = nav_survey_shift /2.;
}else{
survey_radius = nav_survey_shift ;
}
}
rectangle_survey_sweep_num ++;
} else { //room for half sweep after
survey_radius = nav_survey_shift / 2.;
is_last_half = TRUE;
}
} else {// room for full sweep after
survey_radius = nav_survey_shift;
}

x0 = x0 + survey_radius; /* Longitude of next leg */
survey_from.x = survey_to.x = x0;

/* Swap South and North extremities */
float tmp = survey_from.y;
survey_from.y = survey_to.y;
survey_to.y = tmp;

/** Do half a circle around WP 0 */
waypoints[0].enu_f.x = x0;
waypoints[0].enu_f.y = survey_from.y;

/* Computes the right direction */
if (SurveyGoingEast()) {
survey_radius = -survey_radius;
}
} else { /* (survey_orientation == WE) */
/* East or West limit reached, prepare turn and next leg */
/* There is a y0 declared in math.h (for ARM) !!! */
float my_y0 = survey_from.y; /* Current latitude */
if (my_y0 + nav_survey_shift < nav_survey_south
|| my_y0 + nav_survey_shift > nav_survey_north) { // not room for full sweep
if (((my_y0 + (nav_survey_shift / 2)) < nav_survey_south)
|| ((my_y0 + (nav_survey_shift / 2)) > nav_survey_north)) { //not room for half sweep
if (is_last_half) {// was last sweep half?
nav_survey_shift = -nav_survey_shift;
if (interleave) {
survey_radius = nav_survey_shift;
}else {
survey_radius = nav_survey_shift /2.;
}
is_last_half = FALSE;
} else { // last sweep not half
nav_survey_shift = -nav_survey_shift;
if (interleave) {
survey_radius = nav_survey_shift /2.;
}else{
survey_radius = nav_survey_shift ;
}
}
rectangle_survey_sweep_num ++;
} else { //room for half sweep after
survey_radius = nav_survey_shift / 2.;
is_last_half = TRUE;
}
} else {// room for full sweep after
survey_radius = nav_survey_shift;
}

my_y0 = my_y0 + survey_radius; /* latitude of next leg */
survey_from.y = survey_to.y = my_y0;

/* Swap West and East extremities */
float tmp = survey_from.x;
survey_from.x = survey_to.x;
survey_to.x = tmp;

/** Do half a circle around WP 0 */
waypoints[0].enu_f.x = survey_from.x;
waypoints[0].enu_f.y = my_y0;

/* Computes the right direction */
if (SurveyGoingNorth()) {
survey_radius = -survey_radius;
}
}

nav_in_segment = FALSE;
survey_uturn = TRUE;
LINE_STOP_FUNCTION;
#ifdef DIGITAL_CAM
float temp;
if (survey_orientation == NS) {
temp = fabsf(nav_survey_north - nav_survey_south) / dc_distance_interval;
} else{
temp = fabsf(nav_survey_west - nav_survey_east) / dc_distance_interval;
}
double inteiro;
double fract = modf (temp , &inteiro);
if (fract > .5) {
dc_send_command(DC_SHOOT); //if last shot is more than shot_distance/2 from the corner take a picture in the corner before go to the next sweep
}
#endif
}
} else { /* START turn */

static struct EnuCoor_f temp_f;
if (survey_orientation == WE) {
temp_f.x = waypoints[0].enu_f.x;
temp_f.y = waypoints[0].enu_f.y - survey_radius;
} else {
temp_f.y = waypoints[0].enu_f.y;
temp_f.x = waypoints[0].enu_f.x - survey_radius;
}

//detect when segment has done
/* if you like to use position croos instead of approaching uncoment this line
if ( (stateGetPositionEnu_f()->y > waypoints[0].enu_f.y && ((survey_orientation == WE) && (temp_f.y < waypoints[0].enu_f.y)) )||
(stateGetPositionEnu_f()->y < waypoints[0].enu_f.y && ((survey_orientation == WE) && (temp_f.y > waypoints[0].enu_f.y)) )||
(stateGetPositionEnu_f()->x < waypoints[0].enu_f.x && ((survey_orientation == NS) && (temp_f.x > waypoints[0].enu_f.x)) )||
(stateGetPositionEnu_f()->x > waypoints[0].enu_f.x && ((survey_orientation == NS) && (temp_f.x < waypoints[0].enu_f.x)) ) ) {
*/

if (survey_orientation == WE) {
ENU_BFP_OF_REAL(survey_from_i, temp_f);
ENU_BFP_OF_REAL(survey_to_i, waypoints[0].enu_f);
} else {
ENU_BFP_OF_REAL(survey_from_i, temp_f);
ENU_BFP_OF_REAL(survey_to_i, waypoints[0].enu_f);
}
if (nav_approaching_from(&survey_to_i, NULL, 0)) {
survey_uturn = FALSE;
nav_in_circle = FALSE;
LINE_START_FUNCTION;
} else {

if (survey_orientation == WE) {
ENU_BFP_OF_REAL(survey_from_i, temp_f);
ENU_BFP_OF_REAL(survey_to_i, waypoints[0].enu_f);
} else {
ENU_BFP_OF_REAL(survey_from_i, temp_f);
ENU_BFP_OF_REAL(survey_to_i, waypoints[0].enu_f);
}

horizontal_mode = HORIZONTAL_MODE_ROUTE;
nav_route(&survey_from_i, &survey_to_i);
}
} /* END turn */

} /* END entry scan */
return TRUE;

}// /* END survey_retangle */

50 changes: 50 additions & 0 deletions sw/airborne/modules/nav/nav_survey_rectangle_rotorcraft.h
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2007-2009 ENAC, Pascal Brisset, Antoine Drouin
* 2015 NAC-VA, Eduardo Lavratti
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/

/**
* @file modules/nav/nav_survey_rectangle_rotorcraft.h
*
* Automatic survey of a rectangle for rotorcraft.
*
* Rectangle is defined by two points, sweep can be south-north or west-east.
*/

#ifndef NAV_SURVEY_RECTANGLE_ROTORCRAFT_H
#define NAV_SURVEY_RECTANGLE_ROTORCRAFT_H

#include "firmwares/rotorcraft/navigation.h"

typedef enum {NS, WE} survey_orientation_t;

extern float sweep;
extern uint16_t rectangle_survey_sweep_num;
extern bool_t interleave;


extern void nav_survey_rectangle_rotorcraft_init(void);
extern bool_t nav_survey_rectangle_rotorcraft_setup(uint8_t wp1, uint8_t wp2, float grid1, survey_orientation_t so);
extern bool_t nav_survey_rectangle_rotorcraft_run(uint8_t wp1, uint8_t wp2);

#define NavSurveyRectangleInit(_wp1, _wp2, _grid, _orientation) nav_survey_rectangle_rotorcraft_setup(_wp1, _wp2, _grid, _orientation)
#define NavSurveyRectangle(_wp1, _wp2) nav_survey_rectangle_rotorcraft_run(_wp1, _wp2)

#endif // NAV_SURVEY_RECTANGLE_ROTORCRAFT_H
17 changes: 0 additions & 17 deletions sw/airborne/modules/poles/nav_poles.h

This file was deleted.

7 changes: 4 additions & 3 deletions sw/airborne/modules/sensors/airspeed_amsys.c
@@ -1,6 +1,7 @@
/*
* Driver for a Amsys Differential Presure Sensor I2C
* AMS 5812-0003-D
* AMS 5812-0001-D
*
* Copyright (C) 2010 The Paparazzi Team
*
Expand Down Expand Up @@ -42,7 +43,7 @@
#define AIRSPEED_AMSYS_OFFSET_NBSAMPLES_AVRG 60
#define AIRSPEED_AMSYS_NBSAMPLES_AVRG 10
#ifndef AIRSPEED_AMSYS_MAXPRESURE
#define AIRSPEED_AMSYS_MAXPRESURE 2068 //003-2068, 001-689 //Pascal
#define AIRSPEED_AMSYS_MAXPRESURE 2068 //003-2068, 001-1034 //Pascal
#endif
#ifndef AIRSPEED_AMSYS_FILTER
#define AIRSPEED_AMSYS_FILTER 0
Expand All @@ -53,7 +54,7 @@
#ifdef MEASURE_AMSYS_TEMPERATURE
#define TEMPERATURE_AMSYS_OFFSET_MAX 29491
#define TEMPERATURE_AMSYS_OFFSET_MIN 3277
#define TEMPERATURE_AMSYS_MAX 110
#define TEMPERATURE_AMSYS_MAX 85
#define TEMPERATURE_AMSYS_MIN -25
#endif

Expand Down Expand Up @@ -147,7 +148,7 @@ void airspeed_amsys_read_event(void)
airspeed_amsys_raw = (airspeed_amsys_i2c_trans.buf[0] << 8) | airspeed_amsys_i2c_trans.buf[1];
#ifdef MEASURE_AMSYS_TEMPERATURE
tempAS_amsys_raw = (airspeed_amsys_i2c_trans.buf[2] << 8) | airspeed_amsys_i2c_trans.buf[3];
const float temp_off_scale = (float)(TEMPERATURE_AMSYS_MAX) /
const float temp_off_scale = (float)(TEMPERATURE_AMSYS_MAX - TEMPERATURE_AMSYS_MIN) /
(TEMPERATURE_AMSYS_OFFSET_MAX - TEMPERATURE_AMSYS_OFFSET_MIN);
// Tmin=-25, Tmax=85
airspeed_temperature = temp_off_scale * (tempAS_amsys_raw - TEMPERATURE_AMSYS_OFFSET_MIN) +
Expand Down
1 change: 1 addition & 0 deletions sw/airborne/modules/sensors/airspeed_amsys.h
@@ -1,6 +1,7 @@
/*
* Driver for a Amsys Differential Presure Sensor I2C
* AMS 5812-0003-D
* AMS 5812-0001-D
*
* Copyright (C) 2010 The Paparazzi Team
*
Expand Down
9 changes: 6 additions & 3 deletions sw/airborne/modules/sensors/baro_amsys.c
Expand Up @@ -57,7 +57,7 @@
#ifdef MEASURE_AMSYS_TEMPERATURE
#define TEMPERATURE_AMSYS_OFFSET_MAX 29491
#define TEMPERATURE_AMSYS_OFFSET_MIN 3277
#define TEMPERATURE_AMSYS_MAX 110
#define TEMPERATURE_AMSYS_MAX 85
#define TEMPERATURE_AMSYS_MIN -25
#endif

Expand Down Expand Up @@ -142,8 +142,11 @@ void baro_amsys_read_event(void)
pBaroRaw = (baro_amsys_i2c_trans.buf[0] << 8) | baro_amsys_i2c_trans.buf[1];
#ifdef MEASURE_AMSYS_TEMPERATURE
tBaroRaw = (baro_amsys_i2c_trans.buf[2] << 8) | baro_amsys_i2c_trans.buf[3];
baro_amsys_temp = (float)(tBaroRaw - TEMPERATURE_AMSYS_OFFSET_MIN) * TEMPERATURE_AMSYS_MAX / (float)(
TEMPERATURE_AMSYS_OFFSET_MAX - TEMPERATURE_AMSYS_OFFSET_MIN) + (float)TEMPERATURE_AMSYS_MIN;
const float temp_off_scale = (float)(TEMPERATURE_AMSYS_MAX - TEMPERATURE_AMSYS_MIN) /
(TEMPERATURE_AMSYS_OFFSET_MAX - TEMPERATURE_AMSYS_OFFSET_MIN);
// Tmin=-25, Tmax=85
baro_amsys_temp = temp_off_scale * (tBaroRaw - TEMPERATURE_AMSYS_OFFSET_MIN) +
TEMPERATURE_AMSYS_MIN;
#endif
// Check if this is valid altimeter
if (pBaroRaw == 0) {
Expand Down
141 changes: 141 additions & 0 deletions sw/airborne/modules/sonar/sonar_bebop.c
@@ -0,0 +1,141 @@
/*
* Copyright (C) 2015 Freek van Tienen <freek.v.tienen@gmail.com>
*
* This file is part of paparazzi.
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/

/** @file modules/sonar/sonar_bebop.c
* @brief Parrot Bebop Sonar driver
*/

#include "sonar_bebop.h"
#include "generated/airframe.h"
#include "mcu_periph/adc.h"
#include "mcu_periph/spi.h"
#include "subsystems/abi.h"
#include <pthread.h>
#include "subsystems/datalink/downlink.h"

#ifdef SITL
#include "state.h"
#endif


struct SonarBebop sonar_bebop;
static uint8_t sonar_bebop_spi_d[16] = { 0xF0,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static struct spi_transaction sonar_bebop_spi_t;
static pthread_t sonar_bebop_thread;
static void *sonar_bebop_read(void *data);

void sonar_bebop_init(void)
{
sonar_bebop.meas = 0;
sonar_bebop.offset = 0;

sonar_bebop_spi_t.status = SPITransDone;
sonar_bebop_spi_t.select = SPISelectUnselect;
sonar_bebop_spi_t.dss = SPIDss8bit;
sonar_bebop_spi_t.output_buf = sonar_bebop_spi_d;
sonar_bebop_spi_t.output_length = 16;
sonar_bebop_spi_t.input_buf = NULL;
sonar_bebop_spi_t.input_length = 0;

int rc = pthread_create(&sonar_bebop_thread, NULL, sonar_bebop_read, NULL);
if (rc < 0) {
return;
}
}

/**
* Read ADC value to update sonar measurement
*/
static void *sonar_bebop_read(void *data __attribute__((unused)))
{
while(true) {

#ifndef SITL
uint16_t i;
uint16_t adc_buffer[8192];


/* Start ADC and send sonar output */
adc_enable(&adc0, 1);
sonar_bebop_spi_t.status = SPITransDone;
spi_submit(&spi0, &sonar_bebop_spi_t);
while(sonar_bebop_spi_t.status != SPITransSuccess);
adc_read(&adc0, adc_buffer, 8192);
adc_enable(&adc0, 0);

/* Find the peeks */
uint16_t start_send = 0;
uint16_t stop_send = 0;
uint16_t first_peek = 0;
uint16_t lowest_value = 4095;
for(i = 0; i < 8192; i++){
uint16_t adc_val = adc_buffer[i]>>4;
if(start_send == 0 && adc_val == 4095)
start_send = i;
else if(start_send != 0 && stop_send == 0 && adc_val != 4095)
{
stop_send = i-1;
i += 300;
continue;
}

if(start_send != 0 && stop_send != 0 && first_peek == 0 && adc_val < lowest_value)
lowest_value = adc_val;
else if (start_send != 0 && stop_send != 0 && adc_val > lowest_value + 100) {
first_peek = i;
lowest_value = adc_val - 100;
}
else if(start_send != 0 && stop_send != 0 && first_peek != 0 && adc_val+100 < (adc_buffer[first_peek]>>4)) {
break;
}
}

/* Calculate the distance from the peeks */
uint16_t diff = stop_send - start_send;
int16_t peek_distance = first_peek - (stop_send - diff/2);
if(first_peek <= stop_send || diff > 250)
peek_distance = 0;

sonar_bebop.distance = peek_distance / 1000.0;
#else // SITL
sonar_bebop.distance = stateGetPositionEnu_f()->z;
Bound(sonar_bebop.distance, 0.1f, 7.0f);
uint16_t peek_distance = 1;
#endif // SITL

usleep(10000);

if(peek_distance > 0)
{
// Send ABI message
AbiSendMsgAGL(AGL_SONAR_ADC_ID, sonar_bebop.distance);

#ifdef SENSOR_SYNC_SEND_SONAR
// Send Telemetry report
DOWNLINK_SEND_SONAR(DefaultChannel, DefaultDevice, &sonar_bebop.meas, &sonar_bebop.distance);
#endif
}
}

return NULL;
}

@@ -1,6 +1,5 @@

/*
* Copyright (C) 2010 Eric Parsonage
* Copyright (C) 2015 Freek van Tienen <freek.v.tienen@gmail.com>
*
* This file is part of paparazzi.
*
Expand All @@ -18,17 +17,26 @@
* along with paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/

/** @file modules/sonar/sonar_bebop.h
* @brief Parrot Bebop Sonar driver
*/

#ifndef DEPLOY_SONAR_BUOY_H
#define DEPLOY_SONAR_BUOY_H
#ifndef SONAR_BEBOP_H
#define SONAR_BEBOP_H

#include "std.h"

extern bool_t buoy_1;
extern bool_t buoy_2;
extern void deploy_sonar_buoy_init(void);
extern void deploy_sonar_buoy_periodic(void);
struct SonarBebop {
uint16_t meas; ///< Raw ADC value
uint16_t offset; ///< Sonar offset in ADC units
float distance; ///< Distance measured in meters
};

extern struct SonarBebop sonar_bebop;

extern void sonar_bebop_init(void);

#endif /* DEPLOY_SONAR_BUOY_H */
#endif /* SONAR_BEBOP_H */
24 changes: 12 additions & 12 deletions sw/airborne/state.c
Expand Up @@ -70,20 +70,20 @@ void stateCalcPositionEcef_i(void)

if (bit_is_set(state.pos_status, POS_ECEF_F)) {
ECEF_BFP_OF_REAL(state.ecef_pos_i, state.ecef_pos_f);
} else if (bit_is_set(state.pos_status, POS_NED_I)) {
} else if (bit_is_set(state.pos_status, POS_NED_I) && state.ned_initialized_i) {
ecef_of_ned_pos_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i);
} else if (bit_is_set(state.pos_status, POS_NED_F)) {
} else if (bit_is_set(state.pos_status, POS_NED_F) && state.ned_initialized_f) {
/* transform ned_f to ecef_f, set status bit, then convert to int */
ecef_of_ned_point_f(&state.ecef_pos_f, &state.ned_origin_f, &state.ned_pos_f);
SetBit(state.pos_status, POS_ECEF_F);
ECEF_BFP_OF_REAL(state.ecef_pos_i, state.ecef_pos_f);
} else if (bit_is_set(state.pos_status, POS_LLA_I)) {
ecef_of_lla_i(&state.ecef_pos_i, &state.lla_pos_i);
} else if (bit_is_set(state.pos_status, POS_LLA_F)) {
/* transform lla_f to ecef_f, set status bit, then convert to int */
ecef_of_lla_f(&state.ecef_pos_f, &state.lla_pos_f);
SetBit(state.pos_status, POS_ECEF_F);
ECEF_BFP_OF_REAL(state.ecef_pos_i, state.ecef_pos_f);
} else if (bit_is_set(state.pos_status, POS_LLA_I)) {
ecef_of_lla_i(&state.ecef_pos_i, &state.lla_pos_i);
} else {
/* could not get this representation, set errno */
//struct EcefCoor_i _ecef_zero = {0};
Expand Down Expand Up @@ -270,24 +270,24 @@ void stateCalcPositionLla_i(void)
ECEF_BFP_OF_REAL(state.ecef_pos_i, state.ecef_pos_f);
SetBit(state.pos_status, POS_ECEF_I);
lla_of_ecef_i(&state.lla_pos_i, &state.ecef_pos_i);
} else if (bit_is_set(state.pos_status, POS_NED_I)) {
} else if (bit_is_set(state.pos_status, POS_NED_I) && state.ned_initialized_i) {
/* transform ned_i -> ecef_i -> lla_i, set status bits */
ecef_of_ned_pos_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i);
SetBit(state.pos_status, POS_ECEF_I);
lla_of_ecef_i(&state.lla_pos_i, &state.ecef_pos_i);
} else if (bit_is_set(state.pos_status, POS_ENU_I)) {
} else if (bit_is_set(state.pos_status, POS_ENU_I) && state.ned_initialized_i) {
/* transform enu_i -> ecef_i -> lla_i, set status bits */
ecef_of_enu_pos_i(&state.ecef_pos_i, &state.ned_origin_i, &state.enu_pos_i);
SetBit(state.pos_status, POS_ECEF_I);
lla_of_ecef_i(&state.lla_pos_i, &state.ecef_pos_i);
} else if (bit_is_set(state.pos_status, POS_NED_F)) {
} else if (bit_is_set(state.pos_status, POS_NED_F) && state.ned_initialized_i) {
/* transform ned_f -> ned_i -> ecef_i -> lla_i, set status bits */
NED_BFP_OF_REAL(state.ned_pos_i, state.ned_pos_f);
SetBit(state.pos_status, POS_NED_I);
ecef_of_ned_pos_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i);
SetBit(state.pos_status, POS_ECEF_I);
lla_of_ecef_i(&state.lla_pos_i, &state.ecef_pos_i);
} else if (bit_is_set(state.pos_status, POS_ENU_F)) {
} else if (bit_is_set(state.pos_status, POS_ENU_F) && state.ned_initialized_i) {
/* transform enu_f -> enu_i -> ecef_i -> lla_i, set status bits */
ENU_BFP_OF_REAL(state.enu_pos_i, state.enu_pos_f);
SetBit(state.pos_status, POS_ENU_I);
Expand Down Expand Up @@ -354,9 +354,9 @@ void stateCalcPositionEcef_f(void)

if (bit_is_set(state.pos_status, POS_ECEF_I)) {
ECEF_FLOAT_OF_BFP(state.ecef_pos_f, state.ecef_pos_i);
} else if (bit_is_set(state.pos_status, POS_NED_F)) {
} else if (bit_is_set(state.pos_status, POS_NED_F) && &state.ned_initialized_f) {
ecef_of_ned_point_f(&state.ecef_pos_f, &state.ned_origin_f, &state.ned_pos_f);
} else if (bit_is_set(state.pos_status, POS_NED_I)) {
} else if (bit_is_set(state.pos_status, POS_NED_I) && &state.ned_initialized_i) {
/* transform ned_i -> ecef_i -> ecef_f, set status bits */
ecef_of_ned_pos_i(&state.ecef_pos_i, &state.ned_origin_i, &state.ned_pos_i);
SetBit(state.pos_status, POS_ECEF_F);
Expand Down Expand Up @@ -529,12 +529,12 @@ void stateCalcPositionLla_f(void)
ECEF_FLOAT_OF_BFP(state.ecef_pos_f, state.ecef_pos_i);
SetBit(state.pos_status, POS_ECEF_F);
lla_of_ecef_f(&state.lla_pos_f, &state.ecef_pos_f);
} else if (bit_is_set(state.pos_status, POS_NED_F)) {
} else if (bit_is_set(state.pos_status, POS_NED_F) && state.ned_initialized_f) {
/* transform ned_f -> ecef_f -> lla_f, set status bits */
ecef_of_ned_point_f(&state.ecef_pos_f, &state.ned_origin_f, &state.ned_pos_f);
SetBit(state.pos_status, POS_ECEF_F);
lla_of_ecef_f(&state.lla_pos_f, &state.ecef_pos_f);
} else if (bit_is_set(state.pos_status, POS_NED_I)) {
} else if (bit_is_set(state.pos_status, POS_NED_I) && state.ned_initialized_f) {
/* transform ned_i -> ned_f -> ecef_f -> lla_f, set status bits */
NED_FLOAT_OF_BFP(state.ned_pos_f, state.ned_pos_i);
SetBit(state.pos_status, POS_NED_F);
Expand Down
94 changes: 71 additions & 23 deletions sw/airborne/subsystems/actuators/motor_mixing.c
Expand Up @@ -109,25 +109,25 @@ void motor_mixing_init(void)
motor_mixing.nb_saturation = 0;
}

__attribute__((always_inline)) static inline void offset_commands(int32_t offset)
static void offset_commands(int32_t offset)
{
uint8_t j;
for (j = 0; j < MOTOR_MIXING_NB_MOTOR; j++) {
motor_mixing.commands[j] += (offset);
}
}

__attribute__((always_inline)) static inline void bound_commands(void)
static void bound_commands(void)
{
uint8_t j;
for (j = 0; j < MOTOR_MIXING_NB_MOTOR; j++)
Bound(motor_mixing.commands[j],
MOTOR_MIXING_MIN_MOTOR, MOTOR_MIXING_MAX_MOTOR);
for (j = 0; j < MOTOR_MIXING_NB_MOTOR; j++) {
Bound(motor_mixing.commands[j], MOTOR_MIXING_MIN_MOTOR, MOTOR_MIXING_MAX_MOTOR);
}
}

#ifdef MOTOR_MIXING_USE_MAX_MOTOR_STEP_BINDING
__attribute__((always_inline)) static inline void bound_commands_step(void)
static void bound_commands_step(void)
{
#ifdef MOTOR_MIXING_USE_MAX_MOTOR_STEP_BINDING
uint8_t j;
static int32_t prev_commands[MOTOR_MIXING_NB_MOTOR];
static uint8_t initialized = 0;
Expand All @@ -146,22 +146,20 @@ __attribute__((always_inline)) static inline void bound_commands_step(void)
for (j = 0; j < MOTOR_MIXING_NB_MOTOR; j++) {
prev_commands[j] = motor_mixing.commands[j];
}
}
#else
__attribute__((always_inline)) static inline void bound_commands_step(void)
{
}
#endif
}

void motor_mixing_run_spinup(uint32_t counter, uint32_t max_counter)
{
int i;
for (i = 0; i < MOTOR_MIXING_NB_MOTOR; i++) {
#ifdef MOTOR_MIXING_STARTUP_DELAY
if (counter > i * max_counter / (MOTOR_MIXING_NB_MOTOR + MOTOR_MIXING_STARTUP_DELAY)) {
if (counter > MOTOR_MIXING_NB_MOTOR * max_counter / (MOTOR_MIXING_NB_MOTOR + MOTOR_MIXING_STARTUP_DELAY)) {
motor_mixing.commands[i] = MOTOR_MIXING_MIN_MOTOR_STARTUP + (MOTOR_MIXING_MIN_MOTOR - MOTOR_MIXING_MIN_MOTOR_STARTUP) *
counter / max_counter;
if (counter > MOTOR_MIXING_NB_MOTOR * max_counter /
(MOTOR_MIXING_NB_MOTOR + MOTOR_MIXING_STARTUP_DELAY))
{
motor_mixing.commands[i] = MOTOR_MIXING_MIN_MOTOR_STARTUP +
(MOTOR_MIXING_MIN_MOTOR - MOTOR_MIXING_MIN_MOTOR_STARTUP) * counter / max_counter;
} else {
motor_mixing.commands[i] = MOTOR_MIXING_MIN_MOTOR_STARTUP;
}
Expand All @@ -184,17 +182,67 @@ void motor_mixing_run(bool_t motors_on, bool_t override_on, pprz_t in_cmd[])
#else
if (FALSE) {
#endif
/* mean of trim+roll+pitch commands */
int32_t mean_cmd = 0;

/* first calculate the highest priority part of the command:
* - trim + roll/pitch for each motor
* - record mean of that
* - add thrust command
* - record min/max including thrust
*/
for (i = 0; i < MOTOR_MIXING_NB_MOTOR; i++) {
motor_mixing.commands[i] = motor_mixing.trim[i] +
roll_coef[i] * in_cmd[COMMAND_ROLL] +
pitch_coef[i] * in_cmd[COMMAND_PITCH];
/* sum up for mean (average) trim+roll+pitch cmd */
mean_cmd += motor_mixing.commands[i];
}

/* divide sum by number of motors and scale to get mean thrust */
mean_cmd /= (MOTOR_MIXING_NB_MOTOR * MOTOR_MIXING_SCALE);

/* calculate thrust_cmd */
int32_t thrust_cmd = in_cmd[COMMAND_THRUST] - mean_cmd;
Bound(thrust_cmd, 0, MAX_PPRZ);

int32_t tmp_cmd;
int32_t max_overflow = 0;

/* add thrust command and scale */
for (i = 0; i < MOTOR_MIXING_NB_MOTOR; i++) {
motor_mixing.commands[i] += thrust_coef[i] * thrust_cmd;

/* compute the command with yaw for each motor to check how much it would saturate */
tmp_cmd = motor_mixing.commands[i] + yaw_coef[i] * in_cmd[COMMAND_YAW];
tmp_cmd /= MOTOR_MIXING_SCALE;

/* remember max overflow (how much in saturation) */
if (-tmp_cmd > max_overflow) {
max_overflow = -tmp_cmd;
}
else if (tmp_cmd - MAX_PPRZ > max_overflow) {
max_overflow = tmp_cmd - MAX_PPRZ;
}
}

/* calculate how much authority is left for yaw command */
int32_t yaw_authority = ABS(in_cmd[COMMAND_YAW]) - max_overflow;
Bound(yaw_authority, 0, MAX_PPRZ);
int32_t bounded_yaw_cmd = in_cmd[COMMAND_YAW];
BoundAbs(bounded_yaw_cmd, yaw_authority);

/* min/max of commands */
int32_t min_cmd = INT32_MAX;
int32_t max_cmd = INT32_MIN;
/* do the mixing in float to avoid overflows, implicitly casted back to int32_t */

/* add the bounded yaw command and scale */
for (i = 0; i < MOTOR_MIXING_NB_MOTOR; i++) {
motor_mixing.commands[i] = MOTOR_MIXING_MIN_MOTOR +
(thrust_coef[i] * in_cmd[COMMAND_THRUST] +
roll_coef[i] * in_cmd[COMMAND_ROLL] +
pitch_coef[i] * in_cmd[COMMAND_PITCH] +
yaw_coef[i] * in_cmd[COMMAND_YAW] +
motor_mixing.trim[i]) / MOTOR_MIXING_SCALE *
(MOTOR_MIXING_MAX_MOTOR - MOTOR_MIXING_MIN_MOTOR) / MAX_PPRZ;
motor_mixing.commands[i] += yaw_coef[i] * bounded_yaw_cmd;
motor_mixing.commands[i] /= MOTOR_MIXING_SCALE;

/* remember min/max */
if (motor_mixing.commands[i] < min_cmd) {
min_cmd = motor_mixing.commands[i];
}
Expand Down
1 change: 1 addition & 0 deletions sw/airborne/subsystems/actuators/motor_mixing.h
Expand Up @@ -31,6 +31,7 @@
#include "std.h"
#include "paparazzi.h"
#include "generated/airframe.h"
#include "motor_mixing_types.h"

struct MotorMixing {
int32_t commands[MOTOR_MIXING_NB_MOTOR];
Expand Down
166 changes: 166 additions & 0 deletions sw/airborne/subsystems/actuators/motor_mixing_types.h
@@ -0,0 +1,166 @@
/*
* Copyright (C) 2008-2015 The Paparazzi Team
*
* This file is part of Paparazzi.
*
* Paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* Paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/

/** @file motor_mixing_types.h
* Common Motor Mixing configuration types.
*/

#ifndef MOTOR_MIXING_TYPES_H
#define MOTOR_MIXING_TYPES_H

/* already defined common configurations*/
#define QUAD_PLUS 1
#define QUAD_X 2
#define QUAD_X_CCW 3
#define HEXA_X 4
#define HEXA_PLUS 5
#define OCTO_X 6
#define OCTO_PLUS 7

#if MOTOR_MIXING_TYPE == QUAD_PLUS
/*
* Quadrotor in plus (+) cross configuration with motor order:
* front (CW), right (CCW), back (CW), left (CCW)
*/
#define MOTOR_FRONT 0
#define MOTOR_RIGHT 1
#define MOTOR_BACK 2
#define MOTOR_LEFT 3
#define MOTOR_MIXING_NB_MOTOR 4
#define MOTOR_MIXING_SCALE 256
#define MOTOR_MIXING_ROLL_COEF { 0, -256, 0, 256 }
#define MOTOR_MIXING_PITCH_COEF { 256, 0, -256, 0 }
#define MOTOR_MIXING_YAW_COEF { -128, 128, -128, 128 }
#define MOTOR_MIXING_THRUST_COEF { 256, 256, 256, 256 }

#elif MOTOR_MIXING_TYPE == QUAD_X
/*
* Quadrotor in time cross (X) configuration with motor order:
* front left (CW), front right (CCW), back right (CW), back left (CCW)
*/
#define MOTOR_FRONT_LEFT 0
#define MOTOR_FRONT_RIGHT 1
#define MOTOR_BACK_RIGHT 2
#define MOTOR_BACK_LEFT 3
#define MOTOR_MIXING_NB_MOTOR 4
#define MOTOR_MIXING_SCALE 256
#define MOTOR_MIXING_ROLL_COEF { 181, -181, -181, 181 }
#define MOTOR_MIXING_PITCH_COEF { 181, 181, -181, -181 }
#define MOTOR_MIXING_YAW_COEF { -128, 128, -128, 128 }
#define MOTOR_MIXING_THRUST_COEF { 256, 256, 256, 256 }

#elif MOTOR_MIXING_TYPE == QUAD_X_CCW
/*
* Quadrotor in time cross (X) configuration with motor order (reversed from QUAD_X):
* front left (CCW), front right (CW), back right (CCW), back left (CW)
*/
#define MOTOR_FRONT_LEFT 0
#define MOTOR_FRONT_RIGHT 1
#define MOTOR_BACK_RIGHT 2
#define MOTOR_BACK_LEFT 3
#define MOTOR_MIXING_NB_MOTOR 4
#define MOTOR_MIXING_SCALE 256
#define MOTOR_MIXING_ROLL_COEF { 181, -181, -181, 181 }
#define MOTOR_MIXING_PITCH_COEF { 181, 181, -181, -181 }
#define MOTOR_MIXING_YAW_COEF { 128, -128, 128, -128 }
#define MOTOR_MIXING_THRUST_COEF { 256, 256, 256, 256 }

#elif MOTOR_MIXING_TYPE == HEXA_X
/*
* Hexarotor in time cross (X) configuration with motor order:
* front left (CW), front right (CCW), right (CW), back right (CCW), back left (CW), left (CCW)
*/
#define MOTOR_FRONT_LEFT 0
#define MOTOR_FRONT_RIGHT 1
#define MOTOR_RIGHT 2
#define MOTOR_BACK_RIGHT 3
#define MOTOR_BACK_LEFT 4
#define MOTOR_LEFT 5
#define MOTOR_MIXING_NB_MOTOR 6
#define MOTOR_MIXING_SCALE 256
#define MOTOR_MIXING_ROLL_COEF { 128, -128, -256, -128, 128, 256 }
#define MOTOR_MIXING_PITCH_COEF { 222, 222, 0, -222, -222, 0 }
#define MOTOR_MIXING_YAW_COEF { -128, 128, -128, 128, -128, 128 }
#define MOTOR_MIXING_THRUST_COEF { 256, 256, 256, 256, 256, 256 }

#elif MOTOR_MIXING_TYPE == HEXA_PLUS
/*
* Hexarotor in plus (+) configuration with motor order:
* front (CW), front right (CCW), back right (CW), back (CCW), back left (CW), front left (CCW)
*/
#define MOTOR_FRONT 0
#define MOTOR_FRONT_RIGHT 1
#define MOTOR_BACK_RIGHT 2
#define MOTOR_BACK 3
#define MOTOR_BACK_LEFT 4
#define MOTOR_FRONT_LEFT 5
#define MOTOR_MIXING_NB_MOTOR 6
#define MOTOR_MIXING_SCALE 256
#define MOTOR_MIXING_ROLL_COEF { 0, -222, -222, 0, 222, 222 }
#define MOTOR_MIXING_PITCH_COEF { 256, 128, -128, -256, -128, 128 }
#define MOTOR_MIXING_YAW_COEF { -128, 128, -128, 128, -128, 128 }
#define MOTOR_MIXING_THRUST_COEF { 256, 256, 256, 256, 256, 256 }

#elif MOTOR_MIXING_TYPE == OCTO_PLUS
/*
* Hexarotor in plus cross (+) configuration with motor order:
* front (CW), front right (CCW), right (CW), back right (CCW),
* back (CW), back left (CCW), left (CW), front left (CCW)
*/
#define MOTOR_FRONT 0
#define MOTOR_FRONT_RIGHT 1
#define MOTOR_RIGHT 2
#define MOTOR_BACK_RIGHT 3
#define MOTOR_BACK 4
#define MOTOR_BACK_LEFT 5
#define MOTOR_LEFT 6
#define MOTOR_FRONT_LEFT 7
#define MOTOR_MIXING_NB_MOTOR 8
#define MOTOR_MIXING_SCALE 256
#define MOTOR_MIXING_ROLL_COEF { 0, -181, -256, -181, 0, 181, 256, 181 }
#define MOTOR_MIXING_PITCH_COEF { 256, 181, 0, -181, -256, -181, 0, 181 }
#define MOTOR_MIXING_YAW_COEF { -128, 128, -128, 128, -128, 128, -128, 128 }
#define MOTOR_MIXING_THRUST_COEF { 256, 256, 256, 256, 256, 256, 256, 256 }

#elif MOTOR_MIXING_TYPE == OCTO_X
/*
* Hexarotor in time cross (X) configuration with motor order:
* front left1 (CW), front right1 (CCW), front right2 (CW), back right1 (CCW),
* back right2 (CW), back left1 (CCW), back left2 (CW), front left2 (CCW)
*/
#define MOTOR_FRONT_LEFT1 0
#define MOTOR_FRONT_RIGHT1 1
#define MOTOR_FRONT_RIGHT2 2
#define MOTOR_BACK_RIGHT1 3
#define MOTOR_BACK_RIGHT2 4
#define MOTOR_BACK_LEFT1 5
#define MOTOR_BACK_LEFT2 6
#define MOTOR_FRONT_LEFT2 7
#define MOTOR_MIXING_NB_MOTOR 8
#define MOTOR_MIXING_SCALE 256
#define MOTOR_MIXING_ROLL_COEF { 98, -98, -237, -237, -98, 98, 237, 237 }
#define MOTOR_MIXING_PITCH_COEF { 237, 237, 98, -98, -237, -237, -98, 98 }
#define MOTOR_MIXING_YAW_COEF { -128, 128, -128, 128, -128, 128, -128, 128 }
#define MOTOR_MIXING_THRUST_COEF { 256, 256, 256, 256, 256, 256, 256, 256 }

#endif

#endif /* MOTOR_MIXING_TYPES_H */
4 changes: 2 additions & 2 deletions sw/airborne/subsystems/ahrs/ahrs_float_mlkf.c
Expand Up @@ -235,7 +235,7 @@ static inline void update_state(const struct FloatVect3 *i_expected, struct Floa

/* converted expected measurement from inertial to body frame */
struct FloatVect3 b_expected;
float_quat_vmult(&b_expected, &ahrs_mlkf.ltp_to_imu_quat, (struct FloatVect3 *)i_expected);
float_quat_vmult(&b_expected, &ahrs_mlkf.ltp_to_imu_quat, i_expected);

// S = HPH' + JRJ
float H[3][6] = {{ 0., -b_expected.z, b_expected.y, 0., 0., 0.},
Expand Down Expand Up @@ -304,7 +304,7 @@ static inline void update_state_heading(const struct FloatVect3 *i_expected,

/* converted expected measurement from inertial to body frame */
struct FloatVect3 b_expected;
float_quat_vmult(&b_expected, &ahrs_mlkf.ltp_to_imu_quat, (struct FloatVect3 *)i_expected);
float_quat_vmult(&b_expected, &ahrs_mlkf.ltp_to_imu_quat, i_expected);

/* set roll/pitch errors to zero to only correct heading */
struct FloatVect3 i_h_2d = {i_expected->y, -i_expected->x, 0.f};
Expand Down
36 changes: 25 additions & 11 deletions sw/airborne/subsystems/chibios-libopencm3/sdLog.c
Expand Up @@ -7,6 +7,8 @@
#include "printf.h"
#include "sdio.h"
#include "rtcAccess.h"
#include <ctype.h>


#define MIN(x , y) (((x) < (y)) ? (x) : (y))
#define MAX(x , y) (((x) > (y)) ? (x) : (y))
Expand Down Expand Up @@ -54,7 +56,7 @@ struct FilePoolUnit {
};

static struct FilePoolUnit fileDes[SDLOG_NUM_BUFFER] =
{[0 ... SDLOG_NUM_BUFFER-1] = {.fil = {0}, .inUse = false, .tagAtClose=false}};
{[0 ... SDLOG_NUM_BUFFER-1] = {.fil = {0}, .inUse = false, .tagAtClose=false}};

typedef enum {
FCNTL_WRITE = 0b00,
Expand Down Expand Up @@ -408,10 +410,11 @@ SdioError getFileName(const char* prefix, const char* directoryName,
fno.lfname = lfn;
fno.lfsize = sizeof lfn;
#endif
const size_t directoryNameLen = strlen (directoryName);
char slashDirName[directoryNameLen+2];
strcpy (slashDirName, "/");
strcat (slashDirName, directoryName);
const size_t directoryNameLen = MIN(strlen (directoryName), 128);
const size_t slashDirNameLen = directoryNameLen+2;
char slashDirName[slashDirNameLen];
strlcpy (slashDirName, "/", slashDirNameLen);
strlcat (slashDirName, directoryName, slashDirNameLen);

rc = f_opendir(&dir, directoryName);
if (rc != FR_OK) {
Expand Down Expand Up @@ -445,9 +448,15 @@ SdioError getFileName(const char* prefix, const char* directoryName,
return SDLOG_FATFS_ERROR;
}

chsnprintf (nextFileName, nameLength, "%s\\%s%.03d.LOG",
directoryName, prefix, maxCurrentIndex+indexOffset);
return SDLOG_OK;
if (maxCurrentIndex < NUMBERMAX) {
chsnprintf (nextFileName, nameLength, NUMBERFMF,
directoryName, prefix, maxCurrentIndex+indexOffset);
return SDLOG_OK;
} else {
chsnprintf (nextFileName, nameLength, "%s\\%s%.ERR",
directoryName, prefix);
return SDLOG_LOGNUM_ERROR;
}
}


Expand All @@ -472,12 +481,17 @@ uint32_t uiGetIndexOfLogFile (const char* prefix, const char* fileName)
const size_t len = strlen(prefix);

// if filename does not began with prefix, return 0
if (strncmp (prefix, fileName, len))
if (strncmp (prefix, fileName, len) != 0)
return 0;

// we point on the first char after prefix
const char* suffix = &(fileName[len]);

// we test that suffix is valid (at least begin with digit)
if (!isdigit ((int) suffix[0])) {
// DebugTrace ("DBG> suffix = %s", suffix);
return 0;
}

return (uint32_t) atoi (suffix);
}
Expand All @@ -494,7 +508,7 @@ static msg_t thdSdLog(void *arg)

UINT bw;
static struct PerfBuffer perfBuffers[SDLOG_NUM_BUFFER] =
{[0 ... SDLOG_NUM_BUFFER-1] = {.buffer = {0}, .size = 0}};
{[0 ... SDLOG_NUM_BUFFER-1] = {.buffer = {0}, .size = 0}};

chRegSetThreadName("thdSdLog");
while (!chThdShouldTerminate()) {
Expand Down Expand Up @@ -536,7 +550,7 @@ static msg_t thdSdLog(void *arg)
case FCNTL_WRITE:
if (fileDes[lm->op.fd].inUse) {
const int32_t messLen = retLen-sizeof(LogMessage);
if (messLen < (int32_t)(SDLOG_WRITE_BUFFER_SIZE-curBufFill)) {
if (messLen < (SDLOG_WRITE_BUFFER_SIZE-curBufFill)) {
// the buffer can accept this message
memcpy (&(perfBuffer[curBufFill]), lm->mess, messLen);
perfBuffers[lm->op.fd].size += messLen; // curBufFill
Expand Down
13 changes: 8 additions & 5 deletions sw/airborne/subsystems/chibios-libopencm3/sdLog.h
@@ -1,9 +1,12 @@
#ifndef __SD_LOG_H__
#define __SD_LOG_H__
#pragma once
#include "mcuconf.h"

#include "ff.h"
#include <stdarg.h>
#include "mcuconf.h"

#define NUMBERLEN 4
#define NUMBERMAX 9999
#define NUMBERFMF "%s\\%s%.04d.LOG"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -63,6 +66,7 @@ typedef enum {
SDLOG_QUEUEFULL,
SDLOG_NOTHREAD,
SDLOG_INTERNAL_ERROR,
SDLOG_LOGNUM_ERROR
} SdioError;


Expand Down Expand Up @@ -131,7 +135,6 @@ SdioError sdLogFlushLog (const FileDes fileObject);
*/
SdioError sdLogCloseLog (const FileDes fileObject);


/**
* @brief close all opened logs then stop worker thread
* @param[in] flush : if true : flush all ram buffers before closing (take more time)
Expand Down Expand Up @@ -172,4 +175,4 @@ SdioError sdLogWriteByte (const FileDes fileObject, const uint8_t value);
}
#endif

#endif // __SD_LOG_H__