betaflight / betaflight

Open Source Flight Controller Firmware
GNU General Public License v3.0
8.35k stars 2.96k forks source link

TFMini LIDAR values are -1.0 all the time (3.5.7) #7862

Closed andrejpodzimek closed 5 years ago

andrejpodzimek commented 5 years ago

While using this LIDAR, the Sensors tab shows -1.0 for "Sonar" all the time, so it looks like it doesn't work. When looking at the LIDAR with my cell phone camera (which can see infrared and shows it as pink/purple), the LIDAR does emit infrared light. The LIDAR is on UART 4. The FC is an ANYFCF7, the one with 10 big PWM outputs.

I'm using Betaflight 3.5.7, modified to support my octocopter with DShot.1 (I don't think it's relevant, but I'll include all the config and code diff below.)

image

image

# diff all

# version
# Betaflight / ANYFCF7 (ANY7) 3.5.7 Mar 24 2019 / 10:09:51 (b2dc41a2b) MSP API: 1.40

board_name ANYFCF7
manufacturer_id 
mcu_id 003900263036510335383333
signature 

# reset configuration to default settings
defaults nosave

# name
name Kraken

# resources
resource MOTOR 1 A03
resource MOTOR 2 C09
resource MOTOR 3 B04
resource MOTOR 4 B05
resource MOTOR 5 B08
resource MOTOR 6 A02
resource MOTOR 7 A00
resource MOTOR 8 B03
resource PPM 1 NONE
resource PWM 1 NONE
resource PWM 2 NONE
resource SERIAL_TX 1 NONE
resource SERIAL_RX 1 NONE

# mixer
mixer OCTOFLATX

# servo

# servo mix

# feature
feature GPS
feature RANGEFINDER
feature TELEMETRY
feature LED_STRIP
feature ESC_SENSOR

# beeper

# beacon
beacon RX_SET

# map

# serial
serial 1 1 115200 57600 0 115200
serial 2 64 115200 57600 0 115200
serial 3 32768 115200 57600 0 115200
serial 4 2048 115200 57600 0 115200
serial 5 1024 115200 57600 0 115200
serial 6 2 115200 57600 0 115200
serial 7 16384 115200 57600 0 115200

# led
led 0 3,14:SD:CIW:10
led 1 4,14:SD:CIW:10
led 2 5,15:SD:CIW:10
led 3 6,15:SD:CIW:10
led 4 1,10:WD:CIW:2
led 5 1,11:WD:CIW:2
led 6 2,12:WD:CIW:2
led 7 2,13:WD:CIW:2
led 8 2,5:WD:CIW:2
led 9 2,6:WD:CIW:2
led 10 1,7:WD:CIW:2
led 11 1,8:WD:CIW:2
led 12 6,3:ND:CIW:4
led 13 5,3:ND:CIW:4
led 14 4,4:ND:CIW:4
led 15 3,4:ND:CIW:4
led 16 11,4:ND:CIW:4
led 17 10,4:ND:CIW:4
led 18 9,3:ND:CIW:4
led 19 8,3:ND:CIW:4
led 20 13,8:ED:CIW:6
led 21 13,7:ED:CIW:6
led 22 12,6:ED:CIW:6
led 23 12,5:ED:CIW:6
led 24 12,13:ED:CIW:6
led 25 12,12:ED:CIW:6
led 26 13,11:ED:CIW:6
led 27 13,10:ED:CIW:6
led 28 8,15:SD:CIW:10
led 29 9,15:SD:CIW:10
led 30 10,14:SD:CIW:10
led 31 11,14:SD:CIW:10

# color

# mode_color

# aux
aux 0 0 0 1700 2100 0 0
aux 1 1 1 900 1625 0 0
aux 2 2 1 1625 1875 0 0
aux 3 5 6 1700 2100 0 0
aux 4 3 1 900 1375 0 0
aux 5 11 1 900 1125 0 0
aux 6 13 3 1300 2100 0 0
aux 7 28 4 1700 2100 0 0
aux 8 33 5 1700 2100 0 0

# adjrange
adjrange 0 0 2 900 2100 12 2 0 0

# rxrange

# vtx

# rxfail
rxfail 5 s 1000
rxfail 6 s 1000
rxfail 7 s 2000
rxfail 9 s 2000

# master
set acc_calibration = -14,-71,-6
set align_mag = CW180
set mag_declination = 2180
set baro_i2c_device = 4
set max_check = 1950
set serialrx_provider = FPORT
set serialrx_inverted = ON
set serialrx_halfduplex = ON
set adc_device = 0
set blackbox_p_ratio = 0
set blackbox_device = NONE
set min_throttle = 1000
set dshot_idle_value = 300
set use_unsynced_pwm = ON
set motor_pwm_protocol = DSHOT600
set motor_pwm_rate = 16000
set current_meter = ADC
set battery_meter = ESC
set ibata_scale = 800
set gps_provider = UBLOX
set gps_sbas_mode = EGNOS
set gps_auto_baud = ON
set pid_process_denom = 1
set frsky_unit = METRIC
set vtx_channel = 5
set vtx_freq = 5820
set vcd_video_system = PAL
set rangefinder_hardware = TFMINI
set rcdevice_init_dev_attempts = 10

# profile
profile 0

set dterm_notch_hz = 260
set vbat_pid_gain = ON
set anti_gravity_gain = 3000
set smart_feedforward = ON
set iterm_relax = RPY
set yaw_lowpass_hz = 100
set d_level = 80

# profile
profile 1

set dterm_notch_hz = 260
set vbat_pid_gain = ON
set anti_gravity_gain = 3000
set smart_feedforward = ON
set iterm_relax = RPY
set yaw_lowpass_hz = 100
set d_level = 80

# profile
profile 2

set dterm_notch_hz = 260
set vbat_pid_gain = ON
set anti_gravity_gain = 3000
set smart_feedforward = ON
set iterm_relax = RPY
set yaw_lowpass_hz = 100

# restore original profile selection
profile 0

# rateprofile
rateprofile 0

# rateprofile
rateprofile 1

set roll_srate = 80
set pitch_srate = 80
set yaw_srate = 80

# rateprofile
rateprofile 2

set roll_srate = 85
set pitch_srate = 85
set yaw_srate = 80

# rateprofile
rateprofile 3

# rateprofile
rateprofile 4

# rateprofile
rateprofile 5

# restore original rateprofile selection
rateprofile 0

# save configuration
save

Here's a status:

System Uptime: 660 seconds
Current Time: 2003-07-06T05:02:50.153+00:00
Voltage: 246 * 0.1V (6S battery - OK)
CPU Clock=216MHz, Vref=3.29V, Core temp=77degC, GYRO=MPU6000, ACC=MPU6000, BARO=MS5611, MAG=HMC5883, RANGEFINDER=TFMINI
SD card: Startup failed
Stack size: 2048, Stack address: 0x20010000
I2C Errors: 1, config size: 2592, max available config: 32768
CPU:5%, cycle time: 125, GYRO rate: 8000, RX rate: 111, System rate: 9
Arming disable flags: CLI MSP

Here's my code diff [most likely irrelevant]:

diff --git a/src/main/target/ANYFCF7/target.c b/src/main/target/ANYFCF7/target.c
index 17dab5159..a0a9722ab 100644
--- a/src/main/target/ANYFCF7/target.c
+++ b/src/main/target/ANYFCF7/target.c
@@ -30,10 +30,8 @@
 const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = {
     DEF_TIM(TIM12, CH1, PB14, TIM_USE_PWM | TIM_USE_PPM,   0, 0 ), // S1_IN
     DEF_TIM(TIM12, CH2, PB15, TIM_USE_PWM,                 0, 0 ), // S2_IN
-    DEF_TIM(TIM8,  CH1, PC6,  TIM_USE_PWM,                 0, 0 ), // S3_IN DMA2_ST2 DMA2_ST2
-    DEF_TIM(TIM8,  CH2, PC7,  TIM_USE_PWM,                 0, 0 ), // S4_IN DMA2_ST3 DMA2_ST2
-    DEF_TIM(TIM8,  CH3, PC8,  TIM_USE_PWM,                 0, 0 ), // S5_IN DMA2_ST4 DMA2_ST2
-    DEF_TIM(TIM8,  CH4, PC9,  TIM_USE_PWM,                 0, 0 ), // S6_IN DMA2_ST7
+    DEF_TIM(TIM1,  CH3, PA10, TIM_USE_LED,                 0, 0 ),
+    DEF_TIM(TIM8,  CH4, PC9,  TIM_USE_MOTOR,               0, 0 ), // S6_IN DMA2_ST7

     DEF_TIM(TIM4,  CH3, PB8,  TIM_USE_MOTOR,               0, 0 ), // S10_OUT 1 DMA1_ST7
     DEF_TIM(TIM5,  CH3, PA2,  TIM_USE_MOTOR,               0, 0 ), // S6_OUT  2 DMA1_ST0
@@ -43,6 +41,6 @@ const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = {
     DEF_TIM(TIM5,  CH1, PA0,  TIM_USE_MOTOR,               0, 0 ), // S7_OUT DMA1_ST2
     DEF_TIM(TIM4,  CH4, PB9,  TIM_USE_MOTOR,               0, 0 ), // S5_OUT
     DEF_TIM(TIM9,  CH2, PE6,  TIM_USE_MOTOR,               0, 0 ), // S3_OUT
-    DEF_TIM(TIM2,  CH2, PB3,  TIM_USE_MOTOR | TIM_USE_LED, 0, 0 ), // S8_OUT DMA1_ST6
+    DEF_TIM(TIM2,  CH2, PB3,  TIM_USE_MOTOR,               0, 0 ), // S8_OUT DMA1_ST6
     DEF_TIM(TIM3,  CH1, PB4,  TIM_USE_MOTOR,               0, 0 ), // S9_OUT DMA1_ST4
 };
diff --git a/src/main/target/ANYFCF7/target.h b/src/main/target/ANYFCF7/target.h
index 6899cba18..c42b3c596 100644
--- a/src/main/target/ANYFCF7/target.h
+++ b/src/main/target/ANYFCF7/target.h
@@ -55,12 +55,15 @@
 //#define MAG_HMC5883_ALIGN CW270_DEG_FLIP
 //#define MAG_HMC5883_ALIGN CW90_DEG

+#define USE_RANGEFINDER
+#define USE_RANGEFINDER_TF
+
 #define USE_BARO
 #define USE_BARO_MS5611
 #define USE_BARO_BMP280
 #define BARO_I2C_INSTANCE           (I2CDEV_2)

-#define USABLE_TIMER_CHANNEL_COUNT 16
+#define USABLE_TIMER_CHANNEL_COUNT 14

 #define USE_VCP
 #define USE_USB_DETECT
@@ -167,4 +170,4 @@
 #define TARGET_IO_PORTD 0xffff
 #define TARGET_IO_PORTE 0xffff

-#define USED_TIMERS  ( TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(12) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11))
+#define USED_TIMERS  ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(12) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11))

Resources, just for completeness:

Currently active DMA:
--------------------
DMA1 Stream 0: MOTOR 6
DMA1 Stream 1: MOTOR 1
DMA1 Stream 2: MOTOR 7
DMA1 Stream 3: FREE
DMA1 Stream 4: MOTOR 3
DMA1 Stream 5: MOTOR 4
DMA1 Stream 6: MOTOR 8
DMA1 Stream 7: MOTOR 5
DMA2 Stream 0: FREE
DMA2 Stream 1: FREE
DMA2 Stream 2: FREE
DMA2 Stream 3: FREE
DMA2 Stream 4: ADC
DMA2 Stream 5: FREE
DMA2 Stream 6: LED_STRIP
DMA2 Stream 7: MOTOR 2
Currently active IO resource assignments:
(reboot to update)
--------------------
A00: MOTOR 7
A01: FREE
A02: MOTOR 6
A03: MOTOR 1
A04: MPU_CS
A05: SPI_SCK 1
A06: SPI_MISO 1
A07: SPI_MOSI 1
A08: USB_DETECT
A09: FREE
A10: LED_STRIP
A11: USB
A12: USB
A13: FREE
A14: FREE
A15: FREE
B00: FREE
B01: FREE
B02: BEEPER
B03: MOTOR 8
B04: MOTOR 3
B05: MOTOR 4
B06: LED 2
B07: LED 1
B08: MOTOR 5
B09: FREE
B10: I2C_SCL 2
B11: I2C_SDA 2
B12: FREE
B13: FREE
B14: FREE
B15: FREE
C00: FREE
C01: ADC_CURR
C02: FREE
C03: FREE
C04: MPU_EXTI
C05: FREE
C06: FREE
C07: SERIAL_RX 6
C08: FREE
C09: MOTOR 2
C10: SERIAL_TX 4
C11: SERIAL_RX 4
C12: SERIAL_TX 5
C13: FREE
C14: FREE
C15: FREE
D00: FREE
D01: FREE
D02: SPI_PREINIT_IPU 2
D03: FREE
D04: FREE
D05: SERIAL_TX 2
D06: SERIAL_RX 2
D07: FREE
D08: SERIAL_TX 3
D09: FREE
D10: FREE
D11: FREE
D12: I2C_SCL 4
D13: I2C_SDA 4
D14: FREE
D15: FREE
E00: SERIAL_RX 8
E01: SERIAL_TX 8
E02: FREE
E03: FREE
E04: FREE
E05: FREE
E06: FREE
E07: SERIAL_RX 7
E08: SERIAL_TX 7
E09: FREE
E10: FREE
E11: SPI_PREINIT_IPU 1
E12: SPI_SCK 4
E13: SPI_MISO 4
E14: SPI_MOSI 4
E15: FREE

1 The table shown here won't give you a DShot octocopter; the default configuration can use only 6 motors and the table extends this to 7 motors only (due to a conflict on DMA1_ST4). You need a configuration similar to the one above to get a DShot octocopter.

andrejpodzimek commented 5 years ago

Forgot to mention: This machine has had >3 3.5.x versions on it and the problem was the same each time. So it's not specific to 3.5.7.

etracer65 commented 5 years ago

Try testing by logging with set debug_mode = LIDAR_TF. Then debug items will be:

DEBUG_SET(DEBUG_LIDAR_TF, 0, distance);
DEBUG_SET(DEBUG_LIDAR_TF, 1, strength);
DEBUG_SET(DEBUG_LIDAR_TF, 2, tfFrame[4]);
DEBUG_SET(DEBUG_LIDAR_TF, 3, tfFrame[5]);

If this isn't showing anything then communication with the sensor isn't working.

andrejpodzimek commented 5 years ago

@etracer65 Thanks for the hint. Because I don't have BlackBox set up (and have never used it), I found it easier to parse the TFMini protocol [page 7]. I'm attaching my implementation. I think it shows more data than the debug output would. (The disadvantage is that it runs on serialpassthrough, not during a flight.)

Long story short: I'm seeing lots of invalid packets from TFMini. :confused: Packets that are valid show a height that makes perfect sense.

These are the first 10000 lines of my LIDAR reader's output: lidar_reader_output.txt

The LIDAR reader I've used is below.

// TFMini LIDAR protocol reader
// https://cdn.sparkfun.com/assets/5/e/4/7/b/benewake-tfmini-datasheet.pdf
//
// To build this tool:
// clang -Wall -Wextra -march=native -O3 -std=c11 lidar_reader.c -o lidar_reader
// You may need -lrt when building in an old environment.
//
// To set things up in the Betaflight CLI (LIDAR on UART4):
// serialpassthrough 3 115200
//
// After exiting the CLI, run the tool (e.g. with your FC on /dev/ttyACM0):
// ./lidar_reader /dev/ttyACM0

#define _POSIX_C_SOURCE 200809L
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>

#define FAILURE (-1)
#define CHECK(call) \
    ({                                                                         \
        ssize_t retval = (call);                                               \
        if (retval == FAILURE) {                                               \
            printf(                                                            \
                "LIDAR Reader: in %s on line %" PRIu32 " : %s : %s.\n",        \
                __FILE__, __LINE__, #call, strerror(errno));                   \
            exit(EXIT_FAILURE);                                                \
        }                                                                      \
        retval;                                                                \
    })
#define CHECK_EOF(call)                                                        \
    ({                                                                         \
        ssize_t retval = (call);                                               \
        if ((retval) == 0) {                                                   \
            printf(                                                            \
                "LIDAR Reader: in %s on line %" PRIu32 " : Unexpected EOF.\n", \
                __FILE__, __LINE__);                                           \
            exit(EXIT_FAILURE);                                                \
        }                                                                      \
        retval;                                                                \
    })

static const size_t BYTE_HEADER_0 = 0;
static const size_t BYTE_HEADER_1 = 1;
static const size_t BYTE_DIST_LOW = 2;
static const size_t BYTE_DIST_HIGH = 3;
static const size_t BYTE_STRENGTH_LOW = 4;
static const size_t BYTE_STRENGTH_HIGH = 5;
static const size_t BYTE_RESERVED = 6;
static const size_t BYTE_RAW_QUAL = 7;
static const size_t BYTE_PARITY = 8;
static const size_t PARITY_MASK = 0xff;
static const size_t HEADER_SIZE = 2;
static const size_t PACKET_SIZE = 9;
static const uint8_t PACKET_HEADER = 0x59;

static void print_packet(uint8_t (*buffer)[PACKET_SIZE]) {
    static uint64_t packet_count = 0;
    struct timespec ts;
    CHECK(clock_gettime(CLOCK_REALTIME, &ts));
    CHECK(printf("%" PRIuMAX ".%09" PRIdMAX ": packet %" PRIu64 ": ",
                 ts.tv_sec, ts.tv_nsec, packet_count++));
    uint16_t checksum = 0;
    const uint8_t *const data_end = *buffer + BYTE_PARITY;
    for (uint8_t* byte = *buffer; byte < data_end; ++byte) {
        checksum += *byte;
    }
    const uint8_t expected_parity = checksum & PARITY_MASK;
    if ((*buffer)[BYTE_PARITY] == expected_parity) {
        CHECK(printf("Parity OK! (%" PRIu8 "): ", expected_parity));
    } else {
        CHECK(printf("Wrong parity! (expected %" PRIu8 ", but was %" PRIu8 "): ",
                     expected_parity, (*buffer)[BYTE_PARITY]));
    }
    uint16_t distance = (*buffer)[BYTE_DIST_HIGH];
    distance <<= 8;
    distance += (*buffer)[BYTE_DIST_LOW];
    uint16_t strength = (*buffer)[BYTE_STRENGTH_HIGH];
    strength <<= 8;
    strength += (*buffer)[BYTE_STRENGTH_LOW];
    CHECK(printf("distance %" PRIu16 " cm, strength %" PRIu16 ", "
                 "quality %" PRIu8 ", reserved %" PRIu8 "\n",
                 distance, strength,
                 (*buffer)[BYTE_RESERVED], (*buffer)[BYTE_RAW_QUAL]));
}

int main(const int argc, const char* const* const argv) {
    if (argc != 2) {
        if (argc < 1) CHECK(printf("Wrong invocation!\n"));
        else CHECK(printf("Usage: %s <input tty>\n", argv[0]));
        return 1;
    }
    const int tty = CHECK(open(argv[1], O_RDONLY));
    uint8_t buffer[PACKET_SIZE];
    for (;;) {
        // Packet header alignment "state machine".
        size_t alignment_read = 0;
        ssize_t bytes;
        for (;;) {
            bytes = CHECK_EOF(CHECK(read(tty, &buffer[BYTE_HEADER_0], 1)));
            alignment_read += bytes;
            if (buffer[BYTE_HEADER_0] == PACKET_HEADER) {
                bytes = CHECK_EOF(CHECK(read(tty, &buffer[BYTE_HEADER_1], 1)));
                alignment_read += bytes;
                if (buffer[BYTE_HEADER_1] == PACKET_HEADER) {
                    break;
                }
            }
        }
        // Check how many bytes it took to find the packet header.
        if (alignment_read != HEADER_SIZE) {
            CHECK(printf("Read %" PRIuMAX " B before getting packet header!\n",
                         alignment_read));
        }
        // Reading the rest of the packet.
        size_t left = PACKET_SIZE - HEADER_SIZE;
        do {
            bytes = CHECK_EOF(CHECK(read(tty, &buffer[HEADER_SIZE], left)));
            left -= bytes;
        } while (left > 0);    
        print_packet(&buffer);
    }
}

A noteworthy thing is this other documentation that mentions [page 5] two different data formats (standard format implemented above and a string-based Pixhawk format) with commands that switch between them. But a format mismatch is likely not the reason for broken packets shown in the output, because there's nothing that could be switching the TFMini between the two modes so many times — my reader doesn't write into the serialpassthrough port at all.

Should I perhaps order and try another TFMini, to rule out the possibility of this one being faulty? (But it's still more likely that there's bug in my reader. :grin:)

etracer65 commented 5 years ago

Regarding not getting any readings: the problem is that rangefinder support has been removed since 3.4. The sensor driver is still there but the sensor is never read. Even if it was read there's nothing Betaflight could do with the data except possibly supply altitude numbers since altitude hold, etc. have also long been removed. For this reason rangefinder was disabled.

andrejpodzimek commented 5 years ago

@etracer65 I did not expect anything more than having the data in telemetry and OSD.

IIRC, the Betaflight configurator did not have a “Sonar” checkbox in the Sensors tab until recently. (Or maybe I just never noticed it…?) Now that the checkbox is there, it was the first time I looked at the data. Before that I assumed that lidar data was either reconciled with baro data or just unused. The “Sonar” checkbox made me somewhat hopeful that at least the data would be there.

The invalid packets from the TFMini look concerning to me. This looks like it wouldn’t work even if Betaflight did read the sensor. But if the -1 is caused by the sensor being ignored (rather than disabled after an invalid packet), then this is probably not worth further debugging.

mikeller commented 5 years ago

@andrejpodzimek:

IIRC, the Betaflight configurator did not have a “Sonar” checkbox in the Sensors tab until recently. (Or maybe I just never noticed it…?)

I think you never noticed it - there has not been much ongoing development for sonar / LIDAR in a while.

andrejpodzimek commented 5 years ago

I see. Perhaps I had had the LIDAR misconfigured to the point that the checkbox didn't appear.

As for the -1, is there still a way to get the data from the driver (something I can hack in reasonable time) or is this functionality too far gone?

(Now that I've seen all the invalid packets from the TFMini, I'm also curious whether this is a faulty TFMini (and if not, then what those "other" packets mean).)

Maybe I should try iNav in this case… But I'm not sure it would support an octocopter. (It took quite a few hacks and re-wiring to sort out the DShot / DMA / timer conflicts.)

mikeller commented 5 years ago

@andrejpodzimek: I think the functionality will need a thorough check up to find and fix bugs that have crept in, and then it might make sense to wire it up to an altitude display (or a 'close to ground' warning or similar) in the OSD. It will be some work, for not so much practical gain, so not sure if there is a developer with time on his hands and the inclination to spend it on fixing this.

Re iNav, that might be a good option. The Dshot / DMA / timer issue will most likely be less of a problem there, as it seems to be geared towards using PWM as the motor protocol, which does not need DMA for motor output.

andrejpodzimek commented 5 years ago

Digging into where the -1 comes from: This can happen when the distance is out of range (TF_MINI_RANGE_{MIN,MAX}), but that's not the case (based on what I see on serialpassthrough). So at the moment my gues is that it's this initial RANGEFINDER_OUT_OF_RANGE value, because rangefinderProcess() doesn't seem to be called. The Betaflight scheduler doesn't call it (and calls only rangefinderUpdate()), whereas iNav does call it. Betaflight also does't have calculateCosTiltAngle() to get the argument for rangefinderProcess().

…it might make sense to wire it up to an altitude display…

Apart from the altitude display, I was also thinking, given the impressive precision of LIDAR, that it could calibrate the baro data interpretation, to improve baro readings once the drone climbs above the LIDAR range. (One would have to be careful with cosTiltAngle, of course.)

…so not sure if there is a developer with time on his hands and the inclination to spend it on fixing this.

At the moment I do have a bit of spare time. If altitude-related functionality is merely "removed until rewritten and fixed" (rather than "removed forever"), I'd try and look into it. But I don't want to reintroduce stuff that Betaflight wants to get rid of; such effort would be bound to fail.

Re iNav, that might be a good option. The Dshot / DMA / timer issue will most likely be less of a problem there, as it seems to be geared towards using PWM as the motor protocol, which does not need DMA for motor output.

iNav has DShot, albeit with a scary warning. As for analog protocols … I like BLHeli_32 telemetry. From the BLHeli_32 side, telemetry could work with analog protocols — there's an auto telemetry option since version 32.51. But I think it wouldn't work with the usual "all ESCs on one RX" wiring; all ESCs would send telemetry all the time and clash. So telemetry depends on DShot.

Looking at the LIDAR drivers, I see that Betaflight drops invalid packets and so does iNav. So these may not be uncommon.

mikeller commented 5 years ago

@andrejpodzimek: Sonar / LIDAR support was 'moved out of the way' when GPS rescue was introduced, to allow this to happen in a minimal, but workable form, without having to worry about interaction with other systems. It was never the idea to permanently remove this, it is just a case of finding somebody willing to work on it, as there is not much that 'altitude above ground' information can be used for in Betaflight. So you are very welcome to do work on fixing this up and making it work again!

Not sure if 'altitude above ground' could be used for altitude calibration - this will only work if the ground is flat (which we don't know), or the craft is not moving (which would require GPS information to be tied in as well). But even 'only' 'altitude above ground' information can be quite valuable, as this is what pilots really care about (and not absolute altitude) when they are trying to land smoothly.

ESC telemetry is not restricted to digital protocols - in fact, the 'separate wire' ESC telemetry protocol that is used by Dshot was defined by KISS (thanks @ronlix for the original design for this!) to work with OneShot42 before it was 'adopted' by Dshot when Dshot was defined. It works well there, but it has the limitation that OneShot42 is the fastest protocol it can be used with, as a fixed length pulse that is longer than the longest expected OneShot42 pulse is used to trigger telemetry transmission for an individual ESC. This was never adopted by Betaflight, since the maximum 4kHz PID loop time possible with OneShot42 was considered to be slow when ESC telemetry support was added. But with iNav being much less focused on fast loop times, I think 'analog ESC telemetry' might be a valuable addition there - knowing things like ESC temperatures will be a welcome addition for long range flyers.

stale[bot] commented 5 years ago

This issue / pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs within a week.

andrejpodzimek commented 5 years ago

I'm finishing my second LIDAR build (a tricopter) slowly, but surely. (And poking this just to prevent stale bot from closing it.)

stale[bot] commented 5 years ago

This issue / pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs within a week.

stale[bot] commented 5 years ago

Automatically closing as inactive.

HenryHuYu commented 2 weeks ago

Digging into where the -1 comes from: This can happen when the distance is out of range (TF_MINI_RANGE_{MIN,MAX}), but that's not the case (based on what I see on serialpassthrough). So at the moment my gues is that it's this initial RANGEFINDER_OUT_OF_RANGE value, because rangefinderProcess() doesn't seem to be called. The Betaflight scheduler doesn't call it (and calls only rangefinderUpdate()), whereas iNav does call it. Betaflight also does't have calculateCosTiltAngle() to get the argument for rangefinderProcess().

…it might make sense to wire it up to an altitude display…

Apart from the altitude display, I was also thinking, given the impressive precision of LIDAR, that it could calibrate the baro data interpretation, to improve baro readings once the drone climbs above the LIDAR range. (One would have to be careful with cosTiltAngle, of course.)

…so not sure if there is a developer with time on his hands and the inclination to spend it on fixing this.

At the moment I do have a bit of spare time. If altitude-related functionality is merely "removed until rewritten and fixed" (rather than "removed forever"), I'd try and look into it. But I don't want to reintroduce stuff that Betaflight wants to get rid of; such effort would be bound to fail.

Re iNav, that might be a good option. The Dshot / DMA / timer issue will most likely be less of a problem there, as it seems to be geared towards using PWM as the motor protocol, which does not need DMA for motor output.

iNav has DShot, albeit with a scary warning. As for analog protocols … I like BLHeli_32 telemetry. From the BLHeli_32 side, telemetry could work with analog protocols — there's an auto telemetry option since version 32.51. But I think it wouldn't work with the usual "all ESCs on one RX" wiring; all ESCs would send telemetry all the time and clash. So telemetry depends on DShot.

Looking at the LIDAR drivers, I see that Betaflight drops invalid packets and so does iNav. So these may not be uncommon.

hi did u get rangefinder work on bf finally?