nusrobomaster / PX4-Autopilot

PX4 Autopilot Software
https://px4.io
BSD 3-Clause "New" or "Revised" License
2 stars 0 forks source link

DBUS RC Input Support #10

Closed chengguizi closed 3 years ago

chengguizi commented 3 years ago

On Dev A, DBus utilise USART1_RX (PB7), and has an inverting logic (when input is high, the RX pin is low) image

Similarly, for Dev C, the port is UART3_RX (PC11) image

chengguizi commented 3 years ago

Reference code https://github.com/RoboMaster/DevelopmentBoard-Examples/blob/master/RemoteControl/Src/main.c

https://github.com/garfield38/DJI_DBUS/blob/master/DJI_DBUS.cpp https://github.com/RoboMaster-Club/arduino_DBUS_decoder

Blog: https://www.codetd.com/en/article/7453572

chengguizi commented 3 years ago

https://www.youtube.com/watch?v=IqLUHj7nJhI&ab_channel=Mad%27sTech https://github.com/uzh-rpg/rpg_quadrotor_control/wiki/SBUS-Protocol

Good materials to learn

chengguizi commented 3 years ago

The code base within PX4 for SBUS, may just need to take care of the inverting logic rc_io_invert

https://github.com/nusrobomaster/PX4-Autopilot/blob/rm2021/src/drivers/rc_input/RCInput.cpp

/************************************************************************************
 * Name: board_rc_invert_input
 *
 * Description:
 *   All boards may optionally define RC_INVERT_INPUT(bool invert) that is
 *   used to invert the RC_SERIAL_PORT RC port (e.g. to toggle an external XOR via
 *   GPIO).
 *
 * Input Parameters:
 *   invert_on - A positive logic value, that when true (on) will set the HW in
 *               inverted NRZ mode where a MARK will be 0 and SPACE will be a 1.
 *
 * Returned Value:
 *   true the UART inversion got set.
 *
 ************************************************************************************/
chengguizi commented 3 years ago

rc_update module subscribe to

Therefore, this module is expecting a formated RC message uORB::SubscriptionCallbackWorkItem _input_rc_sub{this, ORB_ID(input_rc)};

uint64 timestamp            # time since system start (microseconds)

uint8 RC_INPUT_SOURCE_UNKNOWN = 0
uint8 RC_INPUT_SOURCE_PX4FMU_PPM = 1
uint8 RC_INPUT_SOURCE_PX4IO_PPM = 2
uint8 RC_INPUT_SOURCE_PX4IO_SPEKTRUM = 3
uint8 RC_INPUT_SOURCE_PX4IO_SBUS = 4
uint8 RC_INPUT_SOURCE_PX4IO_ST24 = 5
uint8 RC_INPUT_SOURCE_MAVLINK = 6
uint8 RC_INPUT_SOURCE_QURT = 7
uint8 RC_INPUT_SOURCE_PX4FMU_SPEKTRUM = 8
uint8 RC_INPUT_SOURCE_PX4FMU_SBUS = 9
uint8 RC_INPUT_SOURCE_PX4FMU_ST24 = 10
uint8 RC_INPUT_SOURCE_PX4FMU_SUMD = 11
uint8 RC_INPUT_SOURCE_PX4FMU_DSM = 12
uint8 RC_INPUT_SOURCE_PX4IO_SUMD = 13
uint8 RC_INPUT_SOURCE_PX4FMU_CRSF = 14

uint8 RC_INPUT_MAX_CHANNELS = 18    # Maximum number of R/C input channels in the system. S.Bus has up to 18 channels.

uint64 timestamp_last_signal        # last valid reception time

uint8 channel_count         # number of channels actually being seen

int32 rssi              # receive signal strength indicator (RSSI): < 0: Undefined, 0: no signal, 100: full reception

bool rc_failsafe            # explicit failsafe flag: true on TX failure or TX out of range , false otherwise. Only the true state is reliable, as there are some (PPM) receivers on the market going into failsafe without telling us explicitly.
bool rc_lost                # RC receiver connection status: True,if no frame has arrived in the expected time, false otherwise. True usually means that the receiver has been disconnected, but can also indicate a radio link loss on "stupid" systems. Will remain false, if a RX with failsafe option continues to transmit frames after a link loss.

uint16 rc_lost_frame_count      # Number of lost RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike funtionality.
uint16 rc_total_frame_count     # Number of total RC frames. Note: intended purpose: observe the radio link quality if RSSI is not available. This value must not be used to trigger any failsafe-alike funtionality.
uint16 rc_ppm_frame_length      # Length of a single PPM frame. Zero for non-PPM systems

uint8 input_source          # Input source
uint16[18] values           # measured pulse widths for each of the supported channels
chengguizi commented 3 years ago

The publisher of the rc_input message lies within RCInput.hpp uORB::PublicationMulti<input_rc_s> _to_input_rc{ORB_ID(input_rc)};

chengguizi commented 3 years ago

For figuring out which ttySx port the RC is one, probably you want to enable the following option:

config STM32_SERIAL_DISABLE_REORDERING
    bool "Disable reordering of ttySx devices."
    default n
    ---help---
        NuttX per default reorders the serial ports (/dev/ttySx) so that the
        console is always on /dev/ttyS0. If more than one UART is in use this
        can, however, have the side-effect that all port mappings
        (hardware USART1 -> /dev/ttyS0) change if the console is moved to another
        UART. This is in particular relevant if a project uses the USB console
        in some boards and a serial console in other boards, but does not
        want the side effect of having all serial port names change when just
        the console is moved from serial to USB.
chengguizi commented 3 years ago

This seems to be the parsing code we had last year

https://github.com/nusrobomaster/robot_firmware/blob/f01669813e0cd866af75f9e16014deb0f9b56f38/standard_robot/Core/Tasks/Src/remote_control_task.c

chengguizi commented 3 years ago
try parsing newBytes = 18
0 4 20 0 1 98 0 0 0 0 0 0 0 0 0 0 0 4 
try parsing newBytes = 5
0 4 20 0 1 
try parsing newBytes = 13
98 0 0 0 0 0 0 0 0 0 0 0 4 
try parsing newBytes = 18
0 4 20 0 1 98 0 0 0 0 0 0 0 0 0 0 0 4 
try parsing newBytes = 6
0 4 20 0 1 98 
try parsing newBytes = 12
0 0 0 0 0 0 0 0 0 0 0 4 
try parsing newBytes = 18
0 4 20 0 1 98 0 0 0 0 0 0 0 0 0 0 0 4 
try parsing newBytes = 5
0 4 20 0 1 

Refer to commit cc6fde892105f9c5abedae46a5edbc396863778e , now we are good to go with parsing the 18 bytes

You may refer to https://github.com/RoboMaster-Club/arduino_DBUS_decoder/blob/74d1bcc7fed864ad6b4ff383d8b43cef20990f0c/arduino_DBUS_decoder.ino#L8 for indentifying the start of the frame, when the RC controller is in neutral position.

vincentlauhl commented 3 years ago

Refer to commit https://github.com/nusrobomaster/PX4-Autopilot/commit/cc351bfcb038f20f3429cb2cf2cfe3d1b8046e76 . Successfully parsed 18 bytes from the remote control and changed the values to fit PX4

chengguizi commented 3 years ago

@gimmethisusername I realise this RC input change is only made on Dev A board. Can you test it one the Dev C as well.

@AndreWongZH Are you able to change the relevant UART settings and test on dev C, before we merge this branch