diff --git a/conf/abi.xml b/conf/abi.xml
index d05b9cb76b..cd21c04257 100644
--- a/conf/abi.xml
+++ b/conf/abi.xml
@@ -59,10 +59,10 @@
- Flow in x direction from the camera (in subpixels)
- Flow in y direction from the camera (in subpixels)
- The derotated flow calculation in the x direction (in subpixels)
- The derotated flow calculation in the y direction (in subpixels)
+ Flow in x direction from the camera (in subpixels)
+ Flow in y direction from the camera (in subpixels)
+ The derotated flow calculation in the x direction (in subpixels)
+ The derotated flow calculation in the y direction (in subpixels)
Divergence as determined with the size method (in 1/seconds) with LK, and Divergence (1/seconds) itself with EF
diff --git a/conf/modules/optical_flow_mateksys_3901_l0x.xml b/conf/modules/optical_flow_mateksys_3901_l0x.xml
new file mode 100644
index 0000000000..5cb0921205
--- /dev/null
+++ b/conf/modules/optical_flow_mateksys_3901_l0x.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+ Transfers flow X and Y and range data of the Mateksys3901-l0X sensor to the autopilot
+ This by the default serial connection not by connecting the debug pins on ther sensor
+ The Data is in MSP compatible output.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sw/airborne/modules/optical_flow/mateksys_3901_l0x.c b/sw/airborne/modules/optical_flow/mateksys_3901_l0x.c
new file mode 100644
index 0000000000..1da70121e5
--- /dev/null
+++ b/sw/airborne/modules/optical_flow/mateksys_3901_l0x.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2020 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 modules/optical_flow/mateksys_3901_l0x.h
+ * @brief Driver for the mateksys_3901_l0x sensor via MSP protocol output
+ *
+ */
+
+#include "mateksys_3901_l0x.h"
+#include "mcu_periph/uart.h"
+#include "subsystems/abi.h"
+
+// State interface for rotation compensation
+#include "state.h"
+
+// Messages
+#include "pprzlink/messages.h"
+#include "subsystems/datalink/downlink.h"
+
+
+// Define configuration parameters
+#ifndef MATEKSYS_3901_L0X_MOTION_THRES
+#define MATEKSYS_3901_L0X_MOTION_THRES
+#endif
+
+#ifndef MATEKSYS_3901_L0X_DISTANCE_THRES
+#define MATEKSYS_3901_L0X_DISTANCE_THRES
+#endif
+
+#ifndef USE_MATEKSYS_3901_L0X_AGL
+#define USE_MATEKSYS_3901_L0X_AGL
+#endif
+
+#ifndef USE_MATEKSYS_3901_L0X_OPTICAL_FLOW
+#define USE_MATEKSYS_3901_L0X_OPTICAL_FLOW
+#endif
+
+#ifndef MATEKSYS_3901_L0X_COMPENSATE_ROTATION
+#define MATEKSYS_3901_L0X_COMPENSATE_ROTATION
+#endif
+
+struct Mateksys3901l0X mateksys3901l0x = {
+ .parse_status = MATEKSYS_3901_L0X_INITIALIZE
+};
+
+static void mateksys3901l0x_parse(uint8_t byte);
+
+#if PERIODIC_TELEMETRY
+#include "subsystems/datalink/telemetry.h"
+
+/**
+ * Downlink message flow and lidar (included velocity estimation, not yet tested)
+ */
+static void mateksys3901l0x_send_optical_flow(struct transport_tx *trans, struct link_device *dev)
+{
+ pprz_msg_send_OPTICAL_FLOW(trans, dev, AC_ID,
+ &mateksys3901l0x.time_sec,
+ &mateksys3901l0x.sensor_id,
+ &mateksys3901l0x.motionX_clean,
+ &mateksys3901l0x.motionY_clean,
+ &mateksys3901l0x.velocityX,
+ &mateksys3901l0x.velocityY,
+ &mateksys3901l0x.motion_quality,
+ &mateksys3901l0x.distance_clean,
+ &mateksys3901l0x.distancemm_quality);
+}
+
+#endif
+
+/**
+ * Initialization function
+ */
+void mateksys3901l0x_init(void)
+{
+ mateksys3901l0x.device = &((MATEKSYS_3901_L0X_PORT).device);
+ mateksys3901l0x.parse_crc = 0;
+ mateksys3901l0x.motion_quality = 0;
+ mateksys3901l0x.motionX = 0;
+ mateksys3901l0x.motionY = 0;
+ mateksys3901l0x.distancemm_quality = 0;
+ mateksys3901l0x.distancemm = 0;
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+
+#if PERIODIC_TELEMETRY
+ register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_OPTICAL_FLOW, mateksys3901l0x_send_optical_flow);
+#endif
+}
+
+/**
+ * Receive bytes from the UART port and parse them
+ */
+void mateksys3901l0x_event(void)
+{
+ while (mateksys3901l0x.parse_status != MATEKSYS_3901_L0X_INITIALIZE && mateksys3901l0x.device->char_available(mateksys3901l0x.device->periph)) {
+ mateksys3901l0x_parse(mateksys3901l0x.device->get_byte(mateksys3901l0x.device->periph));
+ }
+}
+
+/**
+ * Parse the sensor MSP output bytes 1 by 1
+ */
+static void mateksys3901l0x_parse(uint8_t byte)
+{
+
+ switch (mateksys3901l0x.parse_status) {
+ case MATEKSYS_3901_L0X_INITIALIZE:
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_HEAD: // MSP general header $
+ if (byte == 0x24) {
+ mateksys3901l0x.parse_status++;
+ }
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_HEAD2: // MSPv2 identifier X
+ if (byte == 0x58) {
+ mateksys3901l0x.parse_status++;
+ } else {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ }
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_DIRECTION: // direction <
+ if (byte == 0x3C) {
+ mateksys3901l0x.parse_status++;
+ } else {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ }
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_LENGTH: // set to 0
+ if (byte == 0x00) {
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ } else {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ }
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_FUNCTION_ID_B1: // 0x01 = rangefinder; 0x02 = opticalflow
+ if (byte == 0x01 || byte == 0x02) {
+ mateksys3901l0x.sensor_id = byte;
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ } else {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ }
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_FUNCTION_ID_B2: // sensor id pointer
+ if (byte == 0x1F) {
+ mateksys3901l0x.parse_status++;
+ mateksys3901l0x.parse_crc += byte;
+ } else {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ }
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_SIZE: // two fixed sizes are expected if message is
+ if (byte == 0x05 || byte == 0x09) {
+ mateksys3901l0x.parse_status++;
+ mateksys3901l0x.parse_crc += byte;
+ } else {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ }
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_POINTER: // should be zero, used to redirect to motion parsing or lidar parsing
+ if (mateksys3901l0x.sensor_id == 0x01) {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_DISTANCEQUALITY;
+ } else if (mateksys3901l0x.sensor_id == 0x02) {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_MOTIONQUALITY;
+ } else {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ }
+ break;
+
+ // rangefinder data parsing
+ case MATEKSYS_3901_L0X_PARSE_DISTANCEQUALITY:
+ mateksys3901l0x.distancemm_quality = byte;
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_DISTANCE_B1:
+ if (mateksys3901l0x.distancemm_quality <= MATEKSYS_3901_L0X_DISTANCE_THRES) {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ } else {
+ mateksys3901l0x.distancemm = byte;
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ }
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_DISTANCE_B2:
+ mateksys3901l0x.distancemm |= (byte << 8);
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_DISTANCE_B3:
+ mateksys3901l0x.distancemm |= (byte << 16);
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_DISTANCE_B4:
+ mateksys3901l0x.distancemm |= (byte << 24);
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_CHECKSUM;
+ break;
+
+ // optical flow data parsing
+ case MATEKSYS_3901_L0X_PARSE_MOTIONQUALITY:
+ mateksys3901l0x.motion_quality = byte;
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_MOTIONY_B1:
+ if (mateksys3901l0x.motion_quality <= MATEKSYS_3901_L0X_MOTION_THRES) {
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ } else {
+ mateksys3901l0x.motionY = byte;
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ }
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_MOTIONY_B2:
+ mateksys3901l0x.motionY |= (byte << 8);
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_MOTIONY_B3:
+ mateksys3901l0x.motionY |= (byte << 16);
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_MOTIONY_B4:
+ mateksys3901l0x.motionY |= (byte << 24);
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_MOTIONX_B1:
+ mateksys3901l0x.motionX = byte;
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_MOTIONX_B2:
+ mateksys3901l0x.motionX |= (byte << 8);
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_MOTIONX_B3:
+ mateksys3901l0x.motionX |= (byte << 16);
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_MOTIONX_B4:
+ mateksys3901l0x.motionX |= (byte << 24);
+ mateksys3901l0x.parse_crc += byte;
+ mateksys3901l0x.parse_status++;
+ break;
+
+ case MATEKSYS_3901_L0X_PARSE_CHECKSUM:
+
+ // When the distance and motion info are valid (max values based on sensor specifications)...
+ if (mateksys3901l0x.distancemm > 0 && mateksys3901l0x.distancemm <= 3000 && abs(mateksys3901l0x.motionX) <= 300 && abs(mateksys3901l0x.motionY) <= 300) {
+ // ... compensate AGL measurement for body rotation
+ if (MATEKSYS_3901_L0X_COMPENSATE_ROTATION) {
+ float phi = stateGetNedToBodyEulers_f()->phi;
+ float theta = stateGetNedToBodyEulers_f()->theta;
+ float gain = (float)fabs((double)(cosf(phi) * cosf(theta)));
+ mateksys3901l0x.distancemm = mateksys3901l0x.distancemm * gain;
+ }
+
+ // send messages with no error measurements
+ mateksys3901l0x.distance_clean = mateksys3901l0x.distancemm/1000.f;
+ mateksys3901l0x.motionX_clean = mateksys3901l0x.motionX;
+ mateksys3901l0x.motionY_clean = mateksys3901l0x.motionY;
+
+ // estimate velocity and send it to telemetry
+ mateksys3901l0x.velocityX = mateksys3901l0x.distance_clean * sin(RadOfDeg(mateksys3901l0x.motionX_clean));
+ mateksys3901l0x.velocityY = mateksys3901l0x.distance_clean * sin(RadOfDeg(mateksys3901l0x.motionY_clean));
+
+ // get ticks
+ uint32_t now_ts = get_sys_time_usec();
+ mateksys3901l0x.time_sec = now_ts*1e-6;
+
+ // send AGL (if requested)
+ if (USE_MATEKSYS_3901_L0X_AGL) {
+ AbiSendMsgAGL(AGL_LIDAR_MATEKSYS_3901_L0X_ID,
+ now_ts,
+ mateksys3901l0x.distance_clean);
+ }
+
+ // send optical flow (if requested)
+ if (USE_MATEKSYS_3901_L0X_OPTICAL_FLOW) {
+ AbiSendMsgOPTICAL_FLOW(FLOW_OPTICFLOW_MATEKSYS_3901_L0X_ID,
+ now_ts,
+ mateksys3901l0x.motionX_clean,
+ mateksys3901l0x.motionY_clean,
+ 0,
+ 0,
+ mateksys3901l0x.motion_quality,
+ 0.0);
+ }
+ }
+ // Start reading again
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ break;
+
+ default:
+ // Error, return to start
+ mateksys3901l0x.parse_status = MATEKSYS_3901_L0X_PARSE_HEAD;
+ break;
+
+ }
+}
diff --git a/sw/airborne/modules/optical_flow/mateksys_3901_l0x.h b/sw/airborne/modules/optical_flow/mateksys_3901_l0x.h
new file mode 100644
index 0000000000..c2ff0beaa6
--- /dev/null
+++ b/sw/airborne/modules/optical_flow/mateksys_3901_l0x.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2020 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 modules/optical_flow/mateksys_3901_l0x.h
+ * @brief Driver for the mateksys_3901_l0x sensor via MSPx protocol output
+ *
+ */
+
+/*
+Since the is no official MSP2 nor MSP1 message definition we choose for time being that
+the IDs to be compatible with INAV as see here
+https://github.com/iNavFlight/inav/blob/master/src/main/msp/msp_protocol_v2_sensor.h
+https://github.com/iNavFlight/inav/wiki/MSP-V2
+*/
+
+#ifndef MATEKSYS_3901_L0X_H
+#define MATEKSYS_3901_L0X_H
+
+#include "std.h"
+#include "stdbool.h"
+//#include "filters/median_filter.h" //Who knows we need it ;)
+
+#define MSP2_IS_SENSOR_MESSAGE(x) ((x) >= 0x1F00 && (x) <= 0x1FFF)
+
+#define MSP2_SENSOR_RANGEFINDER 0x1F01
+#define MSP2_SENSOR_OPTIC_FLOW 0x1F02
+
+enum Mateksys3901l0XParseStatus {
+ MATEKSYS_3901_L0X_INITIALIZE, // initialization
+ MATEKSYS_3901_L0X_PARSE_HEAD,
+ MATEKSYS_3901_L0X_PARSE_HEAD2,
+ MATEKSYS_3901_L0X_PARSE_DIRECTION,
+ MATEKSYS_3901_L0X_PARSE_LENGTH,
+ MATEKSYS_3901_L0X_PARSE_FUNCTION_ID_B1,
+ MATEKSYS_3901_L0X_PARSE_FUNCTION_ID_B2,
+ MATEKSYS_3901_L0X_PARSE_SIZE,
+ MATEKSYS_3901_L0X_PARSE_POINTER, // ??
+ MATEKSYS_3901_L0X_PARSE_DISTANCEQUALITY, // used if lidar message
+ MATEKSYS_3901_L0X_PARSE_DISTANCE_B1,
+ MATEKSYS_3901_L0X_PARSE_DISTANCE_B2,
+ MATEKSYS_3901_L0X_PARSE_DISTANCE_B3,
+ MATEKSYS_3901_L0X_PARSE_DISTANCE_B4,
+ MATEKSYS_3901_L0X_PARSE_MOTIONQUALITY, // used if flow message
+ MATEKSYS_3901_L0X_PARSE_MOTIONY_B1,
+ MATEKSYS_3901_L0X_PARSE_MOTIONY_B2,
+ MATEKSYS_3901_L0X_PARSE_MOTIONY_B3,
+ MATEKSYS_3901_L0X_PARSE_MOTIONY_B4,
+ MATEKSYS_3901_L0X_PARSE_MOTIONX_B1,
+ MATEKSYS_3901_L0X_PARSE_MOTIONX_B2,
+ MATEKSYS_3901_L0X_PARSE_MOTIONX_B3,
+ MATEKSYS_3901_L0X_PARSE_MOTIONX_B4,
+ MATEKSYS_3901_L0X_PARSE_CHECKSUM,
+};
+
+struct Mateksys3901l0X {
+ struct link_device *device;
+ enum Mateksys3901l0XParseStatus parse_status;
+ float time_sec;
+ uint8_t sensor_id;
+ uint8_t motion_quality;
+ int32_t motionX;
+ int32_t motionY;
+ int32_t motionX_clean;
+ int32_t motionY_clean;
+ uint8_t distancemm_quality;
+ int32_t distancemm;
+ float distance_clean;
+ float velocityX;
+ float velocityY;
+ uint8_t parse_crc;
+};
+
+extern struct Mateksys3901l0X mateksys3901l0x;
+
+extern void mateksys3901l0x_init(void);
+extern void mateksys3901l0x_event(void);
+extern void mateksys3901l0x_downlink(void);
+
+#endif /* MATEKSYS_3901_L0X_H */
+
diff --git a/sw/airborne/modules/optical_flow/px4flow.c b/sw/airborne/modules/optical_flow/px4flow.c
index 04d90ba5e3..d12dd9e209 100644
--- a/sw/airborne/modules/optical_flow/px4flow.c
+++ b/sw/airborne/modules/optical_flow/px4flow.c
@@ -162,15 +162,17 @@ void px4flow_init(void)
void px4flow_downlink(void)
{
static float timestamp = 0;
+ static float distance_quality = 0;
timestamp = ((float)optical_flow.time_usec) * 0.000001;
- DOWNLINK_SEND_PX4FLOW(DefaultChannel, DefaultDevice,
- ×tamp,
- &optical_flow.sensor_id,
- &optical_flow.flow_x,
- &optical_flow.flow_y,
- &optical_flow.flow_comp_m_x,
- &optical_flow.flow_comp_m_y,
- &optical_flow.quality,
- &optical_flow.ground_distance);
+ DOWNLINK_SEND_OPTICAL_FLOW(DefaultChannel, DefaultDevice,
+ ×tamp,
+ &optical_flow.sensor_id,
+ &optical_flow.flow_x,
+ &optical_flow.flow_y,
+ &optical_flow.flow_comp_m_x,
+ &optical_flow.flow_comp_m_y,
+ &optical_flow.quality,
+ &optical_flow.ground_distance,
+ &distance_quality);
}
diff --git a/sw/airborne/modules/optical_flow/px4flow.h b/sw/airborne/modules/optical_flow/px4flow.h
index 68504591df..8050d1b5cb 100644
--- a/sw/airborne/modules/optical_flow/px4flow.h
+++ b/sw/airborne/modules/optical_flow/px4flow.h
@@ -47,8 +47,8 @@ struct mavlink_optical_flow {
float flow_comp_m_x; ///< Flow in meters in x-sensor direction, angular-speed compensated [meters/sec]
float flow_comp_m_y; ///< Flow in meters in y-sensor direction, angular-speed compensated [meters/sec]
float ground_distance; ///< Ground distance in meters. Positive value: distance known. Negative value: Unknown distance
- int16_t flow_x; ///< Flow in pixels in x-sensor direction
- int16_t flow_y; ///< Flow in pixels in y-sensor direction
+ int32_t flow_x; ///< Flow in pixels in x-sensor direction
+ int32_t flow_y; ///< Flow in pixels in y-sensor direction
uint8_t sensor_id; ///< Sensor ID
uint8_t quality; ///< Optical flow quality / confidence. 0: bad, 255: maximum quality
};
diff --git a/sw/airborne/modules/optical_flow/px4flow_i2c.c b/sw/airborne/modules/optical_flow/px4flow_i2c.c
index 40c5820473..48ebf6f397 100644
--- a/sw/airborne/modules/optical_flow/px4flow_i2c.c
+++ b/sw/airborne/modules/optical_flow/px4flow_i2c.c
@@ -267,10 +267,11 @@ void px4flow_i2c_downlink(void)
uint8_t id = PX4FLOW_I2C_ID;
float timestamp = get_sys_time_float();
+ static float distance_quality = 0;
#if REQUEST_INT_FRAME
- int16_t flow_x = px4flow.i2c_int_frame.pixel_flow_x_integral;
- int16_t flow_y = px4flow.i2c_int_frame.pixel_flow_y_integral;
+ int32_t flow_x = px4flow.i2c_int_frame.pixel_flow_x_integral;
+ int32_t flow_y = px4flow.i2c_int_frame.pixel_flow_y_integral;
float flow_comp_m_x = 0.0;
float flow_comp_m_y = 0.0;
@@ -278,8 +279,8 @@ void px4flow_i2c_downlink(void)
uint8_t quality = px4flow.i2c_int_frame.qual;
float ground_distance = ((float)px4flow.i2c_int_frame.ground_distance) / 1000.0;
#else
- int16_t flow_x = px4flow.i2c_frame.pixel_flow_x_sum;
- int16_t flow_y = px4flow.i2c_frame.pixel_flow_y_sum;
+ int32_t flow_x = px4flow.i2c_frame.pixel_flow_x_sum;
+ int32_t flow_y = px4flow.i2c_frame.pixel_flow_y_sum;
float flow_comp_m_x = ((float)px4flow.i2c_frame.flow_comp_m_x) / 1000.0;
float flow_comp_m_y = ((float)px4flow.i2c_frame.flow_comp_m_y) / 1000.0;
@@ -288,13 +289,14 @@ void px4flow_i2c_downlink(void)
float ground_distance = ((float)px4flow.i2c_frame.ground_distance) / 1000.0;
#endif
- DOWNLINK_SEND_PX4FLOW(DefaultChannel, DefaultDevice,
- ×tamp,
- &id,
- &flow_x,
- &flow_y,
- &flow_comp_m_x,
- &flow_comp_m_y,
- &quality,
- &ground_distance);
+ DOWNLINK_SEND_OPTICAL_FLOW(DefaultChannel, DefaultDevice,
+ ×tamp,
+ &id,
+ &flow_x,
+ &flow_y,
+ &flow_comp_m_x,
+ &flow_comp_m_y,
+ &quality,
+ &ground_distance,
+ &distance_quality);
}
diff --git a/sw/airborne/subsystems/abi_sender_ids.h b/sw/airborne/subsystems/abi_sender_ids.h
index 4854ed38de..c3fc075be7 100644
--- a/sw/airborne/subsystems/abi_sender_ids.h
+++ b/sw/airborne/subsystems/abi_sender_ids.h
@@ -181,6 +181,10 @@
#define AGL_LIDAR_TFMINI_I2C_ID 14
#endif
+#ifndef AGL_LIDAR_MATEKSYS_3901_L0X_ID
+#define AGL_LIDAR_MATEKSYS_3901_L0X_ID 15
+#endif
+
/*
* IDs of magnetometer sensors (including IMUs with mag)
*/
@@ -367,6 +371,10 @@
#define FLOW_OPTICFLOW_PMW3901_ID 3
#endif
+#ifndef FLOW_OPTICFLOW_MATEKSYS_3901_L0X_ID
+#define FLOW_OPTICFLOW_MATEKSYS_3901_L0X_ID 4
+#endif
+
/*
* IDs of VELOCITY estimates (message 12)
*/
diff --git a/sw/ext/pprzlink b/sw/ext/pprzlink
index 46c4c210ac..da37238464 160000
--- a/sw/ext/pprzlink
+++ b/sw/ext/pprzlink
@@ -1 +1 @@
-Subproject commit 46c4c210ac5e3d1ee49d36a174a3555b29a37196
+Subproject commit da372384642233cf4e3e86aeebbabbb042991149