Week 4 :

Add support for YDLIDAR in meta-ros2-foxy layer

  • Create YDLidar-SDK recipe as it a dependency for ydlidar_ros2_driver.

    # Change into recipe directory
    $ cd $AGL_TOP/master/external/meta-ros/meta-ros2-foxy/generated-recipes/
    $ mkdir ydlidar-ros2-sdk/ 
    $ cd ydlidar-ros2-sdk/
    $ vim ydlidar-ros2-sdk_1.4.7.bb
    
    # Define the recipe
    
    DESCRIPTION = "YDLIDAR SDK"
    AUTHOR = "..."
    ROS_AUTHOR = "...."
    HOMEPAGE = "https://wiki.ros.org"
    SECTION = "devel"
    LICENSE = "BSD"
    LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=4e320231d59c825e45dbfda066af29c9"
    
    SRC_URI = "git://github.com/YDLIDAR/YDLidar-SDK.git;protocol=https"
    
    SRCREV = "8b287ed831db0892f51793650b438790442fa09c"
    
    S = "${WORKDIR}/git"
    
    inherit cmake
    
    FILES_${PN} += "${datadir} ${prefix}/startup"
    
    do_install_append() {
        sed -i -e 's|${DEBUG_PREFIX_MAP}||g; s|--sysroot=${STAGING_DIR_TARGET}||g' ${D}${libdir}/pkgconfig/*.pc
    }
    
    RDEPENDS_${PN} += "bash"
    
  • Create ydlidar_ros2_driver recipe.

    # Change into recipe directory
    $ cd $AGL_TOP/master/external/meta-ros/meta-ros2-foxy/generated-recipes/
    $ mkdir ydlidar-ros2-driver/ 
    $ cd ydlidar-ros2-driver/
    $ vim ydlidar-ros2-driver_1.0.1.bb
    
    # Define the recipe
      
    inherit ros_distro_foxy
    inherit ros_superflore_generated
    
    DESCRIPTION = "The ROS2 device driver for YDLIDAR LIDARS"
    AUTHOR = "..."
    ROS_AUTHOR = "...."
    HOMEPAGE = "https://wiki.ros.org"
    SECTION = "devel"
    LICENSE = "BSD"
    LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=d41d8cd98f00b204e9800998ecf8427e"
    
    ROS_CN = "ydlidar_ros2_driver"
    ROS_BPN = "ydlidar_ros2_driver"
    
    ROS_BUILD_DEPENDS = " \
        rclcpp \
        rclcpp-components \
        sensor-msgs \
        visualization-msgs \
        geometry-msgs \
        std-srvs \
    "
    
    ROS_BUILDTOOL_DEPENDS = " \
        ament-cmake-auto-native \
        ament-cmake-ros-native \
    "
    
    ROS_EXPORT_DEPENDS = ""
    
    ROS_BUILDTOOL_EXPORT_DEPENDS = ""
    
    ROS_EXEC_DEPENDS = " \
        rclcpp \
        rclcpp-components \
        sensor-msgs \
        visualization-msgs \
        geometry-msgs \
        std-srvs \
    "
    
    # Currently informational only -- see http://www.ros.org/reps/rep-0149.html#dependency-tags.
    ROS_TEST_DEPENDS = ""
    
    DEPENDS = "${ROS_BUILD_DEPENDS} ${ROS_BUILDTOOL_DEPENDS}"
    # Bitbake doesn't support the "export" concept, so build them as if we needed them to build this package (even though we actually
    # don't) so that they're guaranteed to have been staged should this package appear in another's DEPENDS.
    DEPENDS += "${ROS_EXPORT_DEPENDS} ${ROS_BUILDTOOL_EXPORT_DEPENDS}" 
    #added
    DEPENDS += "ydlidar-ros2-sdk"
    
    RDEPENDS_${PN} += "${ROS_EXEC_DEPENDS}"
    
    #ROS_BRANCH ?= "branch=release/foxy/ydlidar_ros2_driver"
    SRC_URI = "git://github.com/YDLIDAR/ydlidar_ros2_driver;branch=master;protocol=https"
    SRCREV = "2e095da315aec0a0bc5aaac12082cb9d1f97f8b5"
    S = "${WORKDIR}/git"
    
    ROS_BUILD_TYPE = "ament_cmake"
    
    inherit ros_${ROS_BUILD_TYPE}
    
  • Add ydlidar_ros2_driver recipe to superflore-ros-distro.inc configuration file.

    # After setting up AGL workspace
    
    # Clone the meta-ros layer, skip if already cloned
    $ cd $AGL_TOP/master/external
    $ git clone https://github.com/ros/meta-ros.git
    $ cd meta-ros
    $ git checkout -b dunfell
    
    # Change into conf directory
    $ cd $AGL_TOP/master/external/meta-ros/meta-ros2-foxy/conf/ros-distro/include/foxy/generated
    $ vim superflore-ros-distro.inc
      
    Edit according to add ydlidar_ros2_driver :
    
    In ROS_SUPERFLORE_GENERATED_RECIPES add,
      ydlidar-ros2-driver \
    
    In ROS_SUPERFLORE_GENERATED_RECIPE_BASENAMES_WITH_COMPONENT add,
      ydlidar-ros2-driver/ydlidar-ros2-driver_1.0.1 \
      
    In ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES add,
      ydlidar-ros2-driver \
    
    In ROS_SUPERFLORE_GENERATED_RECIPES_FOR_COMPONENTS add,
      ydlidar-ros2-driver \
    

Build master/x86: meta-ros + agl-image-weston + YDLIDAR support

  • Kindly go through build process of AGL and building for x86 for detailed reference to setup and initialize AGL workspace.

    # After setting up AGL workspace
    
    # Clone the meta-ros layer, skip if already cloned
    $ cd $AGL_TOP/master/external
    $ git clone https://github.com/ros/meta-ros.git
    $ cd meta-ros
    $ git checkout -b dunfell
    
    # Setup build directory
    $ cd $AGL_TOP/master/
    $ source meta-agl/scripts/aglsetup.sh -b build-x86-meta-ros-weston agl-devel
    $ ln -sf $AGL_TOP/site.conf conf/
    $ ls -alh conf/
      
    # Edit the following conf files :
    
    $ vim conf/local.conf #add the following to the bottom, to save error logs for future debugging
    # local.conf
      INHERIT += "buildhistory"
      BUILDHISTORY_COMMIT = "1"
      IMAGE_INSTALL_append = " packagegroup-ros-world-foxy"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "plotjuggler"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "plotjuggler-msgs"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "plotjuggler-ros"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "eigenpy"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "py-trees-ros-tutorials"
        
    $ vim conf/bblayers.conf #Replace the following chunk
    # bblayers.conf
      AGL_META_NETWORKING ?= ""
      AGL_META_PYTHON = "${METADIR}/external/meta-openembedded/meta-python"
      AGL_META_ROS = " \
        ${METADIR}/external/meta-ros/meta-ros-common \
        ${METADIR}/external/meta-ros/meta-ros-backports-gatesgarth \
        ${METADIR}/external/meta-ros/meta-ros2 \
        ${METADIR}/external/meta-ros/meta-ros2-foxy \
        "
      AGL_OTHER_DEPENDENCY_LAYERS = " \
        ${AGL_META_NETWORKING} \
        ${AGL_META_PYTHON} \
        ${AGL_META_ROS} \
        "
    
    # Build the image
    
    $ cd $AGL_TOP/master/build-x86-meta-ros-weston/
    $ source agl-init-build-env #if not sourced
    $ bitbake -p ros-core #build ros-core first, to check all layers are added.
    $ time bitbake agl-image-weston #wait for the build process to finish.
    

Run master/x86: meta-ros + agl-image-weston + YDLIDAR support

  • Kindly use pre-built image agl-image-weston-qemux86-64, if you want to skip the building process.

  • Kindly go through using prebuilt x86 images for detailed reference to setup and initialize AGL workspace.

    # gdrive : https://drive.google.com/drive/folders/1kTjN-Ptouwo6MMB23E5bJQ76Wm6FnRdb?usp=sharing
      
    # Install the dependencies
    $ apt-get install qemu
    $ sudo apt install vinagre
    $ sudo apt install qemu-system-x86
    
    # Copy image and kernel files
    $ cp ~/Downloads/agl-image-weston-qemux86-64.ext4 ./
    $ cp ~/Downloads/bzImage ./
    $ sync
    
    # Run
    $ vim startup.sh
      # attach YDLIDAR to the host system.
      #-device usb-host,hostbus=1,hostport=4, change accordingly to ydlidar usb port `lsusb -t` 
    
      ( sleep 5 && vinagre --vnc-scale localhost ) > /tmp/vinagre.log 2>&1 &
          qemu-system-x86_64 -device virtio-net-pci,netdev=net0,mac=52:54:00:12:35:02 -netdev user,id=net0,hostfwd=tcp::2222-:22 \
          -drive file=agl-image-weston-qemux86-64.ext4,if=virtio,format=raw -show-cursor -usb -usbdevice tablet -device virtio-rng-pci \
          -device usb-host,hostbus=1,hostport=4 -vga virtio \
          -vnc :0 -soundhw hda -machine q35 -cpu kvm64 -cpu qemu64,+ssse3,+sse4.1,+sse4.2,+popcnt -enable-kvm \
          -m 2048 -serial mon:vc -serial mon:stdio -serial null -kernel bzImage \
    
    $ sudo ./startup.sh
    
    # Boots up
    qemu-system-x86_64: -usbdevice tablet: '-usbdevice' is deprecated, please use '-device usb-...' instead
    qemu-system-x86_64: warning: host doesn't support requested feature: CPUID.80000001H:ECX.svm [bit 2]
    
    Automotive Grade Linux 11.91.0+snapshot qemux86-64 ttyS1
    
    qemux86-64 login: root
    root@qemux86-64:~# source /usr/bin/ros_setup.sh
    root@qemux86-64:/# echo $LD_LIBRARY_PATH
      /usr/lib/x86_64-linux-gnu:/usr/lib
    root@qemux86-64:/# cd /usr/share/ydlidar_ros2_driver/ 
    root@qemux86-64:/# vim params/ydlidar.yaml
    # Edit accordingly, for YDLIDAR X4 :
      ydlidar_ros2_driver_node:
        ros__parameters:
          port: /dev/ttyUSB0
          frame_id: laser_frame
          ignore_array: ""
          baudrate: 128000
          lidar_type: 1
          device_type: 0
          sample_rate: 5
          abnormal_check_count: 4
          resolution_fixed: true
          reversion: false
          inverted: true
          auto_reconnect: true
          isSingleChannel: false
          intensity: false
          support_motor_dtr: true
          angle_max: 180.0
          angle_min: -180.0
          range_max: 12.0
          range_min: 0.1
          frequency: 8.0
          invalid_range_is_inf: false
      
    root@qemux86-64:/# ros2 launch launch/ydlidar_launch.py # YDLIDAR starts spinning
      
    # # In a new terminal, ssh into qemu : $ ssh -p 2222 root@localhost
    root@qemux86-64:~# source /usr/bin/ros_setup.sh
    root@qemux86-64:/# echo $LD_LIBRARY_PATH
      /usr/lib/x86_64-linux-gnu:/usr/lib
    root@qemux86-64:/# ros2 topic list -t 
      /parameter_events [rcl_interfaces/msg/ParameterEvent]
      /rosout [rcl_interfaces/msg/Log]
      /scan [sensor_msgs/msg/LaserScan]
      /tf_static [tf2_msgs/msg/TFMessage]
    root@qemux86-64:/# ros2 topic echo /scan # View data stream
      
    # In either terminal
    root@qemux86-64:/# poweroff #else, runs in background
    

Build master/raspberrypi4: meta-ros + agl-image-weston + YDLIDAR support

  • Kindly go through build process of AGL and building for raspberrypi4 for detailed reference to setup and initialize AGL workspace.

    # After setting up AGL workspace
    
    # Clone the meta-ros layer, skip if already cloned
    $ cd $AGL_TOP/master/external
    $ git clone https://github.com/ros/meta-ros.git
    $ cd meta-ros
    $ git checkout -b dunfell
    
    # Setup build directory
    $ cd $AGL_TOP/master/
    $ source meta-agl/scripts/aglsetup.sh -f -m raspberrypi4 -b build-rpi4-meta-ros-weston agl-devel
    $ ln -sf $AGL_TOP/site.conf conf/
    $ ls -alh conf/
    
    # Edit the following conf files :
    
    $ vim conf/local.conf #add the following to the bottom, to save error logs for  future debugging
    # local.conf
      INHERIT += "buildhistory"
      BUILDHISTORY_COMMIT = "1"
      IMAGE_INSTALL_append = " packagegroup-ros-world-foxy"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "plotjuggler"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "plotjuggler-msgs"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "plotjuggler-ros"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "eigenpy"
      ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES_remove = "py-trees-ros-tutorials"
    
    $ vim conf/bblayers.conf #Replace the following chunk
    # bblayers.conf
      AGL_META_NETWORKING ?= ""
      AGL_META_PYTHON = "${METADIR}/external/meta-openembedded/meta-python"
      AGL_META_ROS = " \
        ${METADIR}/external/meta-ros/meta-ros-common \
        ${METADIR}/external/meta-ros/meta-ros-backports-gatesgarth \
        ${METADIR}/external/meta-ros/meta-ros2 \
        ${METADIR}/external/meta-ros/meta-ros2-foxy \
        "
      AGL_OTHER_DEPENDENCY_LAYERS = " \
        ${AGL_META_NETWORKING} \
        ${AGL_META_PYTHON} \
        ${AGL_META_ROS} \
        "
    
    # Build the image
      
    $ cd $AGL_TOP/master/build-rpi4-ros-demo/
    $ source agl-init-build-env #if not sourced
    $ bitbake -p ros-core #build ros-core first, to check all layers are added.
    $ time bitbake agl-image-weston #wait for the build process to finish.
    

Run master/raspberrypi4: meta-ros + agl-image-weston + YDLIDAR support

  • Kindly use pre-built image agl-image-weston-raspberrypi4-64, if you want to skip the building process.

  • Kindly go through using prebuilt raspberrypi4 images for detailed reference to setup and initialize AGL workspace.

  • Connect YDLIDAR X4 to Raspberry Pi 4. Attach external USB if using with Raspberry Pi (otherwise underpowered and DEVICE FAILED warning).

    ## gdrive : https://drive.google.com/drive/folders/1eD-g32fao-5LsiF7k8w4XbbQXkZv0iMP?usp=sharing
    
    # Copy image and extract into SD card
    $ cp ~/Downloads/agl-image-weston-raspberrypi4-64.wic.xz ./
    $ lsblk #find <SD_CARD>
    $ sudo umount <SD_CARD>
    $ xzcat agl-image-weston-raspberrypi4-64.wic.xz | sudo dd of=<SD_CARD> bs=4M
    $ sync
      
    # Boot up Pi and ssh into it (local network)
    $ ifconfig #checkout local address
    $ sudo nmap -sn 192.168.1.0/24 #scan local network
    $ ssh-keygen -f "/home/boron/.ssh/known_hosts" -R "192.168.1.xx" #required if new image on same device
    $ ssh root@192.168.1.xx #Connect to raspberrypi4 through ssh
    
    # Boots Up
    raspberrypi4-64 login: root
    root@raspberrypi4-64:~# source /usr/bin/ros_setup.sh
    root@raspberrypi4-64:/# echo $LD_LIBRARY_PATH
      /usr/lib/x86_64-linux-gnu:/usr/lib
    root@raspberrypi4-64:/# cd /usr/share/ydlidar_ros2_driver/ 
    root@raspberrypi4-64:/# vim params/ydlidar.yaml
    # Edit accordingly, for YDLIDAR X4 :
      ydlidar_ros2_driver_node:
        ros__parameters:
          port: /dev/ttyUSB0
          frame_id: laser_frame
          ignore_array: ""
          baudrate: 128000
          lidar_type: 1
          device_type: 0
          sample_rate: 5
          abnormal_check_count: 4
          resolution_fixed: true
          reversion: false
          inverted: true
          auto_reconnect: true
          isSingleChannel: false
          intensity: false
          support_motor_dtr: true
          angle_max: 180.0
          angle_min: -180.0
          range_max: 12.0
          range_min: 0.1
          frequency: 8.0
          invalid_range_is_inf: false
      
    root@raspberrypi4-64:/# ros2 launch launch/ydlidar_launch.py # YDLIDAR starts spinning
      
    # In a new ssh terminal
    $ ssh root@192.168.1.xx #Connect to raspberrypi4 through ssh
    root@raspberrypi4-64:~# source /usr/bin/ros_setup.sh
    root@raspberrypi4-64:/# echo $LD_LIBRARY_PATH
      /usr/lib/x86_64-linux-gnu:/usr/lib
    root@raspberrypi4-64:/# ros2 topic list -t 
    root@raspberrypi4-64:/# ros2 topic echo /scan # View data stream