umdlife / psdk_ros2

This repository is a ROS 2 wrapper for the DJI PSDK libraries.
https://umdlife.github.io/psdk_ros2/documentation/Introduction.html
Mozilla Public License 2.0
63 stars 16 forks source link

Support for Matrice M3TD? #122

Open kkishore9891 opened 2 months ago

kkishore9891 commented 2 months ago

Hello!

I am running the wrapper on my Matrice M3TD drone and I am getting the following error:

nvidia@nvidia:~/ros2_ws$ ros2 launch psdk_wrapper wrapper.launch.py
[INFO] [launch]: All log files can be found below /home/nvidia/.ros/log/2024-07-31-11-29-47-669209-nvidia-11138
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [psdk_wrapper_node-1]: process started with pid [11151]
[psdk_wrapper_node-1] [INFO] [1722418188.026433398] [wrapper.psdk_wrapper_node]: Creating Constructor PSDKWrapper
[psdk_wrapper_node-1] [INFO] [1722418188.039306654] [wrapper.flight_control_node]: Creating FlightControlModule
[psdk_wrapper_node-1] [INFO] [1722418188.050213413] [wrapper.telemetry_node]: Creating TelemetryModule
[psdk_wrapper_node-1] [INFO] [1722418188.061417333] [wrapper.camera_node]: Creating CameraModule
[psdk_wrapper_node-1] [INFO] [1722418188.073803981] [wrapper.liveview_node]: Creating LiveviewModule
[psdk_wrapper_node-1] [INFO] [1722418188.086290088] [wrapper.gimbal_node]: Creating GimbalModule
[psdk_wrapper_node-1] [INFO] [1722418188.098702912] [wrapper.hms_node]: Creating HmsModule
[psdk_wrapper_node-1] [INFO] [1722418188.116287874] [wrapper.perception_node]: Creating PerceptionModule
[psdk_wrapper_node-1] [INFO] [1722418188.126498834] [wrapper.psdk_wrapper_node]: Configuring PSDKWrapper
[psdk_wrapper_node-1] [INFO] [1722418188.126591637] [wrapper.psdk_wrapper_node]: Loading parameters
[psdk_wrapper_node-1] [INFO] [1722418188.126712793] [wrapper.psdk_wrapper_node]: App name: ----
[psdk_wrapper_node-1] [INFO] [1722418188.126747707] [wrapper.psdk_wrapper_node]: App id: ----
[psdk_wrapper_node-1] [INFO] [1722418188.126778588] [wrapper.psdk_wrapper_node]: App key: ----
[psdk_wrapper_node-1] [INFO] [1722418188.126819133] [wrapper.psdk_wrapper_node]: Baudrate: 921600
[psdk_wrapper_node-1] [INFO] [1722418188.126854398] [wrapper.psdk_wrapper_node]: Using connection configuration file: /home/nvidia/ros2_ws/install/psdk_wrapper/share/psdk_wrapper/cfg/link_config.json
[psdk_wrapper_node-1] [INFO] [1722418188.127004739] [wrapper.psdk_wrapper_node]: Setting environment
[psdk_wrapper_node-1] [INFO] [1722418188.127136551] [wrapper.psdk_wrapper_node]: Registered OSAL handler
[psdk_wrapper_node-1] [INFO] [1722418188.127164520] [wrapper.psdk_wrapper_node]: Registered HAL handler
[psdk_wrapper_node-1] [INFO] [1722418188.127563061] [wrapper.psdk_wrapper_node]: Loaded configuration file
[psdk_wrapper_node-1] [INFO] [1722418188.127597751] [wrapper.psdk_wrapper_node]: Using DJI_USE_UART_USB_BULK_DEVICE
[psdk_wrapper_node-1] [INFO] [1722418188.127628152] [wrapper.psdk_wrapper_node]: Environment has been set!
[psdk_wrapper_node-1] [INFO] [1722418188.128068518] [wrapper.psdk_wrapper_node]: Activating PSDKWrapper
[psdk_wrapper_node-1] [INFO] [1722418188.128112807] [wrapper.psdk_wrapper_node]: Init DJI Core...
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted
[psdk_wrapper_node-1] chmod: changing permissions of '/dev/ttyUSB0': Operation not permitted

This is the link_config.json file:

{
    "dji_sdk_link_config": {
        "link_available": "use_only_uart/use_uart_and_usb_bulk_device/use_uart_and_network_device",
        "link_select": "use_uart_and_usb_bulk_device",
        "uart_config": {
            "uart1_device_name": "/dev/ttyUSB0",
            "uart2_device_enable": "true",
            "uart2_device_name": "/dev/ttyUSB0"
        },
        "network_config": {
            "network_device_name": "enxf8e43b7bbc2c",
            "network_usb_adapter_vid": "0x0955",
            "network_usb_adapter_pid": "0x7020"
        },
        "usb_bulk_config": {
            "usb_device_vid": "0x0955",
            "usb_device_pid": "0x7020",
            "usb_bulk1_device_name": "/dev/usb-ffs/bulk1",
            "usb_bulk1_interface_num": "7",
            "usb_bulk1_endpoint_in": "0x88",
            "usb_bulk1_endpoint_out": "0x05",
            "usb_bulk2_device_name": "/dev/usb-ffs/bulk2",
            "usb_bulk2_interface_num": "8",
            "usb_bulk2_endpoint_in": "0x89",
            "usb_bulk2_endpoint_out": "0x06"
        }
    }
}

This is the content of the hal_usb_bulk.h file in the PayloadSDK from which we could successfully run the DJI sample programs:

/**
 ********************************************************************
 * @file    hal_usb_bulk.h
 * @brief   This is the header file for "hal_usb_bulk.c", defining the structure and
 * (exported) function prototypes.
 *
 * @copyright (c) 2021 DJI. All rights reserved.
 *
 * All information contained herein is, and remains, the property of DJI.
 * The intellectual and technical concepts contained herein are proprietary
 * to DJI and may be covered by U.S. and foreign patents, patents in process,
 * and protected by trade secret or copyright law.  Dissemination of this
 * information, including but not limited to data and other proprietary
 * material(s) incorporated within the information, in any form, is strictly
 * prohibited without the express written consent of DJI.
 *
 * If you receive this source code without DJI’s authorization, you may not
 * further disseminate the information, and you must immediately remove the
 * source code and notify DJI of its removal. DJI reserves the right to pursue
 * legal actions against you for any loss(es) or damage(s) caused by your
 * failure to do so.
 *
 *********************************************************************
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef HAL_USB_BULK_H
#define HAL_USB_BULK_H

/* Includes ------------------------------------------------------------------*/
#include "stdint.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#ifdef LIBUSB_INSTALLED

#include <libusb-1.0/libusb.h>

#endif

#include "dji_platform.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Exported constants --------------------------------------------------------*/
#define LINUX_USB_BULK1_EP_OUT_FD               "/dev/usb-ffs/bulk1/ep1"
#define LINUX_USB_BULK1_EP_IN_FD                "/dev/usb-ffs/bulk1/ep2"

#define LINUX_USB_BULK1_INTERFACE_NUM           (7)
#define LINUX_USB_BULK1_END_POINT_IN            (0x88)
#define LINUX_USB_BULK1_END_POINT_OUT           (5)

#define LINUX_USB_BULK2_EP_OUT_FD               "/dev/usb-ffs/bulk2/ep1"
#define LINUX_USB_BULK2_EP_IN_FD                "/dev/usb-ffs/bulk2/ep2"

#define LINUX_USB_BULK2_INTERFACE_NUM           (8)
#define LINUX_USB_BULK2_END_POINT_IN            (0x89)
#define LINUX_USB_BULK2_END_POINT_OUT           (6)

#ifdef PLATFORM_ARCH_x86_64
#define LINUX_USB_VID                         (0x0B95)
#define LINUX_USB_PID                         (0x1790)
#else
#define LINUX_USB_VID                         (0x0955)
#define LINUX_USB_PID                         (0x7020)
#endif

/* Exported types ------------------------------------------------------------*/

/* Exported functions --------------------------------------------------------*/
T_DjiReturnCode HalUsbBulk_Init(T_DjiHalUsbBulkInfo usbBulkInfo, T_DjiUsbBulkHandle *usbBulkHandle);
T_DjiReturnCode HalUsbBulk_DeInit(T_DjiUsbBulkHandle usbBulkHandle);
T_DjiReturnCode HalUsbBulk_WriteData(T_DjiUsbBulkHandle usbBulkHandle, const uint8_t *buf, uint32_t len,
                                     uint32_t *realLen);
T_DjiReturnCode HalUsbBulk_ReadData(T_DjiUsbBulkHandle usbBulkHandle, uint8_t *buf, uint32_t len, uint32_t *realLen);
T_DjiReturnCode HalUsbBulk_GetDeviceInfo(T_DjiHalUsbBulkDeviceInfo *deviceInfo);

#ifdef __cplusplus
}
#endif

#endif // HAL_USB_BULK_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/

content of the hal_uart.h in the original PayloadSDK repo that we were using:

/**
 ********************************************************************
 * @file    hal_uart.h
 * @brief   This is the header file for "hal_uart.c", defining the structure and
 * (exported) function prototypes.
 *
 * @copyright (c) 2021 DJI. All rights reserved.
 *
 * All information contained herein is, and remains, the property of DJI.
 * The intellectual and technical concepts contained herein are proprietary
 * to DJI and may be covered by U.S. and foreign patents, patents in process,
 * and protected by trade secret or copyright law.  Dissemination of this
 * information, including but not limited to data and other proprietary
 * material(s) incorporated within the information, in any form, is strictly
 * prohibited without the express written consent of DJI.
 *
 * If you receive this source code without DJI’s authorization, you may not
 * further disseminate the information, and you must immediately remove the
 * source code and notify DJI of its removal. DJI reserves the right to pursue
 * legal actions against you for any loss(es) or damage(s) caused by your
 * failure to do so.
 *
 *********************************************************************
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef HAL_UART_H
#define HAL_UART_H

/* Includes ------------------------------------------------------------------*/
#include "stdint.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include "stdlib.h"

#include "dji_platform.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Exported constants --------------------------------------------------------*/
//User can config dev based on there environmental conditions
#define LINUX_UART_DEV1    "/dev/ttyUSB0"
#define LINUX_UART_DEV2    "/dev/ttyACM0"

/* Exported types ------------------------------------------------------------*/

/* Exported functions --------------------------------------------------------*/
T_DjiReturnCode HalUart_Init(E_DjiHalUartNum uartNum, uint32_t baudRate, T_DjiUartHandle *uartHandle);
T_DjiReturnCode HalUart_DeInit(T_DjiUartHandle uartHandle);
T_DjiReturnCode HalUart_WriteData(T_DjiUartHandle uartHandle, const uint8_t *buf, uint32_t len, uint32_t *realLen);
T_DjiReturnCode HalUart_ReadData(T_DjiUartHandle uartHandle, uint8_t *buf, uint32_t len, uint32_t *realLen);
T_DjiReturnCode HalUart_GetStatus(E_DjiHalUartNum uartNum, T_DjiUartStatus *status);

#ifdef __cplusplus
}
#endif

#endif // HAL_UART_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/

The contents of the file where udev rule is set:

  #/etc/udev/rules.d/99-usb-serial.rules                                                   
KERNEL=="ttyUSB[0-9]*", MODE="0666"

Despite adding the udev rule and running

sudo usermod -a -G dialout $USER
# Allow read and write access to owner and group members
sudo chmod 660 /dev/ttyUSB0

I'd like to know if the wrapper works on M3TD drone. Also I would like to assure you that all the hardware connections are correct and we have tested everything in our in house ROS2 PSDK wrapper which can subscribe thermal image feed, run waypoint missions etc. But we want to switch from our PayloadSDK ros2 wrapper to yours to ease our development.

biancabnd commented 2 months ago

Hi @kkishore9891, Thank you for the detailed description. As you mentioned, if you have been able to run successfully the DJI samples then the configuration should be the same to run the wrapper. A few things that I notice and advices I can give you:

  1. In the DJI hal_uart.h the second device is ttyACM0, you should add it as well in the "uart2_device_name" from link_config.json file.
  2. Although you have created and applied the udev rule, you should check that when you physically connect the usb to your computer the rule is correctly applied. So check that indeed the device to which it is connecting is ttyUSB0 and check that the permissions are correct (ls -l /dev | grep ttyUSB). You could also monitor udev events to see if rules are applied (sudo udevadm monitor --environment --udev)
  3. Last resort, try to launch the wrapper with sudo. It is not ideal, but just as a first test to see if at least you get past the permission error and the rest runs well
  4. Are you by any chance running this from inside a docker container? Because that could affect the device management.

Having said this, we do not have an M3TD drone in house, so the wrapper has not been tested with this model. However, we think despite a few changes, the main functionalities of the wrapper should still work. Let us know what you find out, we will try to support you as much as we can.