Skip to content

Commit

Permalink
[sonar] protect sonar reading by mutex for bebop (#3408)
Browse files Browse the repository at this point in the history
Both ABI and telemetry messages are not thread-safe and should be
protected by mutex.
Simulation of sonar is handled by NPS.
  • Loading branch information
gautierhattenberger authored Nov 8, 2024
1 parent 6691770 commit 45abdef
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 38 deletions.
2 changes: 1 addition & 1 deletion conf/airframes/test_boards/disco.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</description>

<firmware name="fixedwing">
<configure name="USE_MAGNETOMETER" value="TRUE"/>
<configure name="USE_MAGNETOMETER" value="FALSE"/>

<target name="ap" board="disco">
<configure name="PERIODIC_FREQUENCY" value="120"/>
Expand Down
5 changes: 2 additions & 3 deletions conf/modules/sonar_bebop.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@
</header>

<init fun="sonar_bebop_init()"/>
<event fun="sonar_bebop_event()"/>

<makefile target="ap|sim">
<file name="sonar_bebop.c"/>
</makefile>
<makefile target="ap">
<file name="sonar_bebop.c"/>
<define name="USE_SPI0" value="1"/>
<define name="USE_ADC0" value="1"/>
</makefile>
Expand Down
71 changes: 37 additions & 34 deletions sw/airborne/modules/sonar/sonar_bebop.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@
struct MedianFilterFloat sonar_filt;
uint32_t sonar_bebop_spike_timer;

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

/** SONAR_BEBOP_INX_DIFF_TO_DIST conversion from index difference to distance based on time of flight
* ADC speed = 160kHz
* speed of sound = 340m/s */
Expand Down Expand Up @@ -112,13 +108,16 @@ void *sonar_bebop_read(void *data);
static float sonar_filter_narrow_obstacles(float distance_sonar);
#endif

static pthread_mutex_t sonar_mutex = PTHREAD_MUTEX_INITIALIZER;

void sonar_bebop_init(void)
{
mode = 0; // default mode is low altitude
pulse_transition_counter = 0;

sonar_bebop.meas = 0;
sonar_bebop.offset = 0;
sonar_bebop.available = false;

/* configure spi transaction */
sonar_bebop_spi_t.status = SPITransDone;
Expand All @@ -141,6 +140,36 @@ void sonar_bebop_init(void)
pthread_setname_np(tid, "sonar");
#endif
#endif
pthread_mutex_init(&sonar_mutex, NULL);
}

void sonar_bebop_event(void)
{
pthread_mutex_lock(&sonar_mutex);
if (sonar_bebop.available) {
#if SONAR_COMPENSATE_ROTATION
float phi = stateGetNedToBodyEulers_f()->phi;
float theta = stateGetNedToBodyEulers_f()->theta;
float gain = (float)fabs( (double) (cosf(phi) * cosf(theta)));
sonar_bebop.distance = sonar_bebop.distance * gain;
#endif

#if SONAR_BEBOP_FILTER_NARROW_OBSTACLES
sonar_bebop.distance = sonar_filter_narrow_obstacles(sonar_bebop.distance);
#endif

// Send ABI message
uint32_t now_ts = get_sys_time_usec();
AbiSendMsgAGL(AGL_SONAR_ADC_ID, now_ts, sonar_bebop.distance);

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

sonar_bebop.available = false;
}
pthread_mutex_unlock(&sonar_mutex);
}

uint16_t adc_buffer[SONAR_BEBOP_ADC_BUFFER_SIZE];
Expand All @@ -150,7 +179,6 @@ uint16_t adc_buffer[SONAR_BEBOP_ADC_BUFFER_SIZE];
void *sonar_bebop_read(void *data __attribute__((unused)))
{
while (true) {
#ifndef SITL
uint16_t i;

/* Start ADC and send sonar output */
Expand Down Expand Up @@ -193,6 +221,7 @@ void *sonar_bebop_read(void *data __attribute__((unused)))
uint16_t diff = stop_send - start_send;
if (diff && diff < SONAR_BEBOP_MAX_TRANS_TIME
&& peak_value > SONAR_BEBOP_MIN_PEAK_VAL) {
pthread_mutex_lock(&sonar_mutex);
sonar_bebop.meas = (uint16_t)(first_peak - (stop_send - diff / 2));
sonar_bebop.distance = update_median_filter_f(&sonar_filt, (float)sonar_bebop.meas * SONAR_BEBOP_INX_DIFF_TO_DIST);

Expand All @@ -210,36 +239,10 @@ void *sonar_bebop_read(void *data __attribute__((unused)))
} else {
pulse_transition_counter = 0;
}

#if SONAR_COMPENSATE_ROTATION
float phi = stateGetNedToBodyEulers_f()->phi;
float theta = stateGetNedToBodyEulers_f()->theta;
float gain = (float)fabs( (double) (cosf(phi) * cosf(theta)));
sonar_bebop.distance = sonar_bebop.distance * gain;
#endif

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

#if SONAR_BEBOP_FILTER_NARROW_OBSTACLES
sonar_bebop.distance = sonar_filter_narrow_obstacles(sonar_bebop.distance);
#endif

// Send ABI message
uint32_t now_ts = get_sys_time_usec();
AbiSendMsgAGL(AGL_SONAR_ADC_ID, now_ts, sonar_bebop.distance);

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

#ifndef SITL
sonar_bebop.available = true;
pthread_mutex_unlock(&sonar_mutex);
}
#endif

usleep(10000); //100Hz FIXME: use SYS_TIME_FREQUENCY and divisor
}
return NULL;
Expand Down
2 changes: 2 additions & 0 deletions sw/airborne/modules/sonar/sonar_bebop.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ struct SonarBebop {
uint16_t meas; ///< Raw ADC value
uint16_t offset; ///< Sonar offset in ADC units
float distance; ///< Distance measured in meters
bool available; ///< New data available
};

extern struct SonarBebop sonar_bebop;

extern void sonar_bebop_init(void);
extern void sonar_bebop_event(void);

#endif /* SONAR_BEBOP_H */
1 change: 1 addition & 0 deletions sw/simulator/nps/nps_fdm_fixedwing_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ void nps_fdm_run_step(bool launch, double *commands, int commands_nb __attribute
ned_of_ecef_vect_d(&fdm.ltpprz_ecef_vel, &ltpdef, &fdm.ecef_ecef_vel);
ned_of_ecef_vect_d(&fdm.ltpprz_ecef_accel, &ltpdef, &fdm.ecef_ecef_accel);
fdm.hmsl = -fdm.ltpprz_pos.z + NAV_ALT0 / 1000.;
fdm.agl = -fdm.ltpprz_pos.z; // flat Earth

/* Eulers */
fdm.ltp_to_body_eulers = sim_state.attitude;
Expand Down
9 changes: 9 additions & 0 deletions sw/simulator/nps/nps_sensor_sonar.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@
#define NPS_SONAR_OFFSET 0
#endif

#ifndef NPS_SONAR_MIN_DIST
#define NPS_SONAR_MIN_DIST 0.1f
#endif

#ifndef NPS_SONAR_MAX_DIST
#define NPS_SONAR_MAX_DIST 7.0f
#endif

void nps_sensor_sonar_init(struct NpsSensorSonar *sonar, double time)
{
Expand All @@ -71,6 +78,8 @@ void nps_sensor_sonar_run_step(struct NpsSensorSonar *sonar, double time)
sonar->value = fdm.agl + sonar->offset;
/* add noise with std dev meters */
sonar->value += get_gaussian_noise() * sonar->noise_std_dev;
/* bound value */
Bound(sonar->value, NPS_SONAR_MIN_DIST, NPS_SONAR_MAX_DIST);

sonar->next_update += NPS_SONAR_DT;
sonar->data_available = TRUE;
Expand Down

0 comments on commit 45abdef

Please sign in to comment.