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()