[module] add pwm based angle of attack sensor

- use pwm_meas module
- log on SD card if available
- shared message with aoa_adc
This commit is contained in:
Gautier Hattenberger
2015-09-29 14:57:38 +02:00
parent 99f62f36ce
commit 7c5c792a41
7 changed files with 246 additions and 6 deletions
+3 -3
View File
@@ -593,9 +593,9 @@
<field name="alt" type="float" unit="m"/>
</message>
<message name="AOA_ADC" id="69">
<field name="adcVal" type="uint16"/>
<field name="AOA" type="float" unit="rad"/>
<message name="AOA" id="69">
<field name="raw" type="uint32"/>
<field name="angle" type="float" unit="rad" alt_unit="deg"/>
</message>
<message name="XTEND_RSSI" id="70">
+39
View File
@@ -0,0 +1,39 @@
<!DOCTYPE module SYSTEM "module.dtd">
<module name="AOA_pwm" dir="sensors">
<doc>
<description> Angle of Attack sensor using PWM input</description>
<configure name="AOA_PWM_CHANNEL" value="PWM_INPUTX" description="Select PWM input channel for AOA sensor"/>
<define name="AOA_SENS" value="(2*3.14)/AOA_PWM_PERIOD" description="sensor sensitivity"/>
<define name="AOA_OFFSET" value="0." description="offset in radian that can be set from settings"/>
<define name="AOA_ANGLE_OFFSET" value="3.14" description="global offset in radian corresponding to the sensor mounting (default: 3.14)"/>
<define name="AOA_REVERSE" value="TRUE|FALSE" description="set to TRUE to reverse rotation direction"/>
<define name="AOA_PWM_PERIOD" value="4096" description="period in microsec (e.g. 4096 for 12 bits sensor)"/>
<define name="AOA_PWM_OFFSET" value="1" description="initial offset on the raw pwm signal if needed (default: 1usec)"/>
<define name="SEND_AOA" value="TRUE|FALSE" description="enable telemetry report (default: TRUE)"/>
<define name="LOG_AOA" value="TRUE|FALSE" description="enable logging on SD card (default: FALSE)"/>
</doc>
<settings>
<dl_settings>
<dl_settings NAME="AOA">
<dl_setting MAX="180" MIN="-180" STEP="0.1" VAR="aoa_pwm.offset" shortname="AOA_offset" module="modules/sensors/aoa_pwm" param="AOA_OFFSET" unit="rad" alt_unit="deg"/>
<dl_setting MAX="0.95" MIN="0" STEP="0.001" VAR="aoa_pwm.filter" shortname="AOA_filter" module="modules/sensors/aoa_pwm" param="AOA_FILTER"/>
</dl_settings>
</dl_settings>
</settings>
<depends>pwm_meas</depends>
<header>
<file name="aoa_pwm.h" />
</header>
<init fun="aoa_pwm_init()" />
<periodic fun="aoa_pwm_update()" freq="20" />
<makefile target="ap">
<file name="aoa_pwm.c" />
<define name="AOA_PWM_CHANNEL" value="$(AOA_PWM_CHANNEL)" cond="ifdef AOA_PWM_CHANNEL" />
<define name="PWM_INPUT_TICKS_PER_USEC" value="1" />
<define name="USE_$(AOA_PWM_CHANNEL)" value="PWM_PULSE_TYPE_ACTIVE_LOW" />
</makefile>
</module>
+2 -1
View File
@@ -125,7 +125,8 @@
<message name="IMU_ACCEL" period=".02"/>
<message name="IMU_GYRO" period=".02"/>
<message name="IMU_MAG" period=".02"/>
<message name="AIR_DATA" period="0.5"/>
<message name="AIR_DATA" period="0.05"/>
<message name="AOA" period="0.05"/>
<message name="RC" period="0.05"/>
<message name="COMMANDS" period="0.05"/>
<message name="ACTUATORS" period="0.05"/>
+1 -1
View File
@@ -87,6 +87,6 @@ void aoa_adc_update(void)
stateSetAngleOfAttack_f(aoa_adc.angle);
#endif
RunOnceEvery(30, DOWNLINK_SEND_AOA_ADC(DefaultChannel, DefaultDevice, &aoa_adc.raw, &aoa_adc.angle));
RunOnceEvery(30, DOWNLINK_SEND_AOA(DefaultChannel, DefaultDevice, &aoa_adc.raw, &aoa_adc.angle));
}
+1 -1
View File
@@ -38,7 +38,7 @@
*/
struct Aoa_Adc {
struct adc_buf buf;
uint16_t raw; ///< raw ADC value
uint32_t raw; ///< raw ADC value
float angle; ///< Angle of attack in radians
float offset; ///< Angle of attack offset in radians
float sens; ///< sensitiviy, i.e. scale to conver raw to angle
+147
View File
@@ -0,0 +1,147 @@
/*
* Copyright (C) 2015 Jean-François Erdelyi, Gautier Hattenberger
*
* 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/sensors/aoa_pwm.c"
* @author Jean-François Erdelyi
* @brief Angle of Attack sensor on PWM
*
* SENSOR, exemple : US DIGITAL MA3-P12-125-B
* @see http://www.usdigital.com/products/encoders/absolute/rotary/shaft/ma3
*/
#include "modules/sensors/aoa_pwm.h"
#include "mcu_periph/pwm_input.h"
#include "messages.h"
#include "subsystems/datalink/downlink.h"
#include "generated/airframe.h"
#if LOG_AOA
#include "sdLog.h"
#include "subsystems/chibios-libopencm3/chibios_sdlog.h"
bool_t log_started;
#endif
#ifndef AOA_PWM_CHANNEL
#error "AOA_PWM_CHANNEL needs to be defined to use AOA_pwm module"
#endif
/// Default to a 12 bit PWM sensor
#ifndef AOA_PWM_PERIOD
#define AOA_PWM_PERIOD 4096
#endif
/// Some sensor may need an initial PWM offset (1 usec in the case of an MA3 sensor)
#ifndef AOA_PWM_OFFSET
#define AOA_PWM_OFFSET 1
#endif
/// Default offset value (assuming 0 AOA is in the middle of the range)
#ifndef AOA_ANGLE_OFFSET
#define AOA_ANGLE_OFFSET M_PI
#endif
/// Default extra offset that can be ajusted from settings
#ifndef AOA_OFFSET
#define AOA_OFFSET 0.0f
#endif
/// Default filter value
#ifndef AOA_FILTER
#define AOA_FILTER 0.0f
#endif
/// Default sensitivity (2*pi on a PWM of period AOA_PWM_PERIOD)
#ifndef AOA_SENS
#define AOA_SENS ((2.0f*M_PI)/AOA_PWM_PERIOD)
#endif
// Set AOA_REVERSE to TRUE to change rotation direction
#if AOA_REVERSE
#define AOA_SIGN -1
#else
#define AOA_SIGN 1
#endif
// Enable telemetry report
#ifndef SEND_SYNC_AOA
#define SEND_SYNC_AOA TRUE
#endif
// Enable SD card logging
#ifndef LOG_AOA
#define LOG_AOA FALSE
#endif
struct Aoa_Pwm aoa_pwm;
#if PERIODIC_TELEMETRY
#include "subsystems/datalink/telemetry.h"
static void send_aoa(struct transport_tx *trans, struct link_device *dev)
{
pprz_msg_send_AOA(trans, dev, AC_ID, &aoa_pwm.raw, &aoa_pwm.angle);
}
#endif
void aoa_pwm_init(void)
{
aoa_pwm.offset = AOA_OFFSET;
aoa_pwm.filter = AOA_FILTER;
aoa_pwm.sens = AOA_SENS;
aoa_pwm.angle = 0.0f;
aoa_pwm.raw = 0.0f;
#if LOG_AOA
log_started = FALSE;
#endif
#if PERIODIC_TELEMETRY
register_periodic_telemetry(DefaultPeriodic, "AOA", send_aoa);
#endif
}
void aoa_pwm_update(void) {
static float prev_aoa = 0.0f;
// raw duty cycle in usec
uint32_t duty_raw = pwm_input_duty_tics[AOA_PWM_CHANNEL] / PWM_INPUT_TICKS_PER_USEC;
// remove some offset if needed
aoa_pwm.raw = duty_raw - AOA_PWM_OFFSET;
// FIXME for some reason, the last value of the MA3 encoder is not 4096 but 4097
// this case is not handled since we don't care about angles close to +- 180 deg
aoa_pwm.angle = AOA_SIGN * (((float)aoa_pwm.raw * aoa_pwm.sens) - aoa_pwm.offset - AOA_ANGLE_OFFSET);
// filter angle
aoa_pwm.angle = aoa_pwm.filter * prev_aoa + (1.0f - aoa_pwm.filter) * aoa_pwm.angle;
prev_aoa = aoa_pwm.angle;
#if USE_AOA
stateSetAngleOfAttack_f(aoa_adc.angle);
#endif
#if SEND_SYNC_AOA
RunOnceEvery(10, DOWNLINK_SEND_AOA(DefaultChannel, DefaultDevice, &aoa_pwm.raw, &aoa_pwm.angle));
#endif
#if LOG_AOA
if(pprzLogFile != -1) {
if (!log_started) {
sdLogWriteLog(pprzLogFile, "AOA_PWM: ANGLE(deg) RAW(int16)\n");
log_started = TRUE;
} else {
float angle = DegOfRad(aoa_pwm.angle);
sdLogWriteLog(pprzLogFile, "AOA_PWM: %.3f %d\n", angle, aoa_pwm.raw);
}
}
#endif
}
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2015 Jean-François Erdelyi, Gautier Hattenberger
*
* 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/sensors/aoa_ppm.h"
* @author Jean-François Erdelyi
* @brief Angle of Attack sensor on PWM
*
* SENSOR, example : US DIGITAL MA3-P12-125-B
*/
#ifndef AOA_PWM_H
#define AOA_PWM_H
#include "std.h"
struct Aoa_Pwm {
uint32_t raw; ///< raw PWM value
float angle; ///< Angle of attack in radians
float offset; ///< Angle of attack offset in radians
float sens; ///< sensitiviy, i.e. scale to conver raw to angle
/** Filtering value [0-1]
* 0: no filtering
* 1: output is a constant value
*/
float filter;
};
extern struct Aoa_Pwm aoa_pwm;
extern void aoa_pwm_init(void);
extern void aoa_pwm_update(void);
#endif /* AOA_PWM_H */