├── paparazzi └── README.md ├── README.md ├── ArduPilot └── README.md └── PX4 └── README.md /paparazzi/README.md: -------------------------------------------------------------------------------- 1 | # Robotic-vehicle-software-tutorial 2 | 3 | ## 1. Quickstart for Ubuntu users 4 | Ubuntu 16.04 or Ubuntu 18.04: 5 | ``` 6 | sudo add-apt-repository -y ppa:paparazzi-uav/ppa && sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa && sudo apt-get update && sudo apt-get -f -y install paparazzi-dev paparazzi-jsbsim gcc-arm-embedded dfu-util && cd ~ && git clone --origin upstream https://github.com/paparazzi/paparazzi.git && cd ~/paparazzi && git remote update -p && git checkout -b v5.18 upstream/v5.18 && sudo cp conf/system/udev/rules/*.rules /etc/udev/rules.d/ && sudo udevadm control --reload-rules && make && ./paparazzi 7 | ``` 8 | 9 | Ubuntu 20.04 10 | ``` 11 | sudo add-apt-repository -y ppa:paparazzi-uav/ppa && sudo apt-get update && sudo apt-get -f -y install paparazzi-dev paparazzi-jsbsim python-is-python3 python3-serial gcc-arm-none-eabi gdb-multiarch dfu-util && cd ~ && git clone --origin upstream https://github.com/paparazzi/paparazzi.git && cd ~/paparazzi && git remote update -p && git checkout -b v5.18 upstream/v5.18 && sudo cp conf/system/udev/rules/*.rules /etc/udev/rules.d/ && sudo udevadm control --reload-rules && make && ./paparazzi 12 | ``` 13 | 14 | ## 2. Step by step 15 | ### 2-1. Download Paparazzi 16 | ``` 17 | git clone https://github.com/paparazzi/paparazzi.git [folder name] 18 | cd [folder name] 19 | git checkout [commit hash] 20 | git submodule update --init --recursive 21 | ``` 22 | 23 | ### 2-2. Compilation and demo simulation 24 | ``` 25 | cd [paparazzi root folder] 26 | make 27 | ./paparazzi 28 | ``` 29 | - Select the "Microjet" aircraft in the upper-left A/C combo box.
30 | - Select "sim" from upper-middle "target" combo box. Click "Build".
31 | - When the compilation is finished, select "Simulation" from the upper-right session combo box and click "Execute".
32 | - In the GCS, wait about 10s for the aircraft to be in the "Holding point" navigation block.
33 | - Switch to the "Takeoff" block (lower-left blue airway button in the strip). Takeoff with the green launch button.
34 | 35 | ## 3. Simulating sensor attacks 36 | ### 3-1. Adding gyro noise 37 | ``` 38 | cd [paparazzi root folder] 39 | vim ./sw/simulator/nps/nps_sensor_gyro.c 40 | ``` 41 | Changing 'bias_initial' and 'bias_random_walk_std_dev' 42 | For example, you can add 30 degrees of noise as follows. 43 | ``` 44 | VECT3_ASSIGN(gyro->bias_initial, 45 | RadOfDeg(30), RadOfDeg(30), RadOfDeg(30)); 46 | ... 47 | VECT3_ASSIGN(gyro->bias_random_walk_std_dev, 48 | RadOfDeg(30), 49 | RadOfDeg(30), 50 | RadOfDeg(30)); 51 | ``` 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Robotic-vehicle-software-tutorial 2 | 3 | Hello! It is not straightforward to precisely manipulate robotic vehicles (RVs) on simulators when you especially want to simulate cyber-physical attacks/defense.
4 | I will keep sharing how I run RV software on simulators. If you want to contribute to this tutorial, please create a pull request.
5 | 6 | ## 1. Download and Setup 7 | ### 1-1 ArduPilot (SITL, Gazebo) 8 | 9 | 10 | 11 | ### 1-2 PX4 (jMAVSim, Gazebo) 12 | 13 | 14 | 15 | ### 1-3 Paparazzi (NPS) 16 | 17 | 18 | 19 | ## 2. Execute control software 20 | ArduPilot 21 |
22 | PX4 23 |
24 | Paparazzi 25 | 26 | ## 3. Tutorials 27 | ### 3-1. ArduPilot 28 | Injecting sensor noise 29 |
30 | Turning off filters 31 |
32 | Leveraging an optical flow sensor 33 |
34 | Testing object avoidance algorithms 35 |
36 | Changing the start time clock (timestamp) 37 |
38 | Troubleshooting 39 | 40 | ### 3-2. PX4 41 | Injecting sensor noise in Gazebo simulation 42 |
43 | Leveraging an optical flow sensor 44 |
45 | Deploying PX4 v.1.13.0 into Crazyflie 2.1 46 |
47 | Simulating mmWave radar with ROS2 and PX4 48 |
49 | Troubleshooting 50 | 51 | ### 3-3. Paparazzi 52 | Simulating sensor attacks 53 |
54 | 55 | ### 3-4 Installing Pymavlink to manipulate vehicles by using Python 56 | 57 | #### Ubuntu 20.04 58 | ``` 59 | sudo apt-get install gcc python-dev libxml2-dev libxslt-dev 60 | sudo apt-get install python-numpy python-pytest 61 | sudo apt install curl 62 | sudo apt install python2 63 | curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py 64 | sudo python2 get-pip.py 65 | sudo python2 -m pip install --upgrade future lxml 66 | 67 | git clone https://github.com/ArduPilot/mavlink.git 68 | cd mavlink 69 | git submodule update --init --recursive 70 | cd pymavlink 71 | sudo MDEF=`pwd`/../message_definitions python2 -m pip install . -v 72 | ``` 73 | 74 | #### Ubuntu 22.04 75 | ``` 76 | # Update list of available packages 77 | sudo apt update 78 | sudo apt -y upgrade 79 | 80 | # Install some dependencies 81 | sudo apt install -y python3-pip 82 | 83 | # Install mavproxy module and everything else needed 84 | pip3 install mavproxy 85 | ``` 86 | 87 | ### 3-5. Ground Control Station (GCS) Software 88 | 89 | #### 3-5-1. Installing QGroundControl 90 | 91 | When your operating system is Ubuntu 20.04 (or later version),
92 | ``` 93 | sudo usermod -a -G dialout $USER 94 | sudo apt-get remove modemmanager -y 95 | sudo apt install gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl -y 96 | sudo apt install libqt5gui5 -y 97 | ``` 98 | Logout and login again to enable the change to user permissions.
99 | 100 | Download QGroundControl 101 | 102 | When your operating system is Ubuntu 16.04,
103 | Download QGroundControl v3.5.6 104 | 105 | ``` 106 | chmod +x ./QGroundControl.AppImage 107 | ./QGroundControl.AppImage (or double click) 108 | ``` 109 | #### 3-5-2. Installing Mission Planner on Ubuntu 20.04 110 | 111 | Install dependecies
112 | ``` 113 | sudo apt install mono-runtime libmono-system-windows-forms4.0-cil libmono-system-core4.0-cil libmono-system-management4.0-cil libmono-system-xml-linq4.0-cil 114 | ``` 115 | 116 | Install mono
117 | ``` 118 | sudo apt install mono-complete 119 | ``` 120 | Get the lastest zipped version of Mission Planner (e.g., link)
121 | 122 | Unzip in the directory you want
123 | 124 | Go into the directory
125 | 126 | Run Mission Planner with mono
127 | ``` 128 | mono MissionPlanner.exe 129 | ``` 130 | -------------------------------------------------------------------------------- /ArduPilot/README.md: -------------------------------------------------------------------------------- 1 | # Robotic-vehicle-software-tutorial 2 | 3 | ## 1. Download and Setup 4 | ``` 5 | sudo apt-get update 6 | sudo apt-get install git 7 | sudo apt-get install gitk git-gui 8 | 9 | git clone https://github.com/ArduPilot/ardupilot.git ArduPilot 10 | cd ArduPilot 11 | git checkout [commit hash] 12 | git submodule update --init --recursive 13 | 14 | # If the command above fails to load submodule, you can try to use *https* instead of *git*. 15 | git config --global url."https://".insteadOf git:// 16 | 17 | Tools/environment_install/install-prereqs-ubuntu.sh -y 18 | . ~/.profile 19 | ``` 20 | 21 | When you meet "No such file or directory: mavproxy.py" error. Please install MAVProxy. 22 | ``` 23 | sudo apt-get install python3-dev python3-opencv python3-wxgtk4.0 python3-pip python3-matplotlib python3-lxml python3-pygame 24 | pip3 install PyYAML mavproxy --user 25 | echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc 26 | ``` 27 | 28 | ## 2. Execute ArduPilot 29 | ### 2-1. SITL 30 | Copter 31 | ``` 32 | ./Tools/autotest/sim_vehicle.py -v ArduCopter --console 33 | ``` 34 | 35 | Plane 36 | ``` 37 | ./Tools/autotest/sim_vehicle.py -v ArduPlane --console 38 | ``` 39 | 40 | Rover 41 | ``` 42 | ./Tools/autotest/sim_vehicle.py -v Rover --console 43 | ``` 44 | 45 | Submarine 46 | ``` 47 | ./Tools/autotest/sim_vehicle.py -v ArduSub --console 48 | ``` 49 | 50 | Key build options 51 | 1) -c: do a make clean before building 52 | 2) -G: use gdb for debugging ardupilot 53 | 3) -w: wipe EEPROM and reload parameters 54 | 55 | 56 | ### 2-2. Gazebo 57 | #### Install Gazebo simulator 58 | gz-garden 59 | ``` 60 | sudo apt-get update 61 | sudo apt-get install lsb-release wget gnupg 62 | 63 | sudo wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg 64 | echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null 65 | sudo apt-get update 66 | sudo apt-get install gz-garden 67 | ``` 68 | 69 | gazebo-classic 70 | ``` 71 | sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list' 72 | wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add - 73 | sudo apt update 74 | sudo apt-get install gazebo11 libgazebo11-dev 75 | ``` 76 | 77 | #### Install the ArduPilot Gazebo Plugin 78 | ``` 79 | cd ~ 80 | git clone https://github.com/khancyr/ardupilot_gazebo.git 81 | 82 | cd ardupilot_gazebo 83 | mkdir build 84 | cd build 85 | cmake .. 86 | make -j4 87 | sudo make install 88 | echo 'source /usr/share/gazebo/setup.sh' >> ~/.bashrc 89 | echo 'export GAZEBO_MODEL_PATH=~/ardupilot_gazebo/models' >> ~/.bashrc 90 | . ~/.bashrc 91 | ``` 92 | 93 | #### Configure the Gazebo environment 94 | In a terminal 95 | ``` 96 | export GZ_SIM_SYSTEM_PLUGIN_PATH=$HOME/gz_ws/src/ardupilot_gazebo/build:$GZ_SIM_SYSTEM_PLUGIN_PATH 97 | export GZ_SIM_RESOURCE_PATH=$HOME/gz_ws/src/ardupilot_gazebo/models:$HOME/gz_ws/src/ardupilot_gazebo/worlds:$GZ_SIM_RESOURCE_PATH 98 | ``` 99 | 100 | In .bashrc or .zshrc 101 | ``` 102 | echo 'export GZ_SIM_SYSTEM_PLUGIN_PATH=$HOME/gz_ws/src/ardupilot_gazebo/build:${GZ_SIM_SYSTEM_PLUGIN_PATH}' >> ~/.bashrc 103 | echo 'export GZ_SIM_RESOURCE_PATH=$HOME/gz_ws/src/ardupilot_gazebo/models:$HOME/gz_ws/src/ardupilot_gazebo/worlds:${GZ_SIM_RESOURCE_PATH}' >> ~/.bashrc 104 | ``` 105 | 106 | #### Run Gazebo simulator 107 | ##### gz-garden 108 | Terminal 1 109 | ``` 110 | gz sim -v4 -r iris_runway.sdf 111 | ``` 112 | 113 | Terminal 2 114 | ``` 115 | ./Tools/autotest/sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --map --console 116 | ``` 117 | 118 | ##### gazebo-classic 119 | Terminal 1 120 | ``` 121 | gazebo --verbose ~/ardupilot_gazebo/worlds/iris_arducopter_runway.world 122 | ``` 123 | 124 | Terminal 2 125 | ``` 126 | ./Tools/autotest/sim_vehicle.py -v ArduCopter -f gazebo-iris --console 127 | ``` 128 | 129 | ## 3. Injecting sensor noise 130 | ### 3-1. Gyro sensor 131 | Source code 132 | ``` 133 | param set SIM_GYR1_RND 3 134 | param set SIM_GYR2_RND 3 135 | param set SIM_GYR3_RND 3 136 | ``` 137 | 138 | ### 3-2. Accelerometer sensor 139 | ``` 140 | param set SIM_ACC1_RND 3 141 | param set SIM_ACC2_RND 3 142 | param set SIM_ACC3_RND 3 143 | ``` 144 | 145 | ### 3-3. Air speed sensor 146 | ``` 147 | param set SIM_ARSPD1_RND 3 148 | param set SIM_ARSPD2_RND 3 149 | param set SIM_ARSPD3_RND 3 150 | ``` 151 | 152 | ### 3-4. Barometer sensor 153 | ``` 154 | param set SIM_BARO1_RND 3 155 | param set SIM_BARO2_RND 3 156 | param set SIM_BARO3_RND 3 157 | ``` 158 | 159 | ### 3-5. Optical flow sensor 160 | ``` 161 | param set SIM_FLOW_RND 3 162 | param set SIM_FLOW_DELAY 3 163 | ``` 164 | 165 | ### 3-6. Magnetometer sensor 166 | ``` 167 | param set SIM_MAG2_FAIL 1 168 | param set SIM_MAG3_FAIL 1 169 | param set SIM_MAG_RND 3 170 | ``` 171 | 172 | ### 3-7. Sonar sensor 173 | ``` 174 | param set SIM_SONAR_RND 3 175 | ``` 176 | 177 | ### 3-8. GPS 178 | You need to set 'SIM_GPS_TYPE' parameter (controling how GPS is used) before adding GPS noise.
179 |
180 | SIM_GPS_TYPE: 181 | - 0: Use 3D velocity & 2D position from GPS 182 | - 1: Use 2D velocity & 2D position (GPS velocity does not contribute to altitude estimate) 183 | - 2: Use 2D position 184 | - 3: No GPS (will use optical flow only if available) 185 | 186 | Changing parameters below triggers GPS glitch fail-safe logic on a software version (d0210f7b8930dc336e7de2c09dfe2029290f596b). 187 | ``` 188 | param set SIM_GPS_NOISE 3 # Add noise 189 | param set SIM_GPS2_NOISE 3 190 | 191 | param set SIM_GPS_VERR_X 3 # Add velocity errors 192 | param set SIM_GPS_VERR_Y 3 193 | param set SIM_GPS_VERR_Z 3 194 | 195 | param set SIM_GPS2_VERR_X 3 196 | param set SIM_GPS2_VERR_Y 3 197 | param set SIM_GPS2_VERR_Z 3 198 | 199 | param set SIM_GPS_GLITCH_X 0.0002 200 | param set SIM_GPS_GLITCH_Y 0.0002 201 | param set SIM_GPS_GLITCH_Z 0.0002 202 | ``` 203 | 204 | Changing parameters below does not trigger GPS glitch fail-safe logic on a software version (d0210f7b8930dc336e7de2c09dfe2029290f596b). 205 | ``` 206 | param set SIM_GPS_NOISE 1 # Add noise 207 | param set SIM_GPS2_NOISE 1 208 | 209 | param set SIM_GPS_VERR_X 1 # Add velocity errors 210 | param set SIM_GPS_VERR_Y 1 211 | param set SIM_GPS_VERR_Z 1 212 | 213 | param set SIM_GPS2_VERR_X 1 214 | param set SIM_GPS2_VERR_Y 1 215 | param set SIM_GPS2_VERR_Z 1 216 | 217 | param set SIM_GPS_GLITCH_X 0.00001 218 | param set SIM_GPS_GLITCH_Y 0.00001 219 | param set SIM_GPS_GLITCH_Z 0.00001 220 | ``` 221 | ### 3-9. EMI Signal Injection Attack 222 | Reference: Paralyzing Drones via EMI Signal Injection on Sensory Communication Channels, NDSS'23 223 | 224 | (Option 1) Turning off all sensors except for GNSS 225 | ``` 226 | param set SIM_GYR_FAIL_MSK 1 227 | param set SIM_ACCEL1_FAIL 1 228 | param set SIM_ACCEL2_FAIL 1 229 | param set SIM_ACCEL3_FAIL 1 230 | param set SIM_BARO_DISABLE 1 231 | param set SIM_MAG1_FAIL 1 232 | param set SIM_MAG2_FAIL 1 233 | param set SIM_MAG3_FAIL 1 234 | ``` 235 | 236 | (Option 2) Add noises into all sensors except for GNSS 237 | ``` 238 | param set SIM_GYR1_RND 700 239 | param set SIM_GYR2_RND 700 240 | param set SIM_GYR3_RND 700 241 | param set SIM_ACC1_RND 700 242 | param set SIM_ACC2_RND 700 243 | param set SIM_ACC3_RND 700 244 | param set SIM_BARO_RND 700 245 | param set SIM_BAR2_RND 700 246 | param set SIM_BAR3_RND 700 247 | param set SIM_MAG_RND 700 248 | param set SIM_MAG2_FAIL 1 249 | param set SIM_MAG3_FAIL 1 250 | ``` 251 | 252 | ## 4. Turning off filters 253 | This is useful when you want to measure each filter's effect and performance. 254 | 255 | ### 4-1. Turning off Harmonic Notch filter 256 | ``` 257 | param set INS_HNTCH_ENABLE 0 258 | ``` 259 | 260 | ### 4-2. Turning off Low Pass filter 261 | Comment out the code line below (here) 262 | ``` 263 | // apply the low pass filter last to attentuate any notch induced noise 264 | gyro_filtered = _imu._gyro_filter[instance].apply(gyro_filtered); 265 | ``` 266 | 267 | ## 5. Leveraging an optical flow sensor 268 | ### 5-1. Adding a rangefinder sensor 269 | ``` 270 | param set SIM_SONAR_SCALE 10 271 | param set RNGFND1_TYPE 1 272 | param set RNGFND1_SCALING 10 273 | param set RNGFND1_PIN 0 274 | param set RNGFND1_MAX_CM 5000 275 | param set RNGFND1_MIN_CM 0 276 | 277 | module load graph 278 | graph RANGEFINDER.distance # You can check measured distances. 279 | ``` 280 | 281 | ### 5-2. Adding an optical flow sensor 282 | ``` 283 | param set SIM_FLOW_ENABLE 1 284 | param set FLOW_TYPE 10 285 | 286 | module load graph 287 | graph OPTICAL_FLOW.flow_comp_m_x OPTICAL_FLOW.flow_comp_m_y # You can check measured (x, y) positions. 288 | ``` 289 | 290 | ### 5-3. Parameter setting for fusing optical flow sensor data 291 | If you use EKF version 3, 292 | ``` 293 | param set EK3_SRC1_VELXY 5 # Velocity Horizontal Source 294 | param set EK3_SRC1_POSXY 0 # Position Horizontal Source 295 | param set EK3_SRC_OPTIONS 0 296 | param set EK3_SRC1_POSZ 1 297 | param set EK3_SRC1_VELZ 0 298 | param set EK3_SRC1_YAW 1 299 | ``` 300 | 301 | If you use EKF version 2, 302 | ``` 303 | param set EK2_SRC1_VELXY 5 304 | param set EK2_SRC1_POSXY 0 305 | param set EK2_SRC_OPTIONS 0 306 | param set EK2_SRC1_POSZ 1 307 | param set EK2_SRC1_VELZ 0 308 | param set EK2_SRC1_YAW 1 309 | ``` 310 | 311 | ### 5-4. Controling sensor fusion source 312 | By setting EK2_GPS_TYPE/SIM_GPS_TYPE parameters, you can decide whether ArduPilot uses (i) GPS and optical flow data or (ii) just optical flow.
313 | - 0: GPS 3D Vel and 2D Pos 314 | - 1: GPS 2D vel and 2D pos 315 | - 2: GPS 2D pos 316 | - 3: No GPS 317 | ``` 318 | # Stop to use GPS data when you fly a real drone 319 | param set EK2_GPS_TYPE 3 320 | 321 | # Stop to use GPS data when you fly a drone on a simulator 322 | param set SIM_GPS_TYPE 3 323 | ``` 324 | 325 | ### 5-5. Running Gazebo simulator to test the optical flow sensor 326 | Open Terminal 1 327 | ``` 328 | gazebo --verbose ~/ardupilot_gazebo/worlds/iris_arducopter_runway.world 329 | ``` 330 | 331 | Open Terminal 2 332 | ``` 333 | ./Tools/autotest/sim_vehicle.py -v ArduCopter -f gazebo-iris 334 | ``` 335 | 336 | ## 6. Testing object avoidance algorithms 337 | ``` 338 | param set AVOID_ENABLE 7 339 | param set FENCE_ENABLE 1 340 | param set FENCE_RADIUS 10000 341 | param set OA_TYPE 2 342 | param set OA_MARGIN_MAX 10 343 | ``` 344 | By setting OA_TYPE parameter, you can choose the object avoidance algorithm. 345 | - 0: Disabled 346 | - 1: BendyRuler 347 | - 2: Dijkstra 348 | - 3: Dijkstra with BendyRuler 349 | 350 | ## 7. How to change the start time clock (timestamp)? 351 | You need to change a code line (here). 352 | 353 | ``` 354 | # Original code line 355 | time_now_us(0), 356 | 357 | # Modify the code line as follows, which leads to system time wrap after 60 seconds 358 | time_now_us(4294900000ULL * 1000ULL), 359 | ``` 360 | Q. What is the purpose of the changed time clock?
361 | A. In case of me, it was useful to test MAVLink 2.0 Packet Signing. 362 | 363 | ## 8. Troubleshooting 364 | ### 8-1. "No module named console" or "No module named map" 365 | İf you using anaconda, you can download Mavproxy requirements with conda. 366 | ``` 367 | conda install -c anaconda wxpython 368 | ``` 369 | -------------------------------------------------------------------------------- /PX4/README.md: -------------------------------------------------------------------------------- 1 | # Robotic-vehicle-software-tutorial 2 | 3 | ## 1. Download and Setup 4 | ``` 5 | git clone https://github.com/PX4/PX4-Autopilot.git PX4 6 | CD PX4 7 | git checkout [commit hash] // e.g., 6823cbc (v.1.13) 8 | git submodule update --init --recursive 9 | ./Tools/setup/ubuntu.sh -y 10 | ``` 11 | Running jMAVSim with SITL to ensure that the simulation prerequisites are installed on the system 12 | ``` 13 | make px4_sitl_default jmavsim 14 | ``` 15 | 16 | If you use Java 11 version, you need to fall back to Java 8. 17 | ``` 18 | sudo apt install openjdk-8-jdk 19 | sudo update-alternatives --config java # choose 8 20 | rm -rf Tools/jMAVSim/out 21 | ``` 22 | ``` 23 | sudo gedit /etc/java-8-openjdk/accessibility.properties 24 | ``` 25 | and comment out the following line like this: 26 | ``` 27 | #assistive_technologies=org.GNOME.Acessibility.AtkWrapper 28 | ``` 29 | 30 | 31 | ## 2. Execute PX4 with Gazebo simulator 32 | ### Takeoff position in the simulator 33 | In the case of **ground** and **aerial vehicles**, the default starting position is Zurich Irchel Park (lat: 47.397742, lon: 8.545594, alt: 488.0).
34 | If the vehicle type is **underwater**, the default starting position is (lat: 47.3334475, lon: 8.5471141).
35 | The takeoff location in SITL Gazebo can be set using environment variables.
36 | ``` 37 | export PX4_HOME_LAT=28.452386 38 | export PX4_HOME_LON=-13.867138 39 | export PX4_HOME_ALT=28.5 40 | ``` 41 | 42 | ### 2-1. Quadrotor 43 | ``` 44 | make clean 45 | make distclean 46 | make px4_sitl gazebo 47 | ``` 48 | 49 | ### 2-2. Quadrotor with Optical Flow 50 | ``` 51 | make px4_sitl gazebo_iris_opt_flow 52 | ``` 53 | 54 | 55 | Gazebo can be run in a headless mode in which the Gazebo UI is not launched. This starts up more quickly and uses less system resources (i.e. it is a more "lightweight" way to run the simulation). 56 | 57 | Simply prefix the normal make command with HEADLESS=1 as shown: 58 | ``` 59 | HEADLESS=1 make px4_sitl gazebo_iris_opt_flow 60 | ``` 61 | 62 | ### 2-3. 3DR Solo (Quadrotor) 63 | ``` 64 | make px4_sitl gazebo_solo 65 | ``` 66 | 67 | ### 2-4. Typhoon H480 (Hexrotor) (supports video streaming) 68 | ``` 69 | make px4_sitl gazebo_typhoon_h480 70 | ``` 71 | 72 | ### 2-5. Standard Plane 73 | ``` 74 | make px4_sitl gazebo_plane 75 | ``` 76 | 77 | ### 2-6. Standard Plane (with catapult launch) 78 | ``` 79 | make px4_sitl gazebo_plane_catapult 80 | ``` 81 | 82 | ### 2-7. Standard VTOL 83 | ``` 84 | make px4_sitl gazebo_standard_vtol 85 | ``` 86 | 87 | ### 2-8. Tailsitter VTOL 88 | ``` 89 | make px4_sitl gazebo_tailsitter 90 | ``` 91 | 92 | ### 2-9. Ackerman UGV (Rover) 93 | ``` 94 | make px4_sitl gazebo_rover 95 | ``` 96 | 97 | ### 2-10. Differential UGV (Rover) 98 | ``` 99 | make px4_sitl gazebo_r1_rover 100 | ``` 101 | 102 | ### 2-11. HippoCampus TUHH (UUV: Unmanned Underwater Vehicle) 103 | ``` 104 | make px4_sitl gazebo_uuv_hippocampus 105 | ``` 106 | 107 | ### 2-12. Boat (USV: Unmanned Surface Vehicle) 108 | ``` 109 | make px4_sitl gazebo_boat 110 | ``` 111 | 112 | ### 2-13. Cloudship (Airship) 113 | ``` 114 | make px4_sitl gazebo_cloudship 115 | ``` 116 | 117 | ## 3. Injecting sensor noise in Gazebo simulation 118 | 119 | ### Disable preflight checks for 'forced arming' 120 | This is an original code snippet in /src/modules/commander/Commander.cpp. 121 | ``` 122 | transition_result_t Commander::arm(arm_disarm_reason_t calling_reason, bool run_preflight_checks) 123 | { 124 | // allow a grace period for re-arming: preflight checks don't need to pass during that time, for example for accidential in-air disarming 125 | if (calling_reason == arm_disarm_reason_t::rc_switch 126 | && (hrt_elapsed_time(&_last_disarmed_timestamp) < 5_s)) { 127 | run_preflight_checks = false; 128 | } 129 | 130 | ``` 131 | 132 | This example code line disables preflight checks for 'forced arming'. 133 | ``` 134 | transition_result_t Commander::arm(arm_disarm_reason_t calling_reason, bool run_preflight_checks) 135 | { 136 | run_preflight_checks = false; 137 | 138 | // allow a grace period for re-arming: preflight checks don't need to pass during that time, for example for accidential in-air disarming 139 | if (calling_reason == arm_disarm_reason_t::rc_switch 140 | && (hrt_elapsed_time(&_last_disarmed_timestamp) < 5_s)) { 141 | run_preflight_checks = false; 142 | } 143 | 144 | ``` 145 | 146 | This is an original code snippet in /src/modules/commander/Commander.cpp. 147 | ``` 148 | } 149 | break; 150 | 151 | case vehicle_command_s::VEHICLE_CMD_DO_FLIGHTTERMINATION: { 152 | ``` 153 | 154 | This example code line disables preflight checks for 'forced arming'. 155 | ``` 156 | } 157 | 158 | cmd_result = 1; 159 | 160 | break; 161 | 162 | case vehicle_command_s::VEHICLE_CMD_DO_FLIGHTTERMINATION: { 163 | ``` 164 | 165 | ### 3-1. Add noises to gyroscopes 166 | 167 | Manually add noise into each sensor in this file 168 | 169 | This is an original code snippet. 170 | ``` 171 | gyroscope_bias_[i] = phi_g_d * gyroscope_bias_[i] + 172 | sigma_b_g_d * standard_normal_distribution_(random_generator_); 173 | ``` 174 | This example code lines add noise into gyroscope sensors. 175 | ``` 176 | gyroscope_bias_[i] = phi_g_d * gyroscope_bias_[i] + 177 | sigma_b_g_d * standard_normal_distribution_(random_generator_) * 20; 178 | ``` 179 | 180 | Q. Why should we modify PX4 source code to add noise? Is there any more easy way (e.g., changing configuration parameters)?
181 | A. Unfortunately, PX4's failure injection is broken.
182 | 183 | ### 3-2. Add noises to accelerometers 184 | 185 | Manually add noise into each sensor in this file 186 | 187 | This is an original code snippet. 188 | ``` 189 | accelerometer_bias_[i] = phi_a_d * accelerometer_bias_[i] + 190 | sigma_b_a_d * standard_normal_distribution_(random_generator_); 191 | ``` 192 | This example code lines add noise into accelerometer sensors. 193 | ``` 194 | accelerometer_bias_[i] = phi_a_d * accelerometer_bias_[i] + 195 | sigma_b_a_d * standard_normal_distribution_(random_generator_) * 20; 196 | ``` 197 | 198 | ### 3-3. Add noises to magnetometers 199 | 200 | Manually add noise into each sensor in this file 201 | 202 | This is an original code snippet. 203 | ``` 204 | bias_[i] = phi_d * bias_[i] + sigma_b_d * standard_normal_distribution_(random_generator_); 205 | ``` 206 | This example code lines add noise into magnetometer sensors. 207 | ``` 208 | bias_[i] = phi_d * bias_[i] + sigma_b_d * standard_normal_distribution_(random_generator_) * 20; 209 | ``` 210 | 211 | ### 3-4. Add noises to a barometer 212 | 213 | Manually add noise into each sensor in this file 214 | 215 | This is an original code snippet. 216 | ``` 217 | // Apply noise and drift 218 | const float abs_pressure_noise = 1.0f * (float)y1; // 1 Pa RMS noise 219 | ``` 220 | This example code lines add noise into magnetometer sensors. 221 | ``` 222 | // Apply noise and drift 223 | const float abs_pressure_noise = 1.0f * (float)y1 * 20; // 1 Pa RMS noise 224 | ``` 225 | 226 | ### 3-5. Add noises to GNSS 227 | Manually add noise into each sensor in this file 228 | 229 | This is an original code snippet. 230 | ``` 231 | noise_gps_pos_.X() = gps_xy_noise_density_ * sqrt(dt) * randn_(rand_); 232 | noise_gps_pos_.Y() = gps_xy_noise_density_ * sqrt(dt) * randn_(rand_); 233 | noise_gps_pos_.Z() = gps_z_noise_density_ * sqrt(dt) * randn_(rand_); 234 | noise_gps_vel_.X() = gps_vxy_noise_density_ * sqrt(dt) * randn_(rand_); 235 | noise_gps_vel_.Y() = gps_vxy_noise_density_ * sqrt(dt) * randn_(rand_); 236 | noise_gps_vel_.Z() = gps_vz_noise_density_ * sqrt(dt) * randn_(rand_); 237 | random_walk_gps_.X() = gps_xy_random_walk_ * sqrt(dt) * randn_(rand_); 238 | random_walk_gps_.Y() = gps_xy_random_walk_ * sqrt(dt) * randn_(rand_); 239 | random_walk_gps_.Z() = gps_z_random_walk_ * sqrt(dt) * randn_(rand_); 240 | ``` 241 | This example code lines add noise into magnetometer sensors. 242 | ``` 243 | noise_gps_pos_.X() = gps_xy_noise_density_ * sqrt(dt) * randn_(rand_) * 60; 244 | noise_gps_pos_.Y() = gps_xy_noise_density_ * sqrt(dt) * randn_(rand_) * 60; 245 | noise_gps_pos_.Z() = gps_z_noise_density_ * sqrt(dt) * randn_(rand_) * 60; 246 | noise_gps_vel_.X() = gps_vxy_noise_density_ * sqrt(dt) * randn_(rand_) * 60; 247 | noise_gps_vel_.Y() = gps_vxy_noise_density_ * sqrt(dt) * randn_(rand_) * 60; 248 | noise_gps_vel_.Z() = gps_vz_noise_density_ * sqrt(dt) * randn_(rand_) * 60; 249 | random_walk_gps_.X() = gps_xy_random_walk_ * sqrt(dt) * randn_(rand_) * 60; 250 | random_walk_gps_.Y() = gps_xy_random_walk_ * sqrt(dt) * randn_(rand_) * 60; 251 | random_walk_gps_.Z() = gps_z_random_walk_ * sqrt(dt) * randn_(rand_) * 60; 252 | ``` 253 | 254 | ### 3-6. Add noises to an optical flow sensor 255 | Manually add noise into each sensor in this file 256 | 257 | This is an original code snippet. 258 | ``` 259 | opticalFlow_message.set_integrated_x(quality ? flow_x_ang : 0.0f); 260 | opticalFlow_message.set_integrated_y(quality ? flow_y_ang : 0.0f); 261 | ``` 262 | This example code lines add noise into an optical flow. 263 | ``` 264 | opticalFlow_message.set_integrated_x(quality ? flow_x_ang * 20 : 0.0f); 265 | opticalFlow_message.set_integrated_y(quality ? flow_y_ang * 20 : 0.0f); 266 | ``` 267 | 268 | ## 4. Leveraging an optical flow sensor 269 | ``` 270 | cd [PX4 source folder] 271 | make px4_sitl gazebo_iris_opt_flow 272 | ``` 273 | You can configure EKF2_AID_MASK parameter to control sensor fusion sources.
274 | - 0: use GPS 275 | - 1: use optical flow 276 | - 2: inhibit IMU bias estimation 277 | - 3: vision position fusion 278 | - 4: vision yaw fusion 279 | - 5: multi-rotor drag fusion 280 | - 6: rotate external vision 281 | - 7: GPS yaw fusion 282 | - 8: vision velocity fusion 283 | 284 | ## 5. Deploying PX4 v.1.13.0 into Crazyflie 2.1 285 | ### 5-1. Build PX4 286 | ``` 287 | git clone https://github.com/PX4/PX4-Autopilot.git PX4 288 | CD PX4 289 | git checkout 6823cbc4140e29568f00e1211ae60e057adb1a1f 290 | git submodule update --init --recursive 291 | ``` 292 | 293 | ### 5-2. Upload firmware into Crazyflie 2.1 294 | ``` 295 | make bitcraze_crazyflie21_default upload 296 | ``` 297 | 298 | ### 5-3. Build cfbridge for Crazyradio PA 299 | ``` 300 | git clone https://github.com/dennisss/cfbridge.git 301 | git submodule update --init 302 | make build 303 | sudo make run 304 | ``` 305 | 306 | ### 5-4. Open QGC and enjoy! 307 | 308 | ### 5-5. Flying Crazyflie 2.1 309 | Altitude mode works well and is supported by the current setup. 310 | 311 | ## 6. Troubleshooting 312 | ### 6-1. No package 'eigen3' found 313 | ``` 314 | sudo apt-add-repository universe 315 | sudo apt-get install libeigen3-dev 316 | ``` 317 | 318 | ### 6-2. Could not find a package configuration file provided by "OpenCV" 319 | #### Installing required build dependencies 320 | ``` 321 | sudo apt-get install cmake 322 | sudo apt-get install gcc g++ 323 | 324 | sudo apt-get install python-dev python-numpy 325 | sudo apt-get install python3-dev python3-numpy 326 | 327 | sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev 328 | sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev 329 | 330 | sudo apt-get install libgtk2.0-dev 331 | sudo apt-get install libgtk-3-dev 332 | 333 | sudo apt-get install libpng-dev 334 | sudo apt-get install libjpeg-dev 335 | sudo apt-get install libopenexr-dev 336 | sudo apt-get install libtiff-dev 337 | sudo apt-get install libwebp-dev 338 | ``` 339 | 340 | #### Downloading and installing OpenCV 341 | ``` 342 | sudo apt-get install git 343 | git clone https://github.com/opencv/opencv.git 344 | 345 | mkdir build 346 | cd build 347 | 348 | cmake ../ 349 | make 350 | sudo make install 351 | ``` 352 | 353 | #### Verifying the installation 354 | ``` 355 | python -c "import cv2; print(cv2.__version__)" 356 | python3 -c "import cv2; print(cv2.__version__)" 357 | ``` 358 | ``` 359 | Output 360 | 4.6.0-dev 361 | 3.2.0 362 | ``` 363 | ### 6-3. Failed to import jinja2: No module named 'jinja2' 364 | ``` 365 | sudo apt remove python-jinja2 366 | sudo apt remove python3-jinja2 367 | 368 | pip3 install --user jinja2 369 | ``` 370 | 371 | ### 6-4. CMake Error: The following variables are used in this project, but they are set to NOTFOUND 372 | ``` 373 | sudo apt-get install libgstreamer-plugins-base1.0-dev 374 | ``` 375 | 376 | ### 6-5. CMake Error: Could not find a package configuration file provided by "MAVSDK" (requested version 1.3.1) with any of the following names 377 | ``` 378 | wget https://github.com/mavlink/MAVSDK/releases/download/v1.4.16/libmavsdk-dev_1.4.16_ubuntu20.04_amd64.deb 379 | sudo chmod 777 libmavsdk-dev_1.4.16_ubuntu20.04_amd64.deb 380 | sudo dpkg -i libmavsdk-dev_1.4.16_ubuntu20.04_amd64.deb 381 | ``` 382 | 383 | ### 6-6. Waiting for simulator to accept connection on TCP port 4560 384 | Installing ant package 385 | ``` 386 | sudo apt install ant 387 | ``` 388 | 389 | ### 6-7. Exception in thread "main" java.lang.reflect.InvocationTargetException 390 | ``` 391 | sudo vim /etc/java-8-openjdk/accessibility.properties 392 | ``` 393 | 394 | Commented out the following line: 395 | ``` 396 | #assistive_technologies=org.GNOME.Accessibility.AtkWrapper 397 | ``` 398 | --------------------------------------------------------------------------------