Bump readme
This commit is contained in:
parent
0dd14bd2fd
commit
824112f661
|
@ -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
|
||||||
|
|
51
README.md
51
README.md
|
@ -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
|
|
||||||
```
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue