5. Simulation and the Digital Double¶
In this tutorial we will cover how a UAV simulation works and introduce Gazebo, the physics simulator that we use in Starling. By the end you should know the different parts of the simulator and how to run it locally.
5.1 UAV Simulation¶
Often UAV Simulation is solely focused on trying to recreate the dynamics of UAV flight. In Starling however, we have decided to leave that to the physics simulator experts, and instead focus on the simulation of systems and architecture involved with UAV flight. This is with the goal to make transferring control from simulation to real hardware as streamlined and straight forward as possible.
In the previous section on UAV control, we said that a core part of UAV control is the Autopilot. It's a physical computer which takes sensor inputs to create motor voltages to spin the motor. To recreate this as closely as possible, we'd like to simulate all of this to ensure that the operation of the UAV is as realistic as possible.
5.1.1 Software in the loop¶
Thankfully, both Ardupilot and SITL can be run as software in the loop or SITL, a simulation where the flight stack that would run on the autopilot, runs on your local computer.
Simulators allow flight code to control a computer modelled vehicle in a simulated "world". You can interact with this vehicle just as you might with a real vehicle, using QGroundControl, an offboard API such as ROS, or a radio controller/gamepad.
Simulation is a quick, easy, and most importantly, safe way to test changes to your controller before attempting to fly in the real world. It is also a good way to start flying when you haven't yet got a vehicle to experiment with or don't want to risk damaging it.
From a Starling perspective, the MAVROS container does not distinguish between running on a real vehicle or running on SITL as both still speak the same version of MAVLINK. The MAVROS container internally handles connecting to the correct source.
5.1.2 Gazebo¶
Alongside the SITL, a physics engine is also required for it to run against. Together, the simulation is often performed in lockstep where the SITL will generate a motion in one step based on the simulator state, followed by the simulator advancing by one step based on that motion.
In Starling, we primarily use the Gazebo physics and visualisation engine as it is one of the most commonly out there currently in the robotics space.
Starling is designed with simulator modularity in mind, and it's hoped that in the future, other simulators will also be supported!
Starling provides a number of containers which have Gazebo pre configured and installed, along with a web based interface for viewing the simulation in progress. In this tutorial, we will be using one container in particular.
5.2 BRL Digital Double¶
As well as simulating the vehicles themselves, it is also important to simulate the environment in which we are operating. For this tutorial we will be flying in the Bristol Robotics Laboratory (BRL) flight arena, and therefore we provide a digital double of that space here. It is contained in the following container:
uobflightlabstarling/uobflightlabstarling/starling-sim-iris-px4-flightarena:latest
This will place you into a space where the exact measurements match the real world version of the flight arena.
Flight arena is 15.6m x 11.8m x 5m (x, y, z) tall, origin is offset by (0.5, 0.7, 0.0) from space center. The coordinate space is: x positive is up and y postive is left (w.r.t the ascii figure).
_________________________________
| |
| ^ |
| |x |
|_ <-- |
|_| y
| | |
|__|____________ |
|___|___|___|___| |
| _____ _____|
|_ _____ ______|_____|_____|
5.3 Running the local simulator¶
We can now run the full simulation of a single UAV in the flight arena locally on your machine.
Go to your new Starling application, and you should see a deployment folder. Inside there is a docker-compose.yml
file. A docker compose file is used to configure the running of multiple containers together, instead of having to run a bunch of them manually. To ensure that you have the latest containers, we should pull all of the used ones from Docker Hub:
docker-compose -f deployment/docker-compose.yml pull
This can take a while, especially if your internet connection is slow.
Once downloaded, you can then run the simulator stack with the up
command:
docker-compose -f deployment/docker-compose.yml up
If you have downloaded and installed the Starling CLI from Murmuration, you could also run the following (it does the same thing under the hood):
starling deploy -f deployment/docker-compose.yml --pull start
Note: depending on what you also have running, you may receive a port in use error. If it is the port for simhost (8080), rosbridge (9090) or the UI (3000), you can change the value of
<local_port>:<container_port>
in thedocker-compose.yml
file.Note: Stop the simulator with
ctrl+c
Once you have run the above command, you should see a lot of text fly by in the terminal! Hopefully none of it is red...
To access the simulator, go to localhost:8080
.
To access the simple UI, go to localhost:3000
.
The UI contains a simple Go and Stop button which both send topics of /mission_start
and /emergency_stop
respectively.
5.4 What is in the local simulation¶
Awesome! You now have the local simulator running... but what have you actually run? Let's take you through the docker-compose
file:
- uobflightlabstarling/starling-sim-iris-px4-flightarena: This is the Gazebo image which contains the model of the flying arena and the model of the UAV. On startup, it spawns the arena and spawns a single vehicle into it.
- uobflightlabstarling/starling-sim-px4-sitl: The container which runs the PX4 Software In The Loop mentioned earlier. Through the environment variables, it knows to connect to the gazebo container for physics, and then knows to expect the mavros container for offboard commands.
- uobflightlabstarling/starling-mavros: The container which runs mavros mentioned in a previous tutorial. It serves as the connection point between the SITL and your own controller code.
- uobflightlabstarling/rosbridge-suite: The gateway for web ros applications like the UI to connect to ROS.
- uobflightlabstarling/starling-ui-example: The example web application with a simple interface.
5.5 Inspecting the local simulation¶
To verify the functionality of the simulator, we can have a look at some of the ROS Topics that are being sent around. We do this by exec
-ing into one of the containers:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca5384b42f41 uobflightlabstarling/starling-mavros:nightly "/ros_entrypoint.sh …" 8 seconds ago Up 7 seconds 0.0.0.0:5760->5760/tcp deployment_mavros_1
633d71686da7 uobflightlabstarling/starling-sim-px4-sitl:nightly "/entrypoint.sh /bin…" 8 seconds ago Up 7 seconds 0.0.0.0:18570->18570/udp deployment_sitl_1
a462241ba16f uobflightlabstarling/starling-sim-iris-px4-flightarena:latest "/entrypoint.sh ros2…" 9 seconds ago Up 8 seconds 7681/tcp, 11345/tcp, 0.0.0.0:8080->8080/tcp deployment_simhost_1
51adc525e085 uobflightlabstarling/starling-ui-example:latest "/ros_entrypoint.sh …" 29 minutes ago Up 8 seconds 9090/tcp, 0.0.0.0:3001->3000/tcp deployment_starling-ui-example_1
f1208345c980 uobflightlabstarling/rosbridge-suite:latest "/ros_entrypoint.sh …" 36 minutes ago Up 9 seconds 0.0.0.0:9090->9090/tcp deployment_rosbridge-suite_1
Choosing the starling-mavros
container, we can exec into that and run the following:
docker exec -it ca5384b42f41 bash
root@ca5384b42f41:/ros_ws# . /opt/ros/foxy/setup.bash
root@ca5384b42f41:/ros_ws# ros2 topic list
/client_count
/clock
/connected_clients
/emergency_stop
/link_states
/model_states
/parameter_events
/performance_metrics
/rosout
/vehicle_1/mavlink/from
/vehicle_1/mavlink/to
/vehicle_1/mavros/battery
/vehicle_1/mavros/distance_sensor/hrlv_ez4_sonar
/vehicle_1/mavros/distance_sensor/lidarlite_laser
/vehicle_1/mavros/distance_sensor/rangefinder
/vehicle_1/mavros/distance_sensor/temperature
/vehicle_1/mavros/extended_state
/vehicle_1/mavros/global_position/global
/vehicle_1/mavros/image/camera_image
/vehicle_1/mavros/imu/data
/vehicle_1/mavros/local_position/accel
/vehicle_1/mavros/local_position/odom
/vehicle_1/mavros/local_position/pose
/vehicle_1/mavros/local_position/pose_cov
/vehicle_1/mavros/local_position/velocity_body
/vehicle_1/mavros/local_position/velocity_body_cov
/vehicle_1/mavros/local_position/velocity_local
/vehicle_1/mavros/manual_control/control
/vehicle_1/mavros/manual_control/send
/vehicle_1/mavros/mission/reached
/vehicle_1/mavros/mission/waypoints
/vehicle_1/mavros/px4flow/ground_distance
/vehicle_1/mavros/px4flow/raw/optical_flow_rad
/vehicle_1/mavros/safety_area
/vehicle_1/mavros/setpoint_accel/accel
/vehicle_1/mavros/setpoint_attitude/attitude
/vehicle_1/mavros/setpoint_attitude/cmd_vel
/vehicle_1/mavros/setpoint_attitude/thrust
/vehicle_1/mavros/setpoint_position/global
/vehicle_1/mavros/setpoint_position/global_to_local
/vehicle_1/mavros/setpoint_position/local
/vehicle_1/mavros/setpoint_raw/attitude
/vehicle_1/mavros/setpoint_raw/global
/vehicle_1/mavros/setpoint_raw/local
/vehicle_1/mavros/setpoint_velocity/cmd_vel_unstamped
/vehicle_1/mavros/state
/vehicle_1/mavros/vision_pose/pose
/vehicle_1/mavros/vision_pose/pose_cov
/vehicle_1/mavros/vision_speed/speed_twist
/vehicle_1/mavros/vision_speed/speed_vector
This lists a list of all the topics currently being broadcast onto the system. Similarly, we can inspect the current list of nodes:
root@ca5384b42f41:/ros_ws# ros2 node list
/gazebo
/gazebo_vehicle_state_plugin
/motion_tracker_sim
/rosapi
/rosapi
/rosbridge_websocket
/vehicle_1/estop
/vehicle_1/ros_bridge
and so on. We can also have a look at some of the topics. For example, if we wanted to look at the state of vehicle_1
, we would have a look at /vehicle_1/mavros/local_position/pose
(Press ctrl+c
to stop the stream).
root@ca5384b42f41:/ros_ws# ros2 topic echo /vehicle_1/mavros/local_position/pose
---
header:
stamp:
sec: 1655741007
nanosec: 589603584
frame_id: map
pose:
position:
x: -0.010252323932945728
y: -0.025252731516957283
z: -0.019200336188077927
orientation:
x: -0.0019689216589022533
y: -0.0020565663184938785
z: 0.0005801513697525905
w: -0.9999958103477264
---
header:
stamp:
sec: 1655741007
nanosec: 617603584
frame_id: map
pose:
position:
x: -0.01022176630795002
y: -0.02509368769824505
z: -0.018872130662202835
orientation:
x: -0.0019977603981865205
y: -0.0021082978655832646
z: 0.0006137002611672492
w: -0.9999956417603324
---
...
Have a play around and investigate the other topics!
Finally to stop the simulator, you can simply run ctrl+c
in the terminal running the simulator.
5.6 Next Steps¶
This tutorial should have introduced you to how UAV simulation works and the Gazebo simulator we use in Starling. It's also shown you how to run the simulator. You'll need to use this to test the controller you will be developing in the next section.