Skip to content

Commit e865720

Browse files
committed
feat: simulation 'big picture' architecture section
1 parent 1d00ebf commit e865720

2 files changed

Lines changed: 156 additions & 9 deletions

File tree

Lines changed: 153 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
# Simulator Architecture
22

3-
## Architecture of the SIL Simulation
3+
This document describes the architecture of the simulator code.
4+
It describes each node's function and role in the simulator, as well as how different visualizers require different configurations of nodes.
45

5-
!!! danger "TODO"
6+
It also details what users would need to do to use their own visualizer with `rosflight_sim`.
7+
8+
!!! note "Prerequisites"
9+
10+
This guide assumes that you have installed and set up the ROSflightSim, as detailed in [the tutorials](../tutorials/setting-up-rosflight-sim.md).
11+
12+
13+
## Big Picture - Sim Architecture
614

15+
!!! danger "TODO"
716
continue here... This page is still under construction. Check back soon!
817

9-
!!! TODO
10-
Make a figure of the new architecture. Maybe make it be a GIF? We could replace the table below
18+
### Design Philosophy
19+
20+
The design goal of the simulator is to mimic hardware as closely as possible.
21+
This means that the same code that flies on hardware should also be flying the aircraft in sim.
22+
This is a **essential** to ensure that the transition from sim to hardware goes as smoothly as possible.
23+
24+
To that end, each module in the simulator mimics a physical module on the aircraft or in the real world.
25+
For example, the physical sensors are replaced with a "simulated sensors" module, and the physical dynamics are replaced by a "dynamics" module.
26+
Apart from these simulated modules, **the rest of the ROSflight code is the same between hardware and simulation**.
1127

12-
To best mimic the hardware experience of ROSflight, the SIL plugin for Gazebo actually implements the firmware source code as a library.
13-
We just implemented a different "board layer" which uses gazebo instead of hardware calls for things like `imu_read()` and `pwm_write()`.
28+
To best mimic the hardware experience of ROSflight, the SIL plugin actually implements the firmware source code as a library.
29+
We just implemented a different "board layer" which uses the `sil_board` functions instead of hardware calls for things like `imu_read()` and `pwm_write()`.
1430
Instead of a serial link over USB to the flight controller, we use a UDP connection bouncing off of localhost to communicate between `rosflight_io` and the firmware.
1531
This means the interface to the SIL plugin is identical to that of hardware.
1632
The `rosflight_io` node is the main gateway to the firmware in simulation, just as it is in hardware.
@@ -20,9 +36,137 @@ The following table summarizes the correlation between connections in hardware a
2036
| Connection Type | Hardware | Simulation |
2137
|-----------------------------------------|--------------|------------------------------------------|
2238
| Serial communications to `rosflight_io` | USB / UART | UDP |
23-
| RC | PPM Receiver | ROS2 `RC` topic (`rosflight_msgs/RCRaw`) |
24-
| Motors | PWM | Gazebo Plugin |
25-
| Sensors | SPI/I2C | Gazebo Plugin |
39+
| RC | PPM/SBUS Receiver | ROS2 `RC` topic (`rosflight_msgs/RCRaw`) |
40+
| Motors | PWM | Handled by `forces_and_moments` |
41+
| Sensors | SPI/I2C | `sensors` module |
42+
43+
44+
### Architecture
45+
46+
The simulator architecture is diagrammed below.
47+
48+
| ![Simulator Architecture](../images/simulator_architecture.svg) |
49+
| --- |
50+
| Fig 1: Architecture of the simulator. Note that the blue dashed box refers to the only parts that are active when running on hardware, while every module runs in sim. |
51+
52+
Throughout this guide, we will refer to **_modules_** in the simulator.
53+
In Fig 1, each module is represented by a green box, and replaces a process or component present on a real, physical system.
54+
A detailed description of each module is found [below](#module-descriptions).
55+
Each module is **implemented as a separate ROS2 node**, making the simulator more modular and flexible.
56+
57+
The modules communicate with each other via the arrows shown in Fig 1.
58+
Most of the time, these arrows refer to publisher/subscriber interfaces between the nodes.
59+
Other arrows refer to service calls.
60+
Note that not all communication lines are shown.
61+
See the code or use `rqt_graph` for a more complete description of how the simulation nodes communicate with each other.
62+
63+
The dashed black box represents `rosflight_sim`, where the green nodes are all the components of the simulator.
64+
The dashed blue box denotes the modules that are the only nodes present when using ROSflight on real hardware.
65+
In other words, these blue nodes are still used in sim, but the green nodes are not present when using real hardware.
66+
67+
!!! warning "Information separation"
68+
69+
It is important to note that the blue nodes do not "know" that they are in sim, making a more realistic simulator.
70+
In other words, the blue nodes depend only on information passed between themselves, so the code is the same in sim as it is on hardware.
71+
72+
For example, the `rosflight_firmware` box (in blue) is located inside the `rosflight_sim` box, since the `sil_board` node has an instantiation of the `rosflight_firmware` object.
73+
When the `rosflight_firmware` code calls functions that usually would interact with physical components on hardware, the `sil_board` instead calls the corresponding simulated module.
74+
75+
One example is the `imu_read` function.
76+
Normally on hardware, the `imu_read` function reads the IMU data from a buffer that is filled asynchronously over serial by the physical IMU.
77+
In sim, however, this IMU data is created by the `sensors` module, and is sent to the `sil_board` via a pub/sub interface.
78+
Then, when the firmware calls `imu_read`, the `sil_board` passes up the simulated information, **in the same way that the physical board would have read the data from the serial buffer**.
79+
80+
In a similar fashion, when the firmware calls `pwm_write`, instead of writing the PWM command to the servos/ESCs (as is done on hardware), the `sil_board` instead publishes the PWM commands over the `sim/pwm_output` topic to the `forces_and_moments` node.
81+
82+
!!! note "Implications of information separation"
83+
84+
Separating the flow of information in a realistic manner has some consequences.
85+
One such consequence in sim is that there is duplicate information flowing over the ROS2 network.
86+
87+
For example, when the `sensors` module creates IMU data, it is sent over the ROS2 network via a pub/sub interface to the `sil_board`.
88+
When the firmware reads that information via the `imu_read` function call, it does some processing but ultimately sends that information via MAVlink to `rosflight_io`.
89+
The `rosflight_io` node then publishes that information on a separate topic to the ROS2 network.
90+
Thus, **two copies** of the same IMU data are sent across the ROS2 network.
91+
92+
While having duplicate information is not ideal, it is more important (from our view) that the simulation is realistic--acting the same way as physical hardware, thereby decreasing the cost to transition from sim to hardware.
93+
94+
Note also that `rosflight_io` publishes the IMU data to the ROS2 network since in hardware, users often need to know or plot that information.
95+
96+
### Flow of information
97+
98+
A single simulation loop starts with the `rosflight_sil_manager` node.
99+
This node calls a service served up by the `sil_board` node, the `tick` service.
100+
This `tick` service corresponds to a single iteration of the main loop in the ROSflight firmware (see the [relevant source code](https://github.com/rosflight/rosflight_firmware/blob/main/src/rosflight.cpp), the `run()` function).
101+
102+
On a `tick`, the `rosflight_firmware` reads sensors when available, performs calculations, communicates over MAVlink, or anything else in the code.
103+
Note that most actions in the firmware are on timers, so not everything happens every time a `tick` service is called.
104+
For example, the GPS sensor only creates information at 5-10 Hz, so it only gets read at that rate.
105+
106+
During this `tick` call, the `rosflight_firmware` communicates with the `rosflight_io` node using MAVlink.
107+
In hardware, this communication happens over a serial connection, but we simulate this serial connection with a UDP connection when in sim.
108+
109+
After a `tick` completes, the `sil_board` publishes the resulting PWM commands over the `sim/pwm_output` topic to the `forces_and_moments` node.
110+
The `forces_and_moments` node first unmixes the PWM commands and then computes the aerodynamic forces and moments acting on the airframe based on motor/prop characteristics and the aerodynamic coefficients of the aircraft.
111+
Note that these calculations are only as accurate as the model in the `forces_and_moments` code.
112+
113+
The `forces_and_moments` node produces forces and moments, which it publishes over the `sim/forces_and_moments` topic to the `dynamics` node.
114+
The `dynamics` node then adds other forces, like gravity and any collision forces, and integrates the state of the aircraft using an RK4 integration step.
115+
The new truth state is published to whatever node is subscribed to the `sim/truth_state` topic.
116+
Note that the `dynamics` node also creates and publishes wind truth to the `sim/wind_truth` topic.
117+
118+
The `visualizer` node refers to the visualizer used, i.e. RViz, Gazebo Classic, HoloOcean, etc.
119+
The visualizer usually just subscribes to the true state and adjusts the visualization accordingly.
120+
121+
!!! note "A note on visualizers"
122+
123+
Remember that different visualizers implement different modules.
124+
Gazebo Classic, for example, handles the dynamic integration while the `standalone_sim` (using RViz as the visualizer) just visualizes the model and the trajectory.
125+
126+
The "visualizer" box in Fig 1 is therefore a placeholder, since the actual visualizer node might take up more than one module.
127+
128+
The `sensors` module receives the true state data and generates sensor data according to the true state.
129+
This sensor data gets sent over various topics (i.e. `sim/standalone_sensors/XXX`) to the `sil_board`.
130+
131+
Finally, the `time_manager` node is in charge of regulating the simulation time, and publishes the `clock` topic to **all** nodes.
132+
Note that if you don't want simulation time to be different than system time, you don't need the `time_manager` node.
133+
134+
## Module Descriptions
135+
136+
This section has more specific information on what each module does and its responsibilities in `rosflight_sim`.
137+
138+
### Time Manager
139+
The `time_manager` node is in charge of regulating simulation time.
140+
In ROS2, every node has a default parameter named `use_sim_time` (note that you don't have to declare this parameter--it comes by default).
141+
By default, this parameter is set `false`.
142+
143+
When `use_sim_time == true`, however, the node will listen to the `clock` topic as its internal time source.
144+
This means that all timers, calls to `get_clock()`, or any other time for that node will be based off of the `clock` topic.
145+
146+
### Sim Manager
147+
148+
### SIL Board
149+
150+
### Sensors
151+
152+
### Forces and Moments
153+
154+
### Dynamics
155+
156+
## Swapping out modules
157+
158+
This section describes how one would swap out modules, i.e. a different dynamics module.
159+
160+
## Node configuration for the different visualizers
161+
162+
This section describes how each visualizer supported by ROSflight uses the different modules described above.
163+
164+
### Standalone Sim
165+
166+
### Gazebo
167+
168+
### HoloOcean
26169

27170
## Adding your own visualizer
28171

172+
This section describes the process to add your own visualizer.

docs/user-guide/images/simulator_architecture.svg

Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)