rotorflight / rotorflight-firmware

GNU General Public License v3.0
82 stars 39 forks source link

Better telemetry with CRSF / ELRS #81

Closed rotorflight closed 2 months ago

rotorflight commented 7 months ago

The current CRSF / ELRS is very limited for helicopter use.

An alternative should be considered how to pass telemetry sensors to the Tx. One option is to use the "Ardupilot FrSky telemetry passthrough", which is sending FrSky telemetry information with custom CRSF frames. This can be decoded by a LUA widget in the Tx.

rotorflight commented 3 months ago

The idea is to implement a new frame type for CRSF, which can encapsulate multiple sensors in a single frame. The FC can choose which sensors, and when to send the frames. This allows a very flexible telemetry, where the user can select exactly what sensors to send, and how often. Also, the sensors can be send only the they change.

In the FC firmware, a new frame type with the relevant sensor handling should be implemented.

In the Tx, a "Custom Script" (was mixer script) should be implemented. It would be reading the unknown telemetry frames, decoding them, and inserting the sensors + values back into EdgeTx.

raphaelcoeffic commented 3 months ago

At the end of the day, you will want to have something that feels more “native”, just to be able to take advantage of the possibilities with sensor values.

offer-shmuely commented 3 months ago
  1. first of all, I missing very match the 6-12 cells voltage, like the FLVSS of frsky (this is one of things stopping me to move to elrs in the first place)

  2. I love this ones: PID#, RTE#, LED#, Hspd, Hspd, Tspd

  3. what are this ones? RT%, Tbat

  4. Vbat is too generic, if I have motor battery, and battery for lights, and battery for RX, witch of them is Vbat? maybe better is Vmot?

  5. why do we have Curr, if we have Iesc/Ibec/Ibus ? it's confusing.

  6. I would add also longName=xxx" in 8 chars, as an optimistic approach that edgeTx (@raphaelcoeffic please...) will give us more than 4 char on ver 3.0 (what is the status on ethos? )

I think it is better to add description to each one in the code, so less guessing

rotorflight commented 3 months ago

I am going to edit this post until everybody agrees on the sensors and their names!

Update 11/6/2024 16:40 Update 12/6/2024 12:08


    -- Heartbeat (millisecond uptime % 60000)
    [0x0001]  = { name="BEAT",    unit=UNIT_RAW,                 prec=0,    dec=decU16  },

    -- Main battery voltage
    [0x0011]  = { name="Volt",    unit=UNIT_VOLTS,               prec=2,    dec=decU16  },
    -- Main battery current
    [0x0012]  = { name="Curr",    unit=UNIT_AMPS,                prec=2,    dec=decU16  },
    -- Main battery used capacity
    [0x0013]  = { name="Capa",    unit=UNIT_MAH,                 prec=3,    dec=decU16  },
    -- Main battery State-of-Charge / fuel level
    [0x0014]  = { name="Fuel",    unit=UNIT_PERCENT,             prec=0,    dec=decU8   },

    -- Main battery cell count
    [0x0020]  = { name="Cel#",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },
    -- Main battery cell voltages
    [0x0021]  = { name="Cels",    unit=UNIT_VOLTS,               prec=2,    dec=decCells },

    -- Control Combined (hires)
    [0x0030]  = { name="Ctrl",    unit=UNIT_RAW,                 prec=0,    dec=decControl },
    -- Roll Control angle
    [0x0031]  = { name="CRol",    unit=UNIT_DEGREE,              prec=1,    dec=decS16  },
    -- Pitch Control angle
    [0x0032]  = { name="CPtc",    unit=UNIT_DEGREE,              prec=1,    dec=decS16  },
    -- Yaw Control angle
    [0x0033]  = { name="CYaw",    unit=UNIT_DEGREE,              prec=1,    dec=decS16  },
    -- Collective Control angle
    [0x0034]  = { name="CCol",    unit=UNIT_DEGREE,              prec=1,    dec=decS16  },
    -- Throttle output %
    [0x0035]  = { name="Thr ",    unit=UNIT_PERCENT,             prec=0,    dec=decS8   },

    -- ESC voltage
    [0x0041]  = { name="EscV",    unit=UNIT_VOLTS,               prec=2,    dec=decU16  },
    -- ESC current
    [0x0042]  = { name="EscI",    unit=UNIT_AMPS,                prec=2,    dec=decU16  },
    -- ESC eRPM
    [0x0043]  = { name="EscR",    unit=UNIT_RPMS,                prec=2,    dec=decS16  },
    -- ESC PWM
    [0x0044]  = { name="EscP",    unit=UNIT_PERCENT,             prec=1,    dec=decS16  },
    -- ESC throttle
    [0x0045]  = { name="Esc%",    unit=UNIT_PERCENT,             prec=1,    dec=decS16  },
    -- ESC temperature
    [0x0046]  = { name="EscT",    unit=UNIT_CELSIUS,             prec=0,    dec=decU8   },
    -- ESC / BEC temperature
    [0x0047]  = { name="BecT",    unit=UNIT_CELSIUS,             prec=0,    dec=decU8   },
    -- ESC / BEC voltage
    [0x0048]  = { name="BecV",    unit=UNIT_VOLTS,               prec=2,    dec=decU16  },
    -- ESC / BEC current
    [0x0049]  = { name="BecI",    unit=UNIT_AMPS,                prec=2,    dec=decU16  },
    -- ESC Status Flags
    [0x004A]  = { name="EscF",    unit=UNIT_RAW,                 prec=0,    dec=decU32  },

    -- Combined ESC voltage
    [0x0080]  = { name="Vesc",    unit=UNIT_VOLTS,               prec=2,    dec=decU16  },
    -- BEC voltage
    [0x0081]  = { name="Vbec",    unit=UNIT_VOLTS,               prec=2,    dec=decU16  },
    -- BUS voltage
    [0x0082]  = { name="Vbus",    unit=UNIT_VOLTS,               prec=2,    dec=decU16  },
    -- MCU voltage
    [0x0083]  = { name="Vmcu",    unit=UNIT_VOLTS,               prec=2,    dec=decU16  },

    -- Combined ESC current
    [0x0090]  = { name="Iesc",    unit=UNIT_AMPS,                prec=2,    dec=decU16  },
    -- BEC current
    [0x0091]  = { name="Ibec",    unit=UNIT_AMPS,                prec=2,    dec=decU16  },
    -- BUS current
    [0x0092]  = { name="Ibus",    unit=UNIT_AMPS,                prec=2,    dec=decU16  },
    -- MCU current
    [0x0093]  = { name="Imcu",    unit=UNIT_AMPS,                prec=2,    dec=decU16  },

    -- Combined ESC temeperature
    [0x00A0]  = { name="Tesc",    unit=UNIT_CELSIUS,             prec=0,    dec=decU8   },
    -- BEC temperature
    [0x00A1]  = { name="Tbec",    unit=UNIT_CELSIUS,             prec=0,    dec=decU8   },
    -- CPU temperature
    [0x00A3]  = { name="Tcpu",    unit=UNIT_CELSIUS,             prec=0,    dec=decU8   },
    -- Air temperature
    [0x00A4]  = { name="Tair",    unit=UNIT_CELSIUS,             prec=0,    dec=decU8   },
    -- Motor temperature
    [0x00A5]  = { name="Tmtr",    unit=UNIT_CELSIUS,             prec=0,    dec=decU8   },
    -- Battery temperature
    [0x00A6]  = { name="Tbat",    unit=UNIT_CELSIUS,             prec=0,    dec=decU8   },

    -- Heading (combined gyro+mag+GPS)
    [0x00B1]  = { name="Hdg ",    unit=UNIT_DEGREE,              prec=1,    dec=decS16  },
    -- Altitude (combined baro+GPS)
    [0x00B2]  = { name="Alt ",    unit=UNIT_METERS,              prec=2,    dec=decS24  },
    -- Variometer (combined baro+GPS)
    [0x00B3]  = { name="VSpd",    unit=UNIT_METERS_PER_SECOND,   prec=2,    dec=decS16  },

    -- Headspeed
    [0x00C0]  = { name="Hrpm",    unit=UNIT_RPMS,                prec=0,    dec=decU16  },
    -- Tailspeed
    [0x00C1]  = { name="Trpm",    unit=UNIT_RPMS,                prec=0,    dec=decU16  },

    -- Attitude (hires combined)
    [0x0100]  = { name="Attd",    unit=UNIT_DEGREE,              prec=1,    dec=decAttitude },
    -- Attitude pitch
    [0x0101]  = { name="Ptch",    unit=UNIT_DEGREE,              prec=0,    dec=decS16  },
    -- Attitude roll
    [0x0102]  = { name="Roll",    unit=UNIT_DEGREE,              prec=0,    dec=decS16  },
    -- Attitude yaw
    [0x0103]  = { name="Yaw ",    unit=UNIT_DEGREE,              prec=0,    dec=decS16  },

    -- Acceleration (hires combined)
    [0x0110]  = { name="Accl",    unit=UNIT_G,                   prec=2,    dec=decAccel },
    -- Acceleration X
    [0x0111]  = { name="AccX",    unit=UNIT_G,                   prec=1,    dec=decS16  },
    -- Acceleration Y
    [0x0112]  = { name="AccY",    unit=UNIT_G,                   prec=1,    dec=decS16  },
    -- Acceleration Z
    [0x0113]  = { name="AccZ",    unit=UNIT_G,                   prec=1,    dec=decS16  },

    -- GPS Satellite count
    [0x0121]  = { name="Sats",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },
    -- GPS PDOP
    [0x0122]  = { name="PDOP",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },
    -- GPS HDOP
    [0x0123]  = { name="HDOP",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },
    -- GPS VDOP
    [0x0124]  = { name="VDOP",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },
    -- GPS Coordinates
    [0x0125]  = { name="GPS ",    unit=UNIT_RAW,                 prec=0,    dec=decLatLong },
    -- GPS altitude
    [0x0126]  = { name="GAlt",    unit=UNIT_METERS,              prec=1,    dec=decS16  },
    -- GPS heading
    [0x0127]  = { name="GHdg",    unit=UNIT_DEGREE,              prec=1,    dec=decS16  },
    -- GPS ground speed
    [0x0128]  = { name="GSpd",    unit=UNIT_METERS_PER_SECOND,   prec=2,    dec=decU16  },
    -- GPS home distance
    [0x0129]  = { name="GDis",    unit=UNIT_METERS,              prec=1,    dec=decU16  },
    -- GPS home direction
    [0x012A]  = { name="GDir",    unit=UNIT_METERS,              prec=1,    dec=decU16  },

    -- CPU load
    [0x0141]  = { name="CPU%",    unit=UNIT_PERCENT,             prec=0,    dec=decU8  },
    -- System load
    [0x0142]  = { name="SYS%",    unit=UNIT_PERCENT,             prec=0,    dec=decU8  },
    -- Realtime CPU load
    [0x0143]  = { name="RT% ",    unit=UNIT_PERCENT,             prec=0,    dec=decU8  },

    -- Model ID
    [0x0200]  = { name="MDL#",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },
    -- Flight mode flags
    [0x0201]  = { name="Mode",    unit=UNIT_RAW,                 prec=0,    dec=decU32  },
    -- Arming disable flags
    [0x0202]  = { name="ARM ",    unit=UNIT_RAW,                 prec=0,    dec=decU32  },
    -- Rescue state
    [0x0203]  = { name="Resc",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },
    -- Governor state
    [0x0204]  = { name="Gov ",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },

    -- Current PID profile
    [0x0211]  = { name="PID#",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },
    -- Current Rate profile
    [0x0212]  = { name="RTE#",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },
    -- Current LED profile
    [0x0213]  = { name="LED#",    unit=UNIT_RAW,                 prec=0,    dec=decU8   },```
offer-shmuely commented 3 months ago

I do not think we must continue with existing edgeTx names. We have a chance to do it better:grinning: I think it better if the first part is “who is reporting “ Second part “what is reported” escV (the first or only esc) escI (use I for current, since C can be interpreted as capacity) escT (in the future: esc temperature) es2V (second esc) es3V mcu% / mcuT becV / becI

rtlopez commented 3 months ago

Hi, I'm thinking about sensors that indicate vibrations, i.e.

Values could be normalized to deg/s, with some scaling we could fit in U8 size, U16 seems bit wasting bandwidth as usually 10-11 bits should be enough.

What do you think?

offer-shmuely commented 3 months ago

Some more comments:

What is the meaning of: Combined ESC voltage? (and temp) You can’t sum voltage like you can do with current.

BecC —> becI (c may be interpreted as capacity, big I is better)

Thr —> Thr% (Throttle output %)

There is a typo in esc current EscV —> EscI

rotorflight commented 3 months ago

Updated.

The Combined ESC is a BF thing. It summs up currents, takes average of voltage, and maximum temperature.

"Thr" is a Frsky sensor. "Thr%" would make more sense though.

rotorflight commented 3 months ago

The ESC sensor grouping is important, because it is forwarding the telemetry from ESC. For other sensors, the grouping is done the way it is most sensible, like temperatures together.

rotorflight commented 3 months ago

Hi, I'm thinking about sensors that indicate vibrations, i.e.

  • VibH - vibrations that comes from Head (from raw gyro)
  • VibT - vibrations that comes from Tail (from raw gyro)
  • VibM - vibrations that comes from Motor (from raw gyro)
  • VibU - unfiltered vibrations that leaks to PID (from filtered gyro)

Values could be normalized to deg/s, with some scaling we could fit in U8 size, U16 seems bit wasting bandwidth as usually 10-11 bits should be enough.

What do you think?

It's a good idea. But I'll leave it later, as we don't have any of this data available yet. Right now, trying to get the data we have into the telemetry sensors.

rtlopez commented 3 months ago

Hi, I'm thinking about sensors that indicate vibrations, i.e.

  • VibH - vibrations that comes from Head (from raw gyro)
  • VibT - vibrations that comes from Tail (from raw gyro)
  • VibM - vibrations that comes from Motor (from raw gyro)
  • VibU - unfiltered vibrations that leaks to PID (from filtered gyro)

Values could be normalized to deg/s, with some scaling we could fit in U8 size, U16 seems bit wasting bandwidth as usually 10-11 bits should be enough. What do you think?

It's a good idea. But I'll leave it later, as we don't have any of this data available yet. Right now, trying to get the data we have into the telemetry sensors.

You are right, the more I think about it, the less certain I am about their names. Nevertheless I'm still thinking about this functionality, and I'll probably make a issue to discuss the details in the future.

However maybe it would be good to have some development fields, like debug1,2,3,4 to be able to verify some concepts, before we decide to add them to telemetry. Even with possibility to pass blackbox debug stream.

rotorflight commented 3 months ago

Now that is a GOOD IDEA. The debug fields. Will add.

rotorflight commented 2 months ago

DONE!!!!

sp3swj commented 2 weeks ago

What progress wit TEMPERATURE related telemetry in CFRS ??

Looks like nobody care for temperature :-(

https://github.com/crsf-wg/crsf/wiki/Packet-Types https://github.com/ExpressLRS/ExpressLRS/blob/master/src/lib/CrsfProtocol/crsf_protocol.h

and EdgeTX can not sent temperature over CFSR :-(

This proporsal is realy nice :-) https://github.com/rotorflight/rotorflight-firmware/issues/81#issuecomment-2160375732

offer-shmuely commented 2 weeks ago

The rotorflight solution is already working 😀 It is a good concept! (Since elrs is stuck on this subject)

The flight controller send any sensor he like, on a special id that is not used by the crsf. And you install on the edgeTx a "telemetry decoder script" that turn it to sensors in the name/type/precision you like