From c751d97503e827e6d15d5590c798e5f52b24a4a4 Mon Sep 17 00:00:00 2001 From: Alex Davies Date: Fri, 31 May 2024 11:58:09 -0300 Subject: [PATCH] Custom simulator management command, because I have given up --- Dockerfile | 13 +- README.md | 12 +- .../simulated-drone/docker-compose.yaml | 135 +++++++++--------- skel/Desktop/simulated-drone/sim_drone.py | 58 ++++++++ 4 files changed, 133 insertions(+), 85 deletions(-) create mode 100755 skel/Desktop/simulated-drone/sim_drone.py diff --git a/Dockerfile b/Dockerfile index 4d0b891..c272b22 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,14 +6,16 @@ COPY --link --from=git.spirirobotics.com/spiri/gazebo-resources:latest /plugins RUN apt-get update && apt-get upgrade --yes -#Install base packages for distrobox -# RUN apt-get install --yes bc bzip2 chpasswd curl diff find findmnt gpg hostname less lsof man mount passwd pigz pinentry ping ps rsync script ssh sudo time tree umount unzip useradd wc wget xauth zip +RUN apt-get install --yes gz-garden WORKDIR /opt/spiri-sdk RUN git clone --depth 1 -b v1.15.0-beta1 https://github.com/PX4/PX4-Autopilot.git --recursive WORKDIR /opt/spiri-sdk/PX4-Autopilot/ -RUN DONT_RUN=1 make px4_sitl gazebo-classic +#Precompile px4 +RUN make px4_sitl_default + +RUN pip3 install typer-slim loguru sh RUN apt-get install --yes virtualbox-guest-dkms virtualbox-guest-utils spice-vdagent qemu-guest-agent RUN apt-get install --yes docker-compose-v2 firefox @@ -23,10 +25,9 @@ RUN apt-get install --yes --no-install-recommends lubuntu-desktop sddm COPY ./skel/ /opt/spiri-sdk/user-home-skeleton/ RUN cp -r /opt/spiri-sdk/user-home-skeleton/* /etc/skel/ -RUN useradd -m -s /bin/bash spiri && echo 'spiri:spiri-friend' | chpasswd +RUN usermod -l spiri -m -d /home/spiri user +RUN echo 'spiri:spiri-friend' | chpasswd RUN usermod -aG sudo,docker spiri -RUN userdel user - #Install vscodium, a vscode fork with no telemetry and a worse package store # RUN sh -c "curl -fSsL https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg | sudo gpg --dearmor | sudo tee /usr/share/keyrings/vscodium.gpg > /dev/null" diff --git a/README.md b/README.md index 34522bf..4ae9b2f 100644 --- a/README.md +++ b/README.md @@ -12,23 +12,13 @@ Advanced users can also use the SDK as a docker image. It pairs well with integrate it with their existing linux workflows. ```bash -distrobox create --image git.spirirobotics.com/spiri/spiri-sdk-desktop:master +distrobox create --unshare-all --init --image git.spirirobotics.com/spiri/spiri-sdk-desktop:master distrobox enter spiri-sdk-desktop-main #You can optionally copy the standard SDK setup from /opt/spiri-sdk/user-home-skeleton/ # cp -r /opt/spiri-sdk/user-home-skeleton/* ~/ cd /opt/spiri-sdk/PX4-Autopilot/ make px4_sitl gazebo-classic #Start the simulator ``` - -You can also run a full init system, and it's own docker container, using - -```bash -distrobox create --root \ - --image git.spirirobotics.com/spiri/spiri-sdk-desktop:master \ - --init \ - --unshare-all -``` - # Building ```bash diff --git a/skel/Desktop/simulated-drone/docker-compose.yaml b/skel/Desktop/simulated-drone/docker-compose.yaml index dcd944c..ff4303a 100644 --- a/skel/Desktop/simulated-drone/docker-compose.yaml +++ b/skel/Desktop/simulated-drone/docker-compose.yaml @@ -1,71 +1,7 @@ version: "3.8" + services: - - gscam: - image: git.spirirobotics.com/spiri/services-ros1-gscam_all_in_one:main - runtime: nvidia - environment: - ROS_MASTER_URI: http://localhost:11311 - ROS_LOG_LEVEL: DEBUG - PORT_GSCAM_CONFIG: > - nvarguscamerasrc sensor-id=0 aelock=true awblock=true ! video/x-raw(memory:NVMM), width=(int)$(arg width), height=(int)$(arg height), format=(string)NV12, framerate=(fraction)$(arg fps)/1 ! nvvidconv flip-method=0 ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR - STARBOARD_GSCAM_CONFIG: > - nvarguscamerasrc sensor-id=1 aelock=true awblock=true ! video/x-raw(memory:NVMM), width=(int)$(arg width), height=(int)$(arg height), format=(string)NV12, framerate=(fraction)$(arg fps)/1 ! nvvidconv flip-method=0 ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR - volumes: - - /tmp/argus_socket:/tmp/argus_socket - - udp-stream: - image: git.spirirobotics.com/spiri/services-ros1-gscam_all_in_one:main - privileged: true - runtime: nvidia - network_mode: host - environment: - DISPLAY: ":0" - volumes: - - /tmp/argus_socket:/tmp/argus_socket - - /tmp/.X11-unix:/tmp/.X11-unix - - /var/run/xauth/:/var/run/xauth/ - command: > - gst-launch-1.0 - nvarguscamerasrc sensor-id=0 - ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)60/1' - ! tee name=raw - raw. ! queue - ! nvegltransform ! nveglglessink sync=false async=false - raw. ! queue - ! videorate max-rate=30 drop-only=true - ! queue max-size-buffers=3 leaky=downstream - ! nvv4l2h265enc - bitrate=2000000 - iframeinterval=300 - vbv-size=33333 - insert-sps-pps=true - control-rate=constant_bitrate - profile=Main - num-B-Frames=0 - ratecontrol-enable=true - preset-level=UltraFastPreset - EnableTwopassCBR=false - maxperf-enable=true - ! rtph265pay name=pay0 pt=96 config-interval=-1 mtu=1400 - ! udpsink host=192.168.1.100 auto-multicast=false port=5600 sync=false async=false - - mavproxy: - image: git.spirirobotics.com/spiri/services-mavproxy:main - command: > - mavproxy.py --non-interactive - --out=udpin:0.0.0.0:14551 - --out=udpin:0.0.0.0:14550 - --out=tcpin:0.0.0.0:5760 - --master=/dev/ttyTHS2 --baudrate 921600 - restart: always - devices: - - "/dev/ttyTHS2:/dev/ttyTHS2" - ports: - - "14550:14550/udp" - - "5760:5760/tcp" - mavros: #This service bridges our mavlink-based robot-coprosessor into ROS #In this example it connects to a simulated coprocessor. @@ -76,8 +12,6 @@ services: depends_on: ros-master: condition: service_healthy - mavproxy: - condition: service_started restart: always deploy: resources: @@ -88,7 +22,6 @@ services: nofile: soft: 1024 hard: 524288 - ros-master: image: git.spirirobotics.com/spiri/services-ros1-core:main command: stdbuf -o L roscore @@ -107,3 +40,69 @@ services: nofile: soft: 1024 hard: 524288 + + # gscam: + # image: git.spirirobotics.com/spiri/services-ros1-gscam_all_in_one:main + # runtime: nvidia + # environment: + # ROS_MASTER_URI: http://localhost:11311 + # ROS_LOG_LEVEL: DEBUG + # PORT_GSCAM_CONFIG: > + # nvarguscamerasrc sensor-id=0 aelock=true awblock=true ! video/x-raw(memory:NVMM), width=(int)$(arg width), height=(int)$(arg height), format=(string)NV12, framerate=(fraction)$(arg fps)/1 ! nvvidconv flip-method=0 ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR + # STARBOARD_GSCAM_CONFIG: > + # nvarguscamerasrc sensor-id=1 aelock=true awblock=true ! video/x-raw(memory:NVMM), width=(int)$(arg width), height=(int)$(arg height), format=(string)NV12, framerate=(fraction)$(arg fps)/1 ! nvvidconv flip-method=0 ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR + # volumes: + # - /tmp/argus_socket:/tmp/argus_socket + # + # udp-stream: + # image: git.spirirobotics.com/spiri/services-ros1-gscam_all_in_one:main + # privileged: true + # runtime: nvidia + # network_mode: host + # environment: + # DISPLAY: ":0" + # volumes: + # - /tmp/argus_socket:/tmp/argus_socket + # - /tmp/.X11-unix:/tmp/.X11-unix + # - /var/run/xauth/:/var/run/xauth/ + # command: > + # gst-launch-1.0 + # nvarguscamerasrc sensor-id=0 + # ! 'video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, format=(string)NV12, framerate=(fraction)60/1' + # ! tee name=raw + # raw. ! queue + # ! nvegltransform ! nveglglessink sync=false async=false + # raw. ! queue + # ! videorate max-rate=30 drop-only=true + # ! queue max-size-buffers=3 leaky=downstream + # ! nvv4l2h265enc + # bitrate=2000000 + # iframeinterval=300 + # vbv-size=33333 + # insert-sps-pps=true + # control-rate=constant_bitrate + # profile=Main + # num-B-Frames=0 + # ratecontrol-enable=true + # preset-level=UltraFastPreset + # EnableTwopassCBR=false + # maxperf-enable=true + # ! rtph265pay name=pay0 pt=96 config-interval=-1 mtu=1400 + # ! udpsink host=192.168.1.100 auto-multicast=false port=5600 sync=false async=false + # + # mavproxy: + # image: git.spirirobotics.com/spiri/services-mavproxy:main + # command: > + # mavproxy.py --non-interactive + # --out=udpin:0.0.0.0:14551 + # --out=udpin:0.0.0.0:14550 + # --out=tcpin:0.0.0.0:5760 + # --master=/dev/ttyTHS2 --baudrate 921600 + # restart: always + # devices: + # - "/dev/ttyTHS2:/dev/ttyTHS2" + # ports: + # - "14550:14550/udp" + # - "5760:5760/tcp" + # + # diff --git a/skel/Desktop/simulated-drone/sim_drone.py b/skel/Desktop/simulated-drone/sim_drone.py new file mode 100755 index 0000000..4b2ee50 --- /dev/null +++ b/skel/Desktop/simulated-drone/sim_drone.py @@ -0,0 +1,58 @@ +#!/bin/env python3 +import typer, os, sys +from loguru import logger +import sh +import atexit + +logger.remove() +logger.add(sys.stdout, format="{time} {level} {extra} {message}") + +px4Path = os.environ.get("SPIRI_SIM_PX4_PATH","/opt/spiri-sdk/PX4-Autopilot/build/px4_sitl_default/bin/px4") +logger.info(f"SPIRI_SIM_PX4_PATH={px4Path}") +px4 = sh.Command(px4Path) + +app = typer.Typer() + +class outputLogger(): + """ + Logs command output to loguru + """ + def __init__(self, name): + self.name=name + def __call__(self, message): + with logger.contextualize(cmd=self.name): + if message.endswith('\n'): + message = message[:-1] + #ToDo, this doesn't work because the output is coloured + if message.startswith('INFO'): + message=message.lstrip("INFO") + logger.info(message) + elif message.startswith('WARN'): + message=message.lstrip("WARN") + logger.warning(message) + else: + logger.info(message) + +@app.command() +def start(sys_id: int =1): + """Starts the simulated drone with a given sys_id, + each drone must have it's own unique ID. + """ + instance_id = sys_id-1 #PX4 will add 1 to the instance ID to get sysID + px4Instance = px4(i=instance_id, + _out=outputLogger("px4"), _bg=True) + atexit.register(lambda: px4Instance.kill()) + docker_stack = sh.docker.compose( + "--project-name", f"simulated_robot_{sys_id}", + "up", + _out=outputLogger("docker_stack"), + _bg=True + ) + atexit.register(lambda: docker_stack.kill()) + px4Instance.wait() + docker_stack.wait() + + + +if __name__ == "__main__": + app()