Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
sonar_i2c.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2023 OpenUAS <noreply@openuas.org>
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 *
21 */
22
23
28#include "generated/airframe.h"
30#include "modules/core/abi.h"
31#if defined(SITL) || (defined(SONAR_I2C_COMPENSATE_ROTATION) && (SONAR_I2C_COMPENSATE_ROTATION == 1))
32#include "state.h"
33#endif
34#if PERIODIC_TELEMETRY
36#include "pprzlink/messages.h"
37#endif
38
39#ifdef MODULE_SONAR_I2C_SYNC_SEND
41#endif
42
43// Check if an I2C device is selected
44#ifndef SONAR_I2C_DEV
45#error SONAR_I2C_DEV needs to be defined
46#endif
48
49// Default base address on 8 bits
50#ifndef SONAR_I2C_ADDR
51#define SONAR_I2C_ADDR 0xE0 // Equals 0x70 if notated as 7bit address
52#endif
53
54#define READ_MODE_SINGLE 0x51 // Deducted from sparse random information and thereafter testing
55
56// The minimum and maximum range what we want in our output e.g. sensor can do 7.2m but we only want to get dat less than 4m set MAX_RANGE to 4.0
57
59#ifndef SONAR_I2C_MIN_RANGE
60#define SONAR_I2C_MIN_RANGE 0.24f //Default for Sonar is 0.24m since many sonar sensors cannot measure a range closer than that reliably
61#endif
62
64#ifndef SONAR_I2C_MAX_RANGE
65#define SONAR_I2C_MAX_RANGE 4.0f //Reasonable default value in meters with still usable readings for it is maximum value for common sonar sensors
66#endif
67
69#ifndef SONAR_I2C_OFFSET
70#define SONAR_I2C_OFFSET 0.0f
71#endif
72
74#ifndef USE_SONAR_I2C_AGL
75#define USE_SONAR_I2C_AGL 0
76#endif
77
79#ifndef SONAR_I2C_USE_FILTER
80#define SONAR_I2C_USE_FILTER 1 // Enable filtering for sonar per default is best, sonars tend to give noisy spiking readings
81#endif
82
83#ifdef SONAR_I2C_USE_FILTER
86#ifndef SONAR_I2C_MEDIAN_SIZE
87#define SONAR_I2C_MEDIAN_SIZE 7 // Default median filter length of 7 is a good fit for most sonar sensors
88#endif
90#endif
91
92#ifndef SONAR_I2C_COMPENSATE_ROTATION
93#define SONAR_I2C_COMPENSATE_ROTATION 0
94#endif
95
96// Gain for sonar sensors to get from raw measuread value to meters
97#ifndef SONAR_I2C_SCALE
98#define SONAR_I2C_SCALE 0.000044f // Experimentally determined gain for famous GY-US42V2 sensor, since there is no datasheet afaik
99#endif
100
102
110
115{
118
119 //Init with defaults that do not cause harm
120 sonar_i2c.distance = (float)SONAR_I2C_MIN_RANGE; // Start with minimum range as default distance
123
125
126#ifdef SONAR_I2C_USE_FILTER
128#endif
129
130#if PERIODIC_TELEMETRY
132#endif
133
134}
135
143{
144 switch (sonar_i2c.trans.status) {
145 case I2CTransPending:
146 // wait and do nothing
147 break;
148 case I2CTransRunning:
149 // wait and do nothing
150 break;
151 case I2CTransSuccess:
152 case I2CTransFailed:
153 // set to done
155 break;
156 default:
157 // do nothing
158 break;
159 }
160#if MODULE_SONAR_I2C_SYNC_SEND
162#endif
163}
164
170{
171#ifndef SITL
172 switch (sonar_i2c.status) {
173
174 //Blocking I2C Transceive did not work for some of those I2C devices, therefore a state machine to handle the I2C transactions
180 }
181 }
182 break;
185 sonar_i2c.trans.buf[1] = 0;
186 sonar_i2c.trans.buf[2] = 0;
189 }
190 }
191 break;
194 // Time of when measurement was taken, not when ABI message was send, tiny delay can occur between those two events
196
197 // Convert the raw value to meters, optionally filter and apply the offset
199#ifdef SONAR_I2C_USE_FILTER
201#endif
202
203 if (sonar_i2c.distance <= (float)SONAR_I2C_MAX_RANGE) { //Discard non reliable readings that are out of range
205
206 // Compensate range measurement for body rotation
207 #if SONAR_I2C_COMPENSATE_ROTATION
208 float phi = stateGetNedToBodyEulers_f()->phi;
209 float theta = stateGetNedToBodyEulers_f()->theta;
210 float gain = cosf(phi) * cosf(theta);
212 // To much attitude difference from neutral, e.g. 50deg roll and 40deg pitch, or even negative upside-down for the sensor to be really useful in AGL perspective, set distance to NAN
213 if (gain < 0.4f) {sonar_i2c.distance = NAN; } //The magic 0.4f is for regular ultrasonic sensors about maximum range
214 #endif
215
216 if (!isnan(sonar_i2c.distance)) {
217 sonar_i2c.distance = sonar_i2c.distance - (float)SONAR_I2C_OFFSET; // Must be applied after rotation compensation
218 // Send AGL message
219 // Only send valid AGL distance values and positive distances, negative distances do not make sense in AGL perspective as it would mean the aircraft is underground
220 if (sonar_i2c.distance > 0.0f && sonar_i2c.update_agl) {
222 }
223 }
224 } else {
225 // Out of range, set to NAN
227 }
228
229 // Reset status as so to start reading new distance value again
231 break;
232 }
233 default:
234 break;
235 }
236
237#else // SITL
239#endif // SITL
240}
241
Main include for ABI (AirBorneInterface).
#define AGL_SONAR_I2C_ID
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition i2c.h:123
enum I2CTransactionStatus status
Transaction status.
Definition i2c.h:127
bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
Definition i2c.c:202
bool i2c_receive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint16_t len)
Submit a read only transaction.
Definition i2c.c:212
@ I2CTransRunning
transaction is currently ongoing
Definition i2c.h:57
@ I2CTransSuccess
transaction successfully finished by I2C driver
Definition i2c.h:58
@ I2CTransFailed
transaction failed
Definition i2c.h:59
@ I2CTransDone
transaction set to done by user level
Definition i2c.h:60
@ I2CTransPending
transaction is pending in queue
Definition i2c.h:56
float phi
in radians
float theta
in radians
static struct FloatEulers * stateGetNedToBodyEulers_f(void)
Get vehicle body attitude euler angles (float).
Definition state.h:1306
static struct EnuCoor_f * stateGetPositionEnu_f(void)
Get position in local ENU coordinates (float).
Definition state.h:848
uint16_t foo
Definition main_demo5.c:58
static float update_median_filter_f(struct MedianFilterFloat *filter, float new_data)
static void init_median_filter_f(struct MedianFilterFloat *filter, uint8_t size)
PRINT_CONFIG_VAR(ONELOOP_ANDI_FILT_CUTOFF)
float z
in meters
#define SONAR_I2C_OFFSET
Rangefinder distance offset value for what should be considered zero distance, e.g....
Definition sonar_i2c.c:70
#define SONAR_I2C_SCALE
Definition sonar_i2c.c:98
void sonar_i2c_event(void)
Rangefinder event function Basically just check the progress of the transation to prevent overruns du...
Definition sonar_i2c.c:142
#define SONAR_I2C_MAX_RANGE
The maximum chosen distance for the device to be give readings.
Definition sonar_i2c.c:65
#define USE_SONAR_I2C_AGL
Send AGL data over ABI.
Definition sonar_i2c.c:75
void sonar_i2c_report(void)
Option to send debug informative values over telemetry if you do not want sonar message in telemetry.
Definition sonar_i2c.c:246
#define SONAR_I2C_MEDIAN_SIZE
The amount of sensor samples to keep in the median filter buffer.
Definition sonar_i2c.c:87
static void sonar_i2c_send_sonar(struct transport_tx *trans, struct link_device *dev)
Send measured value and status information so it can be read back in e.g.
Definition sonar_i2c.c:106
void sonar_i2c_init(void)
Set the default values at initialization.
Definition sonar_i2c.c:114
struct SonarI2C sonar_i2c
Definition sonar_i2c.c:101
struct MedianFilterFloat sonar_i2c_filter
Definition sonar_i2c.c:89
#define SONAR_I2C_MIN_RANGE
The minimum chosen distance for the device to be give readings.
Definition sonar_i2c.c:60
void sonar_i2c_periodic(void)
Get the ranger current distance value.
Definition sonar_i2c.c:169
#define READ_MODE_SINGLE
Definition sonar_i2c.c:54
#define SONAR_I2C_ADDR
Definition sonar_i2c.c:51
Driver for an sonar rangfinder sensor when used via I2C bus.
uint16_t raw
raw measuread non scaled range value from sensor
Definition sonar_i2c.h:42
float distance
Distance scaled to [m].
Definition sonar_i2c.h:43
enum SonarI2CStatus status
Definition sonar_i2c.h:41
bool update_agl
Do or don't update AGL ABI message.
Definition sonar_i2c.h:44
@ SONAR_I2C_PARSE_DATA
Definition sonar_i2c.h:35
@ SONAR_I2C_READ_DATA
Definition sonar_i2c.h:34
@ SONAR_I2C_REQ_DATA
Definition sonar_i2c.h:33
uint8_t addr
Definition sonar_i2c.h:40
struct i2c_transaction trans
Definition sonar_i2c.h:39
API to get/set the generic vehicle states.
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
int16_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint16_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition telemetry.h:66
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.