Bump readme
Build Docs / build (push) Waiting to run Details
Create and publish a Docker image / build-and-push-image (push) Has been cancelled Details

This commit is contained in:
Alex Davies 2024-09-17 12:27:20 -03:00
parent 0dd14bd2fd
commit 824112f661
3 changed files with 44 additions and 50 deletions

View File

@ -14,7 +14,7 @@ RUN apt-get clean
RUN apt-get update && apt-get upgrade --yes RUN apt-get update && apt-get upgrade --yes
#RUN apt-get install --yes gz-garden #RUN apt-get install --yes gz-garden
RUN apt-get remove gz-garden RUN apt-get remove gz-garden mutter
RUN apt-get install --yes ros-noetic-desktop gazebo11 libgazebo11 libgazebo11-dev RUN apt-get install --yes ros-noetic-desktop gazebo11 libgazebo11 libgazebo11-dev
#Install ROS #Install ROS

View File

@ -1,50 +1,3 @@
# Ways of running New SDK
There are two main ways of running this software. toDo, usage instructions
Most users are recomended to install [VirtualBox](https://www.virtualbox.org/), create a new
VM, and use the supplied VDI as the disk image. You will likely want
to increase memory limits and CPU count above the default.
Advanced users can also use the SDK as a docker image. It pairs well with
[distrobox](https://github.com/89luca89/distrobox) to better
integrate it with their existing linux workflows.
```bash
distrobox create --image git.spirirobotics.com/spiri/spiri-sdk-desktop:master
distrobox enter spiri-sdk-desktop-master
cp -r /opt/spiri-sdk/user-home-skeleton/* ~/
cd ~/Desktop/simulated-drone/
./sim_drone.py launch
```
# Usage
Each drone has it's own ros master, you can specify a ros master by adding a sys_id to your port
To launch the drone, run the command `sim_drone.py start-group 2`. For more detailed information user
the `--help` command. You must run the command from inside a folder with a compliant dockerfile.
If using the VM there should be one on your desktop, if not you can run `cp -r /opt/spiri-sdk/user-home-skeleton/ ~/`
and all relevent development resources will be added to your home folder.
```bash
ROS_MASTER_URI=http://localhost:11311 rostopic list #Drone with sys_id 1
ROS_MASTER_URI=http://localhost:11312 rostopic list #Drone with sys_id 2
```
# Building
```bash
#Note that because this is running in a container, the -o output flag must be relative to the current directory.
# We mount the current working directory in the docker container as part of this script.
./virtualize.sh build ./ -s 100gb -o sdk.vdi
```
For testing the VM, I use the following
```bash
./virtualize.sh build ./ -s 100gb -o sdk.qcow2
qemu-system-x86_64 -display default,show-cursor=on -enable-kvm -device virtio-gpu -m 4g -smp 4 -hda sdk.qcow2
```

View File

@ -107,22 +107,44 @@ def wait_for_gazebo(timeout=60, interval=1):
return False 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() @app.command()
def start(sys_id: int = 1, extra_apps: List[pathlib.Path] = []): def start(sys_id: int = 1, extra_apps: List[pathlib.Path] = []):
"""Starts the simulated drone with a given sys_id, """Starts the simulated drone with a given sys_id,
each drone must have it's own unique 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): with logger.contextualize(syd_id=sys_id):
DOCKER_INSTANCE = (str(2375 + sys_id),)
with modified_environ( with modified_environ(
# PX4_SIM_MODEL=os.environ.get("PX4_SIM_MODEL") or "gz_x500", # PX4_SIM_MODEL=os.environ.get("PX4_SIM_MODEL") or "gz_x500",
# ToDo: pose is not passed to gazebo classic # 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_GZ_MODEL_POSE=os.environ.get("PX4_GZ_MODEL_POSE") or f"0,{(sys_id-1)}",
PX4_INSTANCE="intance_id", PX4_INSTANCE="intance_id",
DOCKER_INSTANCE=DOCKER_INSTANCE,
ROS_MASTER_PORT=str(11310 + sys_id), ROS_MASTER_PORT=str(11310 + sys_id),
MAVROS_SIM_GCS_PORT=str(14556 + sys_id), MAVROS_SIM_GCS_PORT=str(14556 + sys_id),
MAVROS_SIM_FCU_PORT=str(14539 + sys_id), MAVROS_SIM_FCU_PORT=str(14539 + sys_id),
DRONE_SYS_ID=str(sys_id), DRONE_SYS_ID=str(sys_id),
): ):
logger.info("Starting drone simulation")
# Run the make px4_sitl gazebo-classic command # Run the make px4_sitl gazebo-classic command
px4_command = sh.make( px4_command = sh.make(
"px4_sitl", "px4_sitl",
@ -132,6 +154,25 @@ def start(sys_id: int = 1, extra_apps: List[pathlib.Path] = []):
_cwd=px4Path, _cwd=px4Path,
) )
processes.append(px4_command) 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") logger.info("Starting drone stack, this may take some time")
docker_stack = sh.docker.compose( docker_stack = sh.docker.compose(
"--project-name", "--project-name",