Removed desktop specific items
This commit is contained in:
parent
824112f661
commit
1011396402
|
@ -1,3 +0,0 @@
|
||||||
[submodule "PX4-Autopilot"]
|
|
||||||
path = PX4-Autopilot
|
|
||||||
url = https://git.spirirobotics.com/Spiri/PX4-Autopilot.git
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit dd0fb2ef11fc6882c005b16801b1ef47b5d8683b
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
ardupilot:
|
||||||
|
image: git.spirirobotics.com/spiri/ardupilot:spiri-master
|
||||||
|
command: >
|
||||||
|
./Tools/autotest/sim_vehicle.py -v copter --no-rebuild
|
||||||
|
--out=udpin:0.0.0.0:5000
|
||||||
|
--enable-dds
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
mavproxy:
|
||||||
|
image: git.spirirobotics.com/spiri/services-mavproxy:main
|
||||||
|
command: >
|
||||||
|
mavproxy.py --non-interactive
|
||||||
|
--out=udpbcast:192.168.7.255:14560
|
||||||
|
--out=tcpin:0.0.0.0:5760
|
||||||
|
--master=udpout:ardupilot:5000
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 5760:5760
|
||||||
|
|
||||||
|
mavros:
|
||||||
|
#This service bridges our mavlink-based robot-coprosessor into ROS
|
||||||
|
#In this example it connects to a simulated coprocessor.
|
||||||
|
image: git.spirirobotics.com/spiri/services-ros1-mavros:master
|
||||||
|
command: roslaunch mavros px4.launch fcu_url:="udp://:14555@mavproxy:14550" tgt_system:="1"
|
||||||
|
environment:
|
||||||
|
- "ROS_MASTER_URI=http://ros-master:11311"
|
||||||
|
depends_on:
|
||||||
|
ros-master:
|
||||||
|
condition: service_healthy
|
||||||
|
mavproxy:
|
||||||
|
condition: service_started
|
||||||
|
restart: always
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
# cpus: '0.01'
|
||||||
|
memory: 200M
|
||||||
|
ulimits:
|
||||||
|
nofile:
|
||||||
|
soft: 1024
|
||||||
|
hard: 524288
|
||||||
|
|
||||||
|
ros-master:
|
||||||
|
image: git.spirirobotics.com/spiri/services-ros1-core:main
|
||||||
|
command: stdbuf -o L roscore
|
||||||
|
environment:
|
||||||
|
- "ROS_MASTER_URI=http://ros-master:11311"
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:11311:11311"
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 1G
|
||||||
|
# Madness, setting a low ulimit here fixes memory leaks
|
||||||
|
# https://answers.ros.org/question/336963/rosout-high-memory-usage/
|
||||||
|
ulimits:
|
||||||
|
nofile:
|
||||||
|
soft: 1024
|
||||||
|
hard: 524288
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
# Minimal makefile for Sphinx documentation
|
|
||||||
#
|
|
||||||
|
|
||||||
# You can set these variables from the command line, and also
|
|
||||||
# from the environment for the first two.
|
|
||||||
SPHINXOPTS ?=
|
|
||||||
SPHINXBUILD ?= sphinx-build
|
|
||||||
SOURCEDIR = source
|
|
||||||
BUILDDIR = build
|
|
||||||
|
|
||||||
# Put it first so that "make" without argument is like "make help".
|
|
||||||
help:
|
|
||||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
||||||
|
|
||||||
.PHONY: help Makefile
|
|
||||||
|
|
||||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
|
||||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
|
||||||
%: Makefile
|
|
||||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
|
@ -1,11 +0,0 @@
|
||||||
If you have a correctly configured sphinx environment you can build this project
|
|
||||||
using `make html latexpdf`.
|
|
||||||
|
|
||||||
You can also use nektos/act to build this project in the same way our build does.
|
|
||||||
```bash
|
|
||||||
cd ../ #Make sure you're in the project root, you should have a hidden folder
|
|
||||||
# named ./.github/workflows available.
|
|
||||||
act --artifact-server-path ./doc-build
|
|
||||||
```
|
|
||||||
|
|
||||||
Your compiled doc project will now be in the ./doc-build folder.
|
|
|
@ -1,35 +0,0 @@
|
||||||
@ECHO OFF
|
|
||||||
|
|
||||||
pushd %~dp0
|
|
||||||
|
|
||||||
REM Command file for Sphinx documentation
|
|
||||||
|
|
||||||
if "%SPHINXBUILD%" == "" (
|
|
||||||
set SPHINXBUILD=sphinx-build
|
|
||||||
)
|
|
||||||
set SOURCEDIR=source
|
|
||||||
set BUILDDIR=build
|
|
||||||
|
|
||||||
%SPHINXBUILD% >NUL 2>NUL
|
|
||||||
if errorlevel 9009 (
|
|
||||||
echo.
|
|
||||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
|
||||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
|
||||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
|
||||||
echo.may add the Sphinx directory to PATH.
|
|
||||||
echo.
|
|
||||||
echo.If you don't have Sphinx installed, grab it from
|
|
||||||
echo.https://www.sphinx-doc.org/
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1" == "" goto help
|
|
||||||
|
|
||||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
||||||
goto end
|
|
||||||
|
|
||||||
:help
|
|
||||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
||||||
|
|
||||||
:end
|
|
||||||
popd
|
|
|
@ -1,34 +0,0 @@
|
||||||
.wy-side-nav-search {
|
|
||||||
background: #FFFFFF !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.wy-nav-side {
|
|
||||||
background-color: #FFFFFF !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Add borders and box-shadow */
|
|
||||||
.wy-side-nav {
|
|
||||||
border: 1px solid #899CA3 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
width: 100px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wy-menu-vertical a {
|
|
||||||
color: #899CA3 !important; /* Change to your desired color */
|
|
||||||
}
|
|
||||||
|
|
||||||
.document-title {
|
|
||||||
color: #000 !important;
|
|
||||||
font-size: 24px !important;
|
|
||||||
text-transform: uppercase !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-home {
|
|
||||||
font-weight: bold !important;
|
|
||||||
text-transform: uppercase !important;
|
|
||||||
color: #000 !important;
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
# Configuration file for the Sphinx documentation builder.
|
|
||||||
#
|
|
||||||
# For the full list of built-in configuration values, see the documentation:
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
|
||||||
import sphinx_rtd_theme
|
|
||||||
|
|
||||||
project = "spiri-sdk"
|
|
||||||
copyright = "2024, Spiri Robotics"
|
|
||||||
author = "Spiri Robotics"
|
|
||||||
|
|
||||||
html_logo = "logos/SPIRI_STLockup_Mixed_RGB.png" # For HTML output
|
|
||||||
html_logo_width = '200px'
|
|
||||||
latex_logo = "logos/SPIRI_STLockup_Mixed_RGB.png"
|
|
||||||
latex_logo_width = '5cm'
|
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
|
||||||
|
|
||||||
extensions = [
|
|
||||||
"sphinx.ext.duration",
|
|
||||||
"sphinx.ext.doctest",
|
|
||||||
"sphinx.ext.autodoc",
|
|
||||||
"sphinx.ext.autosummary",
|
|
||||||
"sphinx.ext.intersphinx",
|
|
||||||
"sphinx.ext.todo",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
numfig = True
|
|
||||||
|
|
||||||
todo_include_todos = True
|
|
||||||
todo_emit_warnings = True
|
|
||||||
todo_link_only = True
|
|
||||||
|
|
||||||
|
|
||||||
templates_path = ["_templates"]
|
|
||||||
exclude_patterns = []
|
|
||||||
|
|
||||||
# -- Options for HTML output -------------------------------------------------
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
|
||||||
|
|
||||||
html_theme = "sphinx_rtd_theme"
|
|
||||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
|
||||||
|
|
||||||
html_static_path = ['_static']
|
|
||||||
|
|
||||||
html_css_files = [
|
|
||||||
'custom.css',
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
html_theme_options = {
|
|
||||||
'collapse_navigation': True,
|
|
||||||
'sticky_navigation': True,
|
|
||||||
'navigation_depth': 4, #could be set to -1 if we want unlimited depth
|
|
||||||
'includehidden': True,
|
|
||||||
'titles_only': False
|
|
||||||
}
|
|
||||||
|
|
||||||
latex_engine = "xelatex"
|
|
||||||
# Configure LaTeX options for PDF generation
|
|
|
@ -1,20 +0,0 @@
|
||||||
.. spiri-sdk documentation master file, created by
|
|
||||||
sphinx-quickstart on Wed Feb 14 11:51:45 2024.
|
|
||||||
You can adapt this file completely to your liking, but it should at least
|
|
||||||
contain the root `toctree` directive.
|
|
||||||
|
|
||||||
Welcome to spiri-sdk's documentation!
|
|
||||||
============================================
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
:caption: Contents:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Indices and tables
|
|
||||||
==================
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
||||||
* :ref:`modindex`
|
|
||||||
* :ref:`search`
|
|
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
|
@ -1 +0,0 @@
|
||||||
spiri:$5$kasm$bc2Fwutowq1kSiQCv2rNYVgn8.bJeARYMydYCvU1WKC:wo
|
|
|
@ -1,107 +0,0 @@
|
||||||
version: "3.8"
|
|
||||||
|
|
||||||
|
|
||||||
services:
|
|
||||||
mavros:
|
|
||||||
image: git.spirirobotics.com/spiri/services-ros1-mavros:master
|
|
||||||
command: roslaunch mavros px4.launch fcu_url:="udp://:${MAVROS_SIM_FCU_PORT}@127.0.0.1:${MAVROS_SIM_GCS_PORT:-14557}" tgt_system:=${DRONE_SYS_ID:-1}
|
|
||||||
environment:
|
|
||||||
- "ROS_MASTER_URI=http://ros-master:${ROS_MASTER_PORT:-11311}"
|
|
||||||
depends_on:
|
|
||||||
ros-master:
|
|
||||||
condition: service_healthy
|
|
||||||
restart: always
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
memory: 200M
|
|
||||||
ulimits:
|
|
||||||
nofile:
|
|
||||||
soft: 1024
|
|
||||||
hard: 524288
|
|
||||||
ports:
|
|
||||||
- "${MAVROS_SIM_FCU_PORT:-14540}:${MAVROS_SIM_FCU_PORT:-14540}/udp"
|
|
||||||
- "${MAVROS_SIM_GCS_PORT:-14557}:${MAVROS_SIM_GCS_PORT:-14557}/udp"
|
|
||||||
|
|
||||||
ros-master:
|
|
||||||
image: git.spirirobotics.com/spiri/services-ros1-core:main
|
|
||||||
command: stdbuf -o L roscore --port ${ROS_MASTER_PORT:-11311}
|
|
||||||
environment:
|
|
||||||
- "ROS_MASTER_URI=http://ros-master:${ROS_MASTER_PORT:-11311}"
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:${ROS_MASTER_PORT:-11311}:${ROS_MASTER_PORT:-11311}"
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
memory: 1G
|
|
||||||
ulimits:
|
|
||||||
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"
|
|
||||||
#
|
|
||||||
#
|
|
|
@ -1,229 +0,0 @@
|
||||||
#!/bin/env python3
|
|
||||||
import typer
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import contextlib
|
|
||||||
import pathlib
|
|
||||||
import time
|
|
||||||
import functools
|
|
||||||
from typing import List
|
|
||||||
from loguru import logger
|
|
||||||
import sh
|
|
||||||
import atexit
|
|
||||||
|
|
||||||
logger.remove()
|
|
||||||
logger.add(
|
|
||||||
sys.stdout, format="<green>{time}</green> <level>{level}</level> {extra} {message}"
|
|
||||||
)
|
|
||||||
|
|
||||||
px4Path = os.environ.get("SPIRI_SIM_PX4_PATH", "/opt/spiri-sdk/PX4-Autopilot/")
|
|
||||||
logger.info(f"SPIRI_SIM_PX4_PATH={px4Path}")
|
|
||||||
|
|
||||||
app = typer.Typer()
|
|
||||||
|
|
||||||
# This is a list of processes that we need to .kill and .wait for on exit
|
|
||||||
processes = []
|
|
||||||
|
|
||||||
|
|
||||||
class outputLogger:
|
|
||||||
"""
|
|
||||||
Logs command output to loguru
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, name, instance):
|
|
||||||
self.name = name
|
|
||||||
self.instance = instance
|
|
||||||
|
|
||||||
def __call__(self, message):
|
|
||||||
with logger.contextualize(cmd=self.name, instance=self.instance):
|
|
||||||
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)
|
|
||||||
elif message.startswith("ERROR"):
|
|
||||||
message = message.lstrip("ERROR")
|
|
||||||
logger.error(message)
|
|
||||||
elif message.startswith("DEBUG"):
|
|
||||||
message = message.lstrip("DEBUG")
|
|
||||||
logger.debug(message)
|
|
||||||
else:
|
|
||||||
logger.info(message)
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def modified_environ(*remove, **update):
|
|
||||||
"""
|
|
||||||
Temporarily updates the ``os.environ`` dictionary in-place.
|
|
||||||
|
|
||||||
The ``os.environ`` dictionary is updated in-place so that the modification
|
|
||||||
is sure to work in all situations.
|
|
||||||
|
|
||||||
:param remove: Environment variables to remove.
|
|
||||||
:param update: Dictionary of environment variables and values to add/update.
|
|
||||||
"""
|
|
||||||
env = os.environ
|
|
||||||
update = update or {}
|
|
||||||
remove = remove or []
|
|
||||||
|
|
||||||
# List of environment variables being updated or removed.
|
|
||||||
stomped = (set(update.keys()) | set(remove)) & set(env.keys())
|
|
||||||
# Environment variables and values to restore on exit.
|
|
||||||
update_after = {k: env[k] for k in stomped}
|
|
||||||
# Environment variables and values to remove on exit.
|
|
||||||
remove_after = frozenset(k for k in update if k not in env)
|
|
||||||
|
|
||||||
try:
|
|
||||||
env.update(update)
|
|
||||||
[env.pop(k, None) for k in remove]
|
|
||||||
yield
|
|
||||||
finally:
|
|
||||||
env.update(update_after)
|
|
||||||
[env.pop(k) for k in remove_after]
|
|
||||||
|
|
||||||
|
|
||||||
def wait_for_gazebo(timeout=60, interval=1):
|
|
||||||
start_time = time.time()
|
|
||||||
while time.time() - start_time < timeout:
|
|
||||||
try:
|
|
||||||
# Run the 'gz topic list' command
|
|
||||||
topics = sh.gz("topic", "-l").strip()
|
|
||||||
if topics:
|
|
||||||
logger.info("Gazebo Ignition is running.")
|
|
||||||
return True
|
|
||||||
except sh.ErrorReturnCode:
|
|
||||||
# If the command fails, Gazebo might not be running yet
|
|
||||||
pass
|
|
||||||
logger.info(
|
|
||||||
f"Gazebo Ignition is not running. Retrying in {interval} seconds..."
|
|
||||||
)
|
|
||||||
time.sleep(interval)
|
|
||||||
|
|
||||||
logger.error("Timeout reached. Gazebo Ignition is not running.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def wait_for_docker_on_port(port, timeout=60, interval=1):
|
|
||||||
start_time = time.time()
|
|
||||||
while time.time() - start_time < timeout:
|
|
||||||
try:
|
|
||||||
# Check if there's a working docker daemon listening at port
|
|
||||||
with modified_environ(DOCKER_HOST=f"tcp://localhost:{port}"):
|
|
||||||
sh.docker("version")
|
|
||||||
except sh.ErrorReturnCode:
|
|
||||||
# If the command fails, Gazebo might not be running yet
|
|
||||||
pass
|
|
||||||
logger.info(f"Docker port is not running. Retrying in {interval} seconds...")
|
|
||||||
time.sleep(interval)
|
|
||||||
logger.error("Timeout reached. Docker port is not running.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
@app.command()
|
|
||||||
def start(sys_id: int = 1, extra_apps: List[pathlib.Path] = []):
|
|
||||||
"""Starts the simulated drone with a given sys_id,
|
|
||||||
each drone must have it's own unique ID.
|
|
||||||
"""
|
|
||||||
if sys_id < 1 or sys_id > 254:
|
|
||||||
logger.error("sys_id must be between 1 and 254")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
with logger.contextualize(syd_id=sys_id):
|
|
||||||
DOCKER_INSTANCE = (str(2375 + sys_id),)
|
|
||||||
with modified_environ(
|
|
||||||
# PX4_SIM_MODEL=os.environ.get("PX4_SIM_MODEL") or "gz_x500",
|
|
||||||
# ToDo: pose is not passed to gazebo classic
|
|
||||||
PX4_GZ_MODEL_POSE=os.environ.get("PX4_GZ_MODEL_POSE") or f"0,{(sys_id-1)}",
|
|
||||||
PX4_INSTANCE="intance_id",
|
|
||||||
DOCKER_INSTANCE=DOCKER_INSTANCE,
|
|
||||||
ROS_MASTER_PORT=str(11310 + sys_id),
|
|
||||||
MAVROS_SIM_GCS_PORT=str(14556 + sys_id),
|
|
||||||
MAVROS_SIM_FCU_PORT=str(14539 + sys_id),
|
|
||||||
DRONE_SYS_ID=str(sys_id),
|
|
||||||
):
|
|
||||||
logger.info("Starting drone simulation")
|
|
||||||
# Run the make px4_sitl gazebo-classic command
|
|
||||||
px4_command = sh.make(
|
|
||||||
"px4_sitl",
|
|
||||||
"gazebo-classic_mu",
|
|
||||||
_bg=True,
|
|
||||||
_out=outputLogger("px4", sys_id),
|
|
||||||
_cwd=px4Path,
|
|
||||||
)
|
|
||||||
processes.append(px4_command)
|
|
||||||
logger.info("Starting drone docker instance")
|
|
||||||
# Here we start a docker-in-docker instance with the DOCKER_INSTANCE port exposed to localhost
|
|
||||||
dockerinstance = sh.docker(
|
|
||||||
"run",
|
|
||||||
"--privileged",
|
|
||||||
"--name",
|
|
||||||
f"simulated_robot_{sys_id}_docker",
|
|
||||||
"-p",
|
|
||||||
f"localhost:{DOCKER_INSTANCE}:{DOCKER_INSTANCE}",
|
|
||||||
# Run the docker command in forground to capture the output
|
|
||||||
"docker:dind",
|
|
||||||
_bg=True,
|
|
||||||
_out=outputLogger("docker", sys_id),
|
|
||||||
)
|
|
||||||
processes.append(dockerinstance)
|
|
||||||
# Wait for the docker daemon to start
|
|
||||||
logger.info(f"Waiting for docker daemon on port {DOCKER_INSTANCE}")
|
|
||||||
wait_for_docker_on_port(DOCKER_INSTANCE)
|
|
||||||
|
|
||||||
logger.info("Starting drone stack, this may take some time")
|
|
||||||
docker_stack = sh.docker.compose(
|
|
||||||
"--project-name",
|
|
||||||
f"simulated_robot_{sys_id}",
|
|
||||||
"up",
|
|
||||||
_out=outputLogger("docker_stack", sys_id),
|
|
||||||
_err=sys.stderr,
|
|
||||||
_bg=True,
|
|
||||||
)
|
|
||||||
processes.append(docker_stack)
|
|
||||||
for extra_app in extra_apps:
|
|
||||||
logger.info(f"Starting app {extra_app}, this may take some time")
|
|
||||||
app_name = extra_app.stem
|
|
||||||
app_stack = sh.docker.compose(
|
|
||||||
"--project-name",
|
|
||||||
f"simulated_robot_{sys_id}_{app_name}",
|
|
||||||
"up",
|
|
||||||
_out=outputLogger(app_name, sys_id),
|
|
||||||
_err=sys.stderr,
|
|
||||||
_bg=True,
|
|
||||||
)
|
|
||||||
processes.append(app_stack)
|
|
||||||
|
|
||||||
|
|
||||||
@app.command()
|
|
||||||
def start_group(
|
|
||||||
count: int = typer.Argument(min=1, max=10), extra_apps: List[pathlib.Path] = []
|
|
||||||
):
|
|
||||||
"""Start a group of robots"""
|
|
||||||
for i in range(count):
|
|
||||||
logger.info(f"start robot {i}")
|
|
||||||
start(sys_id=i + 1, extra_apps=extra_apps)
|
|
||||||
if i == 0:
|
|
||||||
wait_for_gazebo()
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup():
|
|
||||||
# Wait for all subprocesses to exit
|
|
||||||
logger.info("Waiting for commands to exit")
|
|
||||||
print(processes)
|
|
||||||
for waitable in processes:
|
|
||||||
waitable.kill()
|
|
||||||
waitable.wait()
|
|
||||||
|
|
||||||
|
|
||||||
atexit.register(cleanup)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
try:
|
|
||||||
app()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
logger.info("KeyboardInterrupt caught, exiting...")
|
|
||||||
cleanup()
|
|
||||||
sys.exit(0)
|
|
|
@ -1,31 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Function to extract the output file from arguments
|
|
||||||
extract_output_file() {
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
key="$1"
|
|
||||||
case $key in
|
|
||||||
-o | --output)
|
|
||||||
output_file="$2"
|
|
||||||
shift # past argument
|
|
||||||
shift # past value
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
shift # past argument
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Extract the -o argument
|
|
||||||
extract_output_file "$@"
|
|
||||||
|
|
||||||
# Run the docker command
|
|
||||||
#docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock --privileged -v "$PWD":/d2vm -w /d2vm vmutil "$@"
|
|
||||||
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock --privileged -v "$PWD":/d2vm -w /d2vm git.spirirobotics.com/spiri/utils-docker_to_ovf:2024-05-21 "$@"
|
|
||||||
|
|
||||||
# Change the ownership of the output file to the current user
|
|
||||||
if [[ -n "$output_file" ]]; then
|
|
||||||
echo "Setting permissions on file"
|
|
||||||
sudo chown $(whoami) "$output_file"
|
|
||||||
fi
|
|
Loading…
Reference in New Issue