Heavy02011 / DonkeyJet

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Workspace for DonkeyJet

Introducing my ongoing robotics project, currently named DonkeyJet, inspired by the Donkey Car project. This mobile robot is built on an RC car frame and powered by Jetson Nano, providing a hands-on platform for practicing robotics knowledge. The goal is to continually enhance its capabilities while exploring various aspects of robotics technology. While I am not certain about the name DonkeyJet, I invite you to follow me on this exciting journey of discovery as I document my progress and share insights with fellow enthusiasts in my weblog here.

Docker Images

We are using docker for this project. Read more here.

Setup for building docker image for multiple platforms which images are built natively on the corresponding hardware without emulation.

/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
export REGISTRY="<the docker registry to be used, or dockerhub user>"

docker context create jetson --docker "host=tcp://jetson:2375"
docker context create localamd64 --docker "host=unix:///var/run/docker.sock"

# just one time
# docker buildx create --use  --driver-opt network=host --config=buildkitd.toml --name MultiPlatform
docker buildx create --use --driver-opt network=host --config=buildkitd-arm64.toml --name mybuilder jetson
docker buildx create --append --driver-opt network=host --config=buildkitd-amd64.toml --name mybuilder localamd64

Docker image with CUDA and ROS2

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -f ros2_base2.Dockerfile \
  -t ${REGISTRY}/ros2_base2:latest \
  --push .

# test the images
docker pull ${REGISTRY}/ros2_base2:latest
docker run \
  --name ros2_base \
  --rm \
  -it \
  --runtime nvidia \
  --network host \
  --gpus all \
  -e DISPLAY \
  ${REGISTRY}/ros2_base2:latest \
  bash

# test images
ros2 run demo_nodes_cpp talker
ros2 run demo_nodes_cpp listener

ROS2 Workspace Docker Container

# build my image
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -f ros2_ws.Dockerfile \
  --build-arg BASE_IMAGE=${REGISTRY}/ros2_base2:latest \
  -t ${REGISTRY}/ros2_ws:latest \
  --push .


docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -f ros2_ws.Dockerfile \
  --build-arg BASE_IMAGE=${REGISTRY}/ros2_base2:latest \
  -t ${REGISTRY}/ros2_ws:latest \
  . --output registry.insecure=true,push=true,type=image

Docker For Development

export JETSON_IP=

function BUILD_AND_RUN(){
  docker -H $JETSON_IP pull ${REGISTRY}/ros2_base2:latest
  docker -H $JETSON_IP buildx build -f ros2_ws.Dockerfile  --build-arg BASE_IMAGE=${REGISTRY}/ros2_base2:latest   -t ${REGISTRY}/ros2_ws:latest .
  docker -H $JETSON_IP run --name ros2_ws --rm -it --runtime nvidia --network host --gpus all --privileged -e DISPLAY -v /dev:/dev -v /proc:/proc -v /sys:/sys ${REGISTRY}/ros2_ws:latest bash -ic "$@"
}
export EXEC_RUN="docker -H $JETSON_IP exec -it ros2_ws /bin/bash -ic"

# Run nodes separately
BUILD_AND_RUN "ros2 run bot_hardware joy"
$EXEC_RUN "ros2 run bot_hardware pca9685"

# run the launch file
BUILD_AND_RUN "ros2 launch bot_hardware manual_control_launch.py"

# local dev env
docker run \
  --name ros2_base \
  --rm \
  -it \
  --runtime nvidia \
  --network host \
  --gpus all \
  --privileged \
  -e DISPLAY \
  -v `pwd`/ros2_ws/src:/root/ros2_ws/src \
  -v `pwd`/ros2_ws_tutorial/src:/root/ros2_ws_tutorial/src \
  ${REGISTRY}/ros2_base2:latest \
  bash 

Docker image with CUDA, ROS2, Realsense

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -f realsense.Dockerfile \
  --build-arg BASE_IMAGE=${REGISTRY}/ros2_base2:latest \
  -t ${REGISTRY}/ros2_realsense:latest \
  --push .

# on jetson run only once
sudo curl https://raw.githubusercontent.com/IntelRealSense/librealsense/master/config/99-realsense-libusb.rules -o /etc/udev/rules.d/99-realsense-libusb.rules \
  && sudo udevadm control --reload-rules \
  && sudo udevadm trigger

docker run \
  --name ros2_realsense \
  --rm \
  -it \
  --runtime nvidia \
  --network host \
  --gpus all \
  --privileged \
  ${REGISTRY}/ros2_realsense:latest \
  bash

# to test run the following in the docker container
rs-depth

ros2 launch realsense2_camera rs_launch.py initial_reset:=true

Joystick

Read more About Joystick in Linux.

Test the joystick

With GUI

sudo apt install -y jstest-gtk
jstest-gtk

Without GUI

jstest /dev/input/js0

With ros

docker -H 192.168.68.68 pull ${REGISTRY}/ros2_base2:latest
docker -H 192.168.68.68 run \
  --rm -it  --runtime nvidia --network host \
  --gpus all --privileged \
  -v /dev:/dev -v /proc:/proc -v /sys:/sys \
  ${REGISTRY}/ros2_base2:latest \
  bash

Run motors

Read more here

docker run \
  --name realsense \
  --rm \
  -it \
  --privileged \
  --network host \
  -e DISPLAY \
  --runtime nvidia \
  --gpus all \
  ${REGISTRY}/ros2_realsense:latest \
  bash

  -v /dev/input:/dev/input \
  -v /dev/v4l:/dev/v4l \
  -v /dev:/dev \
  -v /proc:/proc \
  -v /sys:/sys \
# issue about Jetson.GPIO inside docker: 
# https://forums.developer.nvidia.com/t/jetson-gpio-not-working-on-python-inside-the-container/180435
python -m pip install adafruit-circuitpython-servokit Jetson.GPIO
i2cdetect -y -r 1

PWM Signals

  • PWM Period: 20 ms, PWM Frequency: 50Hz
  • 1ms - 2ms high or Duty cycle: 1% - 10% with 50Hz freq
  • Servo from left to right
  • Throttle form full backward to full forward.
freq = 60
prescaler = 0x66 = 25M / (4096 * frequency)
i2cset -y 1 0x40 0x00 0x90
i2cset -y 1 0x40 0xFE 0x66
i2cset -y 1 0x40 0x00 0xA0

# steering
i2cset -y 1 0x40 0x0A 0x00 && \
  i2cset -y 1 0x40 0x0B 0x00 && \
  i2cset -y 1 0x40 0x0C 0xFA && \
  i2cset -y 1 0x40 0x0D 0x00

i2cset -y 1 0x40 0x0A 0x00 0x00 0x4F 0x01 i

# throttle (85 instead of 6f is good value for test)
i2cset -y 1 0x40 0x06 0x00 && \
i2cset -y 1 0x40 0x07 0x00 && \
i2cset -y 1 0x40 0x08 0x85 && \
i2cset -y 1 0x40 0x09 0x01

i2cset -y 1 0x40 0x06 0x00 0x00 0x4F 0x01 i

About


Languages

Language:C++ 54.2%Language:Dockerfile 37.0%Language:CMake 7.5%Language:Python 1.2%