├── .gitignore ├── README.md ├── aircraft ├── Rascal │ ├── Dialogs │ │ └── config.xml │ ├── Engines │ │ ├── 18x8.xml │ │ └── Zenoah_G-26A.xml │ ├── Models │ │ ├── Rascal.rgb │ │ ├── Rascal110-000-013.ac │ │ ├── Rascal110.xml │ │ ├── Trajectory-Marker.ac │ │ ├── Trajectory-Marker.xml │ │ └── smokeW.xml │ ├── README.Rascal │ ├── Rascal-keyboard.xml │ ├── Rascal-submodels.xml │ ├── Rascal.xml │ ├── Rascal110-JSBSim-set.xml │ ├── Rascal110-JSBSim.xml │ ├── Rascal110-splash.rgb │ ├── Systems │ │ ├── 110-autopilot.xml │ │ ├── airdata.nas │ │ ├── electrical.xml │ │ ├── main.nas │ │ └── ugear.nas │ ├── reset.xml │ ├── reset_CMAC.xml │ ├── reset_template.xml │ └── thumbnail.jpg ├── arducopter │ ├── Engines │ │ ├── a2830-12.xml │ │ └── prop10x4.5.xml │ ├── Models │ │ ├── AutoSave_plus_quad.skp │ │ ├── Untitled.ac │ │ ├── Untitled.skp │ │ ├── Y6_test.ac │ │ ├── Y6_test.skp │ │ ├── Y6_test2.skp │ │ ├── _propeller0_.skb │ │ ├── _propeller0_.skp │ │ ├── arducopter.ac │ │ ├── arducopter.xml │ │ ├── plus_quad.ac │ │ ├── plus_quad.skb │ │ ├── plus_quad.skp │ │ ├── plus_quad2.ac │ │ ├── plus_quad2.dae │ │ ├── plus_quad2.skb │ │ ├── plus_quad2.skp │ │ ├── plus_quad2.xml │ │ ├── quad.3ds │ │ ├── quad.skp │ │ └── shareware_output.3ds │ ├── README │ ├── arducopter-set.xml │ ├── arducopter.jpg │ ├── arducopter.xml │ ├── data │ │ ├── arducopter_half_step.txt │ │ ├── arducopter_step.txt │ │ └── rw_generic_pylon.ac │ ├── initfile.xml │ ├── plus_quad2-set.xml │ ├── plus_quad2.xml │ └── quad.nas └── easystar │ ├── .gitignore │ ├── .quiltrc │ ├── Data │ ├── MOI.gnumeric │ ├── aerodynamics comparison.gnumeric │ └── shadowmaster.ods │ ├── Datcom │ ├── .gitignore │ ├── datcom.dcm │ └── datcom_aero.xml │ ├── Engines │ ├── HB2815-2000.xml │ └── apc6x4.xml │ ├── Init │ ├── cruise.xml │ └── cruise_steady_turn.xml │ ├── Makefile │ ├── Models │ ├── aircraft-ft.ac │ ├── aircraft-m.ac │ ├── aircraft.blend │ ├── model.xml │ └── splash.rgb │ ├── Nasal │ └── systems.nas │ ├── Scripts │ └── cruise.xml │ ├── Systems │ ├── aerodynamics_simple.xml │ ├── flight_control.xml │ └── sound.xml │ ├── easystar │ ├── easystar-set.xml │ ├── easystar.xml │ ├── patches │ ├── aero-fixes │ └── series │ ├── reset.xml │ └── reset_template.xml ├── data ├── easystar_parameters_12mps.txt ├── easystar_test.xml ├── fgout.xml ├── flightgear.xml ├── rascal_test.xml ├── rc_desktop ├── rc_hil └── sf_waypoints.txt ├── modules ├── aircraft.py ├── constants.py ├── fdpexpect.py ├── gcs.py ├── hangar.py ├── noise.py ├── rotmat.py ├── sensors.py └── util.py ├── run_sitl_fw.py ├── runhil.py └── scripts ├── fgStart.sh ├── px4MAVProxy.start.sh └── px4Start.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | *.png 3 | *.pkl 4 | *.pyc 5 | *~ 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##Hardware in the loop tool for PX4 Firmware 2 | 3 | This is a tool for running hardware-in-the-loop (HIL) simulations for the px4 autopilot. 4 | 5 | ###HIL modes: 6 | 7 | * State-level HIL: tests the control and guidance systems. 8 | * Sensor-level HIL: tests the navigation system in addition to the control, and guidance systems. This requires a lot of data to be sent to the vehicle and a high baudrate. 9 | 10 | ## Dependencies 11 | 12 | ### PyMAVLink 13 | 14 | Pymavlink is the python library required for running the runhil.py script, you can install it with easy install or pypi-install 15 | 16 | If you are using a debian based system (e.g. Ubuntu), you can install using pypi-install so that it can be installed as debian package: 17 | 18 | ``` 19 | sudo apt-get install python-stdeb 20 | pypi-install pymavlink 21 | ``` 22 | 23 | If you are using Mac OS / other unix systems: 24 | 25 | ``` 26 | sudo easy_install pymavlink 27 | ``` 28 | 29 | ### JSBSim 30 | 31 | JSBSim is the C++ flight dynamics model. It can be built with cmake/ or autotools. 32 | 33 | ``` 34 | brew install autoconf automake 35 | ``` 36 | 37 | ``` 38 | git clone https://github.com/PX4/jsbsim.git jsbsim 39 | cd jsbsim 40 | ./autogen.sh 41 | make 42 | ``` 43 | 44 | ## Usage 45 | 46 | ### NSH Startup Script 47 | 48 | You must use the startup script found in data/rc. The two main lines added to normal startup are: 49 | ``` 50 | kalman_demo start 51 | control_demo start 52 | ``` 53 | 54 | ### Python Script 55 | 56 | This python script runhil.py is used for conducting HIL. Both sensor-level and state-level HIL are supported. You can view the runhil.py usage with: 57 | ``` 58 | runhil.py -h 59 | ``` 60 | 61 | A call to runhil.py might look like this: 62 | ``` 63 | ./runhil.py --waypoints data/sf_waypoints.txt --master /dev/ttyUSB1 --gcs localhost:14550 --mode sensor 64 | ``` 65 | 66 | Explanation: 67 | * load the given waypoints in data/sf_waypoints.txt, NOTE: QGC waypoints are not compatible with pymavlink currently, you simply need to change the version number in the file to 110 if it is 120 68 | * connect to the px4 autopilot on usb port 1 69 | * setup external ground station communication of localhost:14550 udp. 70 | * mode sensor says do sensor-level hardware-in-the-loop (HIL), this can be set to state as well 71 | 72 | ### GroundControl Interface 73 | Note that the script defaults to opening a mavlink slave port on udp:14550, this is the default udp port for QGroundControl. If you start QGC, it should start communicating with runhil.py automatically. 74 | 75 | ## Notes 76 | 77 | ### TODO: 78 | 79 | * Magnetometer measurement model doesn't depend on lat/lot yet. 80 | * Add noise. 81 | * Initialization routines for EKF. 82 | 83 | ### Source 84 | 85 | This uses pymavlink and is based off of MAVProxy/ ardupilotemga SITL code. 86 | -------------------------------------------------------------------------------- /aircraft/Rascal/Dialogs/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rascal-config 5 | vbox 6 | 40 7 | 40 8 | 9 | 10 | hbox 11 | 12 | true 13 | 14 | 15 | 16 | 17 | 18 | true 19 | 20 | 33 | 34 | 35 | 36 | 37 | 38 | table 39 | 40 | 41 | 42 | 0 0 43 | left 44 | 45 | /ugear/settings/ap-enable 46 | true 47 | 48 | dialog-apply 49 | 50 | 51 | 52 | 53 | 54 | 1 0 55 | left 56 | 57 | /ugear/settings/turret-enable 58 | true 59 | 60 | dialog-apply 61 | 62 | 63 | 64 | 65 | 66 | 2 0 67 | left 68 | 69 | /sim/multiplay/generic/int[0] 70 | true 71 | 72 | dialog-apply 73 | 74 | 75 | 76 | 77 | 78 | 3 0 79 | left 80 | 81 | /sim/multiplay/generic/int[1] 82 | true 83 | 84 | dialog-apply 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /aircraft/Rascal/Engines/18x8.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 0.00085 14 | 18.0 15 | 2 16 | 30 17 | 30 18 | 19 | 20 | 21 | 0.0 0.0776 22 | 0.1 0.0744 23 | 0.2 0.0712 24 | 0.3 0.0655 25 | 0.4 0.0588 26 | 0.5 0.0518 27 | 0.6 0.0419 28 | 0.7 0.0318 29 | 0.8 0.0172 30 | 1.0 -0.0058 31 | 1.4 -0.0549 32 | 33 |
34 | 35 | 36 | 37 | 0.0 0.0902 38 | 0.1 0.0893 39 | 0.2 0.0880 40 | 0.3 0.0860 41 | 0.4 0.0810 42 | 0.5 0.0742 43 | 0.6 0.0681 44 | 0.7 0.0572 45 | 0.8 0.0467 46 | 1.0 0.0167 47 | 1.4 -0.0803 48 | 49 |
50 | 51 |
52 | -------------------------------------------------------------------------------- /aircraft/Rascal/Engines/Zenoah_G-26A.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2207.27 8 | 9 | -------------------------------------------------------------------------------- /aircraft/Rascal/Models/Rascal.rgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/Rascal/Models/Rascal.rgb -------------------------------------------------------------------------------- /aircraft/Rascal/Models/Rascal110.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Rascal110-000-013.ac 6 | 7 | 8 | Aircraft/Rascal/Models/smokeW.xml 9 | 10 | 2.0 11 | 0.0 12 | 0.0 13 | 0 14 | 0 15 | 0 16 | 17 | 18 | 19 | 20 | rotate 21 | L_Aileron 22 | /surface-positions/left-aileron-pos-norm 23 | 20.0 24 |
25 | 0.735 26 | -0.450 27 | 0.139 28 |
29 | 30 | 0.037 31 | 1.0 32 | -0.029 33 | 34 |
35 | 36 | 37 | rotate 38 | R_Aileron 39 | /surface-positions/right-aileron-pos-norm 40 | 20.0 41 |
42 | 0.735 43 | 0.450 44 | 0.139 45 |
46 | 47 | -0.037 48 | 1.0 49 | 0.029 50 | 51 |
52 | 53 | 54 | rotate 55 | Elevator 56 | /surface-positions/elevator-pos-norm 57 | 35.0 58 |
59 | 1.752 60 | 0.0 61 | 0.051 62 |
63 | 64 | 0.0 65 | 1.0 66 | 0.0 67 | 68 |
69 | 70 | 71 | rotate 72 | Rudder 73 | /surface-positions/rudder-pos-norm 74 | 35.0 75 |
76 | 1.752 77 | 0.0 78 | 0.0 79 |
80 | 81 | 0.0 82 | 0.0 83 | 1.0 84 | 85 |
86 | 87 |
88 | -------------------------------------------------------------------------------- /aircraft/Rascal/Models/Trajectory-Marker.ac: -------------------------------------------------------------------------------- 1 | AC3Db 2 | MATERIAL "ac3dmat9" rgb 0 0 1 amb 0 0 1 emis 0 0 1 spec 0 0 1 shi 0 trans 0 3 | MATERIAL "ac3dmat3" rgb 1 0 0 amb 1 0 0 emis 1 0 0 spec 1 0 0 shi 0 trans 0 4 | OBJECT world 5 | kids 2 6 | OBJECT poly 7 | name "line" 8 | loc 0 0.5 0 9 | numvert 2 10 | 0 0.5 0 11 | 0 -0.5 0 12 | numsurf 1 13 | SURF 0x22 14 | mat 0 15 | refs 2 16 | 0 0 1 17 | 1 0 0 18 | kids 0 19 | OBJECT poly 20 | name "line" 21 | numvert 2 22 | 0 0 -3 23 | 0 0 3 24 | numsurf 1 25 | SURF 0x22 26 | mat 1 27 | refs 2 28 | 0 0 1 29 | 1 0 0 30 | kids 0 31 | -------------------------------------------------------------------------------- /aircraft/Rascal/Models/Trajectory-Marker.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Trajectory-Marker.ac 8 | 9 | 10 | -------------------------------------------------------------------------------- /aircraft/Rascal/Models/smokeW.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | smoke 10 | 11 | 12 | 0.000 13 | 0.000 14 | -0.000 15 | 0.000 16 | 0.000 17 | 0.000 18 | 19 | 20 | smoke.png 21 | 22 | 23 | sim/multiplay/generic/int[0] 24 | 25 | 26 | false 27 | false 28 | billboard 29 | world 30 | 31 | 32 | point 33 | 34 | 35 | 36 | 10 37 | 86 38 | -1.5 39 | 8 40 | 41 | 10 42 | 2.5 43 | 44 | 45 | 5 46 | 5 47 | 5 48 | 60 49 | 60 50 | 60 51 | 52 | 53 | 54 | 55 | 56 | 100 57 | 1 58 | 59 | 60 | 61 | 62 | 63 | 64 | 0.9 65 | 0.9 66 | 0.9 67 | 0.3 68 | 69 | 70 | 0.3 71 | 72 | 73 | 74 | 75 | 76 | 0.900 77 | 0.900 78 | 0.900 79 | 0.001 80 | 81 | 82 | 10.0 83 | 84 | 85 | 86 | 87 | 60 88 | 89 | 90 | 0.001 91 | 1.0 92 | 93 | 94 | 95 | air 96 | false 97 | true 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /aircraft/Rascal/README.Rascal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/Rascal/README.Rascal -------------------------------------------------------------------------------- /aircraft/Rascal/Rascal-keyboard.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Ctrl-I 7 | Show configuration dialog 8 | 9 | nasal 10 | 11 | 12 | 13 | 14 | 15 | S 16 | Toggle smoke 17 | 18 | property-toggle 19 | sim/multiplay/generic/int[0] 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /aircraft/Rascal/Rascal-submodels.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | trajectory marker 7 | Aircraft/Rascal/Models/Trajectory-Marker.xml 8 | /sim/multiplay/generic/int[1] 9 | 0 10 | true 11 | 0.75 12 | -1 13 | -0.5 14 | 0.0 15 | -0.08 16 | 0.0 17 | 0.0 18 | 1000000000.00 19 | 600 20 | 32 21 | false 22 | false 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /aircraft/Rascal/Rascal110-JSBSim-set.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | Rascal 110 (R/C) 14 | Lee Elliot (3D) Dave Culp (JSBsim dynamics) and Curt Olson 15 | 0.1 16 | 400 17 | 18 | 19 | Aircraft/Rascal/Rascal110-splash.rgb 20 | 21 | 22 | jsb 23 | Rascal110-JSBSim 24 | 0.8 25 | 26 | 27 | 28 | Aircraft/Rascal/Systems/110-autopilot.xml 29 | 30 | 31 | Aircraft/Rascal/Systems/electrical.xml 32 | 33 | 34 | 35 | 36 | Aircraft/Generic/generic-sound.xml 37 | 38 | 39 | 40 | false 41 | 42 | 43 | 44 | Aircraft/Rascal/Models/Rascal110.xml 45 | 46 | 47 | 48 | true 49 | 50 | 0.0 51 | -0.15 52 | 0.9 53 | 0 54 | 55 | 56 | 57 | 58 | 1 59 | Aircraft/Rascal/Rascal-submodels.xml 60 | 61 | 62 | 63 | 64 | 0.5 65 | 66 | 67 | 68 | 69 | 70 | 0.5 71 | 72 | 73 | 74 | 75 | 76 | 0.5 77 | 78 | 79 | 80 | 81 | 82 | 0.5 83 | 84 | 85 | 86 | 87 | 88 | 0.5 89 | 90 | 91 | 92 | 93 | 94 | 0.5 95 | 96 | 97 | 98 | 99 | 1 100 | 101 | 0 102 | 0 103 | 104 | 105 | 106 | 107 | Rascal 110 (Sig Mfg) 108 | Cruise speed: 60 kts 109 | Never-exceed (Vne): 85 kts 110 | Best Glide (Vglide): 20 kts 111 | Maneuvering (Va): 50 kts 112 | Approach speed: 20-25 kts 113 | Stall speed (Vs): 15 kts 114 | 115 | 116 | 117 | 118 | 119 | 120 | Aircraft/Rascal/Systems/main.nas 121 | Aircraft/Rascal/Systems/airdata.nas 122 | Aircraft/Rascal/Systems/ugear.nas 123 | 140 | 141 | 142 | 143 | 144 | 145 | 2 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -0.01 156 | 0.00 157 | 0.00 158 | 159 | 160 | 161 | 3 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 700 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /aircraft/Rascal/Rascal110-splash.rgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/Rascal/Rascal110-splash.rgb -------------------------------------------------------------------------------- /aircraft/Rascal/Systems/airdata.nas: -------------------------------------------------------------------------------- 1 | var last_time = 0.0; 2 | var last_speed = 0.0; 3 | var speed_sensed = 0.0; 4 | var sensor_step = 1.0; 5 | var speed_filt = 0.0; 6 | var accel_filt = 0.0; 7 | 8 | var compute_airspeed_accel = func( speed_filt, dt ) { 9 | # print ( "computing forward acceleration ", dt ); 10 | 11 | var delta_speed = speed_filt - last_speed; 12 | last_speed = speed_filt; 13 | 14 | var accel = delta_speed / dt; 15 | 16 | return accel; 17 | } 18 | 19 | 20 | var update_airdata = func( dt ) { 21 | # crude model of a noisy electronic pitot tube 22 | sensed_speed = getprop("/velocities/airspeed-kt"); 23 | var r = rand(); 24 | if ( r < 0.3333 ) { 25 | sensed_speed = sensed_speed - sensor_step; 26 | } elsif ( r > 0.6666 ) { 27 | sensed_speed = sensed_speed + sensor_step; 28 | } 29 | 30 | speed_filt = 0.97 * speed_filt + 0.03 * sensed_speed; 31 | 32 | var sensed_accel = 0.0; 33 | if ( dt > 0 ) { 34 | sensed_accel = compute_airspeed_accel( speed_filt, dt ); 35 | } 36 | 37 | accel_filt = 0.97 * accel_filt + 0.03 * sensed_accel; 38 | 39 | setprop("/accelerations/airspeed-ktps", accel_filt); 40 | } 41 | 42 | round10 = func(v) { 43 | if (v == nil) return 0; 44 | return 0.1*int(v*10); 45 | } 46 | 47 | round100 = func(v) { 48 | if (v == nil) return 0; 49 | return 0.01*int(v*100); 50 | } 51 | 52 | var update_vars = func( dt ) { 53 | asl_ft = getprop("/position/altitude-ft"); 54 | ground = getprop("/position/ground-elev-ft"); 55 | agl_m = (asl_ft - ground) * 0.3048; 56 | 57 | setprop("/apm/altitude", round10(agl_m)); 58 | 59 | setprop("/apm/pitch", round10(getprop("/orientation/pitch-deg"))); 60 | setprop("/apm/roll", round10(getprop("/orientation/roll-deg"))); 61 | setprop("/apm/heading", round10(getprop("/orientation/heading-deg"))); 62 | 63 | setprop("/apm/aileron", round100(getprop("/surface-positions/right-aileron-pos-norm"))); 64 | setprop("/apm/elevator", round100(getprop("/surface-positions/elevator-pos-norm"))); 65 | setprop("/apm/rudder", round100(getprop("/surface-positions/rudder-pos-norm"))); 66 | setprop("/apm/throttle", round10(getprop("/engines/engine/rpm"))); 67 | 68 | setprop("/apm/groundspeed", round10(0.514444444*getprop("/instrumentation/gps/indicated-ground-speed-kt"))); 69 | 70 | # airspeed-kt is actually in feet per second (FDM NET bug) 71 | setprop("/apm/airspeed", round10(0.3048*getprop("/velocities/airspeed-kt"))); 72 | } 73 | -------------------------------------------------------------------------------- /aircraft/Rascal/Systems/electrical.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Battery 1 13 | /systems/electrical/suppliers/battery[0] 14 | battery 15 | 28 16 | 60 17 | 18 | 19 | 20 | Alternator 1 21 | /systems/electrical/suppliers/alternator[0] 22 | alternator 23 | /engines/engine[0]/rpm 24 | 28 25 | 60 26 | 27 | 28 | 29 | 30 | 31 | Master Bus 32 | /systems/electrical/outputs/bus[0] 33 | /systems/electrical/outputs/transponder 34 | 35 | 36 | 37 | 38 | 39 | Starter 1 Power 40 | /systems/electrical/outputs/starter[0] 41 | 42 | 43 | 44 | Landing Light Power 45 | /systems/electrical/outputs/landing-light 46 | 47 | 48 | 49 | Beacon Power 50 | /systems/electrical/outputs/beacon 51 | 52 | 53 | 54 | Strobe Lights Power 55 | /systems/electrical/outputs/strobe-lights 56 | 57 | 58 | 59 | Taxi Lights Power 60 | /systems/electrical/outputs/taxi-lights 61 | 62 | 63 | 64 | Pitot Heat Power 65 | /systems/electrical/outputs/pitot-heat 66 | 67 | 68 | 69 | 70 | 71 | 72 | Alternator 1 73 | Master Bus 74 | 75 | /controls/engines/engine[0]/master-alt 76 | 77 | 78 | 79 | 80 | Battery 1 81 | Master Bus 82 | 83 | /controls/engines/engine[0]/master-bat 84 | 85 | 86 | 87 | 88 | 89 | 90 | Master Bus 91 | Starter 1 Power 92 | 93 | /controls/engines/engine[0]/starter 94 | off 95 | 96 | 97 | 98 | 99 | 100 | 101 | Master Bus 102 | Landing Light Power 103 | 104 | /controls/switches/landing-light 105 | 106 | 107 | 108 | 109 | Master Bus 110 | Beacon Power 111 | 112 | /controls/switches/flashing-beacon 113 | 114 | 115 | 116 | 117 | Master Bus 118 | Strobe Lights Power 119 | 120 | /controls/switches/strobe-lights 121 | 122 | 123 | 124 | 125 | Master Bus 126 | Taxi Lights Power 127 | 128 | /controls/switches/taxi-lights 129 | 130 | 131 | 132 | 133 | Master Bus 134 | Pitot Heat Power 135 | 136 | /controls/switches/pitot-heat 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /aircraft/Rascal/Systems/main.nas: -------------------------------------------------------------------------------- 1 | var dialog = gui.Dialog.new("/sim/gui/dialogs/rascal/config/dialog", 2 | "Aircraft/Rascal/Dialogs/config.xml"); 3 | 4 | var last_time = 0.0; 5 | 6 | 7 | var main_loop = func { 8 | var time = getprop("/sim/time/elapsed-sec"); 9 | var dt = time - last_time; 10 | last_time = time; 11 | 12 | update_airdata( dt ); 13 | update_vars( dt ); 14 | update_ugear( dt ); 15 | 16 | settimer(main_loop, 0); 17 | } 18 | 19 | 20 | setlistener("/sim/signals/fdm-initialized", 21 | func { 22 | main_loop(); 23 | }); 24 | -------------------------------------------------------------------------------- /aircraft/Rascal/Systems/ugear.nas: -------------------------------------------------------------------------------- 1 | var update_ugear = func( dt ) { 2 | var max_zoom_rate = 10*dt; 3 | var max_pan_rate = 30*dt; 4 | var max_tilt_rate = 45*dt; 5 | 6 | var ap_enable = props.globals.getNode("/ugear/settings/ap-enable"); 7 | if ( ap_enable == nil ) { 8 | props.globals.initNode("/ugear/settings/ap-enable", 0, "BOOL", 1); 9 | ap_enable = props.globals.getNode("/ugear/settings/ap-enable"); 10 | } 11 | if ( ap_enable.getBoolValue() ) { 12 | setprop( "/controls/flight/aileron", getprop("/ugear/act/aileron") ); 13 | setprop( "/controls/flight/elevator", getprop("/ugear/act/elevator") ); 14 | } 15 | 16 | var turret_enable = props.globals.getNode("/ugear/settings/turret-enable"); 17 | if ( turret_enable == nil ) { 18 | props.globals.initNode("/ugear/settings/turret-enable", 0, "BOOL", 1); 19 | turret_enable = props.globals.getNode("/ugear/settings/turret-enable"); 20 | } 21 | 22 | if ( (getprop("/sim/current-view/name") == "Camera View") 23 | and turret_enable.getBoolValue() ) 24 | { 25 | var target_zoom = getprop("/ugear/act/channel6"); 26 | var target_pan = -getprop("/ugear/act/channel7"); 27 | if ( target_pan < -180.0 ) { target_pan += 360.0; } 28 | if ( target_pan > 180.0 ) { target_pan -= 360.0; } 29 | var target_tilt = -getprop("/ugear/act/channel8"); 30 | var cur_zoom = getprop("/sim/current-view/field-of-view"); 31 | var cur_pan = getprop("/sim/current-view/heading-offset-deg"); 32 | var cur_tilt = getprop("/sim/current-view/pitch-offset-deg"); 33 | var diff = 0.0; 34 | 35 | diff = target_zoom - cur_zoom; 36 | if ( diff > max_zoom_rate ) { diff = max_zoom_rate; } 37 | if ( diff < -max_zoom_rate ) { diff = -max_zoom_rate; } 38 | setprop("/sim/current-view/field-of-view", cur_zoom + diff); 39 | 40 | diff = target_pan - cur_pan; 41 | if ( diff > 180 ) { diff -= 360; } 42 | if ( diff < -180 ) { diff += 360; } 43 | if ( diff > max_pan_rate ) { diff = max_pan_rate; } 44 | if ( diff < -max_pan_rate ) { diff = -max_pan_rate; } 45 | setprop("/sim/current-view/heading-offset-deg", cur_pan + diff); 46 | 47 | diff = target_tilt - cur_tilt; 48 | if ( diff > 90 ) { diff = 90; } 49 | if ( diff < -90 ) { diff = -90; } 50 | if ( diff > max_tilt_rate ) { diff = max_tilt_rate; } 51 | if ( diff < -max_tilt_rate ) { diff = -max_tilt_rate; } 52 | setprop("/sim/current-view/pitch-offset-deg", cur_tilt + diff); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /aircraft/Rascal/reset.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 37.6181747166966929 4 | -122.373104095458984 5 | 300.0 6 | 50.0 7 | 0.0 8 | 0.0 9 | 0.0 10 | 0.0 11 | 12 | -------------------------------------------------------------------------------- /aircraft/Rascal/reset_CMAC.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -35.362851 4 | 149.165223 5 | 0 6 | 0.0 7 | 0.0 8 | 0.0 9 | 0.0 10 | 0.0 11 | 12 | -------------------------------------------------------------------------------- /aircraft/Rascal/reset_template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %(LATITUDE)s 4 | %(LONGITUDE)s 5 | 0 6 | 0.0 7 | 0.0 8 | 0.0 9 | 0.0 10 | %(HEADING)s 11 | 12 | -------------------------------------------------------------------------------- /aircraft/Rascal/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/Rascal/thumbnail.jpg -------------------------------------------------------------------------------- /aircraft/arducopter/Engines/a2830-12.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 187 4 | 5 | -------------------------------------------------------------------------------- /aircraft/arducopter/Engines/prop10x4.5.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 0.000041666666 20 | 21 | 10.0 22 | 2 23 | 1.0 24 | 0.79 25 | 26 | 27 | 0.0 0.0054513 28 | 1.4 0.0054513 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
44 | 45 | 46 | 0.0 0.0028 47 | 0.1 0.0028 48 | 0.2 0.0027 49 | 0.3 0.0027 50 | 0.4 0.0025 51 | 0.5 0.0023 52 | 0.6 0.0021 53 | 0.7 0.0018 54 | 0.8 0.0015 55 | 1.0 0.0005 56 | 1.2 -0.0008 57 | 1.4 -0.0025 58 | 1.6 -0.0042 59 | 60 |
61 | 62 | 63 | 64 | 0.85 1.0 65 | 1.05 0.8 66 | 67 |
68 | 69 | 70 | 71 | 0.85 1.0 72 | 1.05 1.8 73 | 2.00 1.4 74 | 75 |
76 |
77 | -------------------------------------------------------------------------------- /aircraft/arducopter/Models/AutoSave_plus_quad.skp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/AutoSave_plus_quad.skp -------------------------------------------------------------------------------- /aircraft/arducopter/Models/Untitled.ac: -------------------------------------------------------------------------------- 1 | AC3Db 2 | MATERIAL "default" rgb 0.72 0.72 0.72 amb 0.8 0.8 0.8 emis 0.08 0.08 0.08 spec 0.2 0.2 0.2 shi 128 trans 0 3 | MATERIAL "material.006"1"1" rgb 0.0000 0.0000 0.0000 amb 0.0000 0.0000 0.0000 emis 0.0000 0.0000 0.0000 spec 0.2 0.2 0.2 shi 128 trans 0.0000 4 | OBJECT world 5 | kids 1 6 | OBJECT poly 7 | name "blah" 8 | numvert 88 9 | 0.008832 0.001373 -0.000873 10 | 0.008506 0.000990 -0.000881 11 | 0.009033 0.001338 -0.000893 12 | 0.008326 0.001009 -0.000823 13 | 0.007376 -0.000207 -0.000850 14 | 0.007229 -0.000460 -0.000812 15 | 0.007268 -0.000476 -0.000806 16 | 0.007489 -0.000258 -0.000838 17 | 0.007554 0.000049 -0.000887 18 | 0.009654 0.002468 -0.000833 19 | 0.009255 0.001925 -0.000848 20 | 0.009734 0.002440 -0.000831 21 | 0.009103 0.001954 -0.000835 22 | 0.009555 0.002483 -0.000837 23 | 0.008591 0.001436 -0.000825 24 | 0.008638 0.001416 -0.000829 25 | 0.009076 0.001982 -0.000840 26 | 0.009396 0.001900 -0.000860 27 | 0.005825 -0.001719 -0.000888 28 | 0.005965 -0.001746 -0.000876 29 | 0.005486 -0.002262 -0.000867 30 | 0.006389 -0.001191 -0.000892 31 | 0.006188 -0.001154 -0.000911 32 | 0.009024 0.001954 -0.000833 33 | 0.009502 0.002462 -0.000841 34 | 0.008560 0.001453 -0.000824 35 | 0.008093 0.000346 -0.000945 36 | 0.007752 0.000090 -0.000908 37 | 0.007754 0.000168 -0.000919 38 | 0.008097 0.000505 -0.000954 39 | 0.008326 0.000640 -0.000974 40 | 0.007883 0.000406 -0.000928 41 | 0.006630 -0.001281 -0.000850 42 | 0.006117 -0.001776 -0.000863 43 | 0.006144 -0.001803 -0.000868 44 | 0.006660 -0.001276 -0.000843 45 | 0.006197 -0.001776 -0.000860 46 | 0.007844 0.000385 -0.000848 47 | 0.007963 0.000343 -0.000869 48 | 0.007663 0.000128 -0.000889 49 | 0.007952 0.000649 -0.000800 50 | 0.007991 0.000634 -0.000806 51 | 0.007731 0.000435 -0.000835 52 | 0.007128 -0.000157 -0.000946 53 | 0.006895 -0.000448 -0.000980 54 | 0.007044 -0.000422 -0.000905 55 | 0.008263 0.001060 -0.000809 56 | 0.008280 0.001025 -0.000814 57 | 0.008638 0.001456 -0.000843 58 | 0.008486 0.001037 -0.000911 59 | 0.008683 0.000994 -0.000933 60 | 0.005665 -0.002304 -0.000873 61 | 0.005718 -0.002283 -0.000876 62 | 0.006714 -0.000807 -0.000893 63 | 0.006894 -0.000833 -0.000835 64 | 0.006735 -0.000851 -0.000924 65 | 0.006934 -0.000873 -0.000832 66 | 0.006582 -0.001277 -0.000862 67 | 0.007030 -0.000596 -0.000896 68 | 0.007305 -0.000350 -0.000868 69 | 0.006583 -0.001239 -0.000848 70 | 0.007180 -0.000444 -0.000827 71 | 0.006957 -0.000886 -0.000822 72 | 0.005693 -0.002293 -0.000875 73 | 0.006097 -0.001829 -0.000868 74 | 0.007124 -0.000315 -0.000958 75 | 0.007515 -0.000219 -0.000874 76 | 0.007519 -0.000149 -0.000909 77 | 0.007338 -0.000219 -0.000930 78 | 0.006538 -0.000807 -0.000946 79 | 0.009124 0.002008 -0.000839 80 | 0.009527 0.002472 -0.000839 81 | 0.007257 -0.000163 -0.000871 82 | 0.007466 0.000089 -0.000906 83 | 0.008176 0.000606 -0.000900 84 | 0.008040 0.000619 -0.000821 85 | 0.008191 0.000779 -0.000888 86 | 0.007915 0.000530 -0.000864 87 | 0.007328 -0.000058 -0.000926 88 | 0.007560 0.000012 -0.000898 89 | 0.007520 -0.000273 -0.000840 90 | 0.007581 0.000176 -0.000871 91 | 0.007657 0.000166 -0.000898 92 | 0.007636 0.000000 -0.000871 93 | 0.005566 -0.002290 -0.000869 94 | 0.007705 0.000400 -0.000873 95 | 0.007656 0.000213 -0.000903 96 | 0.007701 0.000450 -0.000838 97 | numsurf 166 98 | SURF 0x30 99 | mat 1 100 | refs 3 101 | 0 0 0 102 | 1 0 0 103 | 2 0 0 104 | SURF 0x30 105 | mat 1 106 | refs 3 107 | 0 0 0 108 | 3 0 0 109 | 1 0 0 110 | SURF 0x30 111 | mat 1 112 | refs 3 113 | 4 0 0 114 | 5 0 0 115 | 6 0 0 116 | SURF 0x30 117 | mat 1 118 | refs 3 119 | 4 0 0 120 | 6 0 0 121 | 7 0 0 122 | SURF 0x30 123 | mat 1 124 | refs 3 125 | 8 0 0 126 | 4 0 0 127 | 7 0 0 128 | SURF 0x30 129 | mat 1 130 | refs 3 131 | 9 0 0 132 | 10 0 0 133 | 11 0 0 134 | SURF 0x30 135 | mat 1 136 | refs 3 137 | 9 0 0 138 | 12 0 0 139 | 10 0 0 140 | SURF 0x30 141 | mat 1 142 | refs 3 143 | 13 0 0 144 | 12 0 0 145 | 9 0 0 146 | SURF 0x30 147 | mat 1 148 | refs 3 149 | 12 0 0 150 | 14 0 0 151 | 15 0 0 152 | SURF 0x30 153 | mat 1 154 | refs 3 155 | 16 0 0 156 | 14 0 0 157 | 12 0 0 158 | SURF 0x30 159 | mat 1 160 | refs 3 161 | 10 0 0 162 | 0 0 0 163 | 17 0 0 164 | SURF 0x30 165 | mat 1 166 | refs 3 167 | 10 0 0 168 | 15 0 0 169 | 0 0 0 170 | SURF 0x30 171 | mat 1 172 | refs 3 173 | 18 0 0 174 | 19 0 0 175 | 20 0 0 176 | SURF 0x30 177 | mat 1 178 | refs 3 179 | 21 0 0 180 | 19 0 0 181 | 18 0 0 182 | SURF 0x30 183 | mat 1 184 | refs 3 185 | 22 0 0 186 | 21 0 0 187 | 18 0 0 188 | SURF 0x30 189 | mat 1 190 | refs 3 191 | 16 0 0 192 | 14 0 0 193 | 23 0 0 194 | SURF 0x30 195 | mat 1 196 | refs 3 197 | 24 0 0 198 | 16 0 0 199 | 23 0 0 200 | SURF 0x30 201 | mat 1 202 | refs 3 203 | 23 0 0 204 | 14 0 0 205 | 25 0 0 206 | SURF 0x30 207 | mat 1 208 | refs 3 209 | 26 0 0 210 | 27 0 0 211 | 28 0 0 212 | SURF 0x30 213 | mat 1 214 | refs 3 215 | 29 0 0 216 | 26 0 0 217 | 28 0 0 218 | SURF 0x30 219 | mat 1 220 | refs 3 221 | 30 0 0 222 | 26 0 0 223 | 29 0 0 224 | SURF 0x30 225 | mat 1 226 | refs 3 227 | 29 0 0 228 | 28 0 0 229 | 31 0 0 230 | SURF 0x30 231 | mat 1 232 | refs 3 233 | 32 0 0 234 | 33 0 0 235 | 34 0 0 236 | SURF 0x30 237 | mat 1 238 | refs 3 239 | 35 0 0 240 | 32 0 0 241 | 34 0 0 242 | SURF 0x30 243 | mat 1 244 | refs 3 245 | 35 0 0 246 | 34 0 0 247 | 36 0 0 248 | SURF 0x30 249 | mat 1 250 | refs 3 251 | 37 0 0 252 | 27 0 0 253 | 38 0 0 254 | SURF 0x30 255 | mat 1 256 | refs 3 257 | 37 0 0 258 | 39 0 0 259 | 27 0 0 260 | SURF 0x30 261 | mat 1 262 | refs 3 263 | 40 0 0 264 | 37 0 0 265 | 41 0 0 266 | SURF 0x30 267 | mat 1 268 | refs 3 269 | 40 0 0 270 | 42 0 0 271 | 37 0 0 272 | SURF 0x30 273 | mat 1 274 | refs 3 275 | 42 0 0 276 | 39 0 0 277 | 37 0 0 278 | SURF 0x30 279 | mat 1 280 | refs 3 281 | 43 0 0 282 | 44 0 0 283 | 45 0 0 284 | SURF 0x30 285 | mat 1 286 | refs 3 287 | 46 0 0 288 | 47 0 0 289 | 40 0 0 290 | SURF 0x30 291 | mat 1 292 | refs 3 293 | 14 0 0 294 | 47 0 0 295 | 46 0 0 296 | SURF 0x30 297 | mat 1 298 | refs 3 299 | 48 0 0 300 | 47 0 0 301 | 14 0 0 302 | SURF 0x30 303 | mat 1 304 | refs 3 305 | 49 0 0 306 | 50 0 0 307 | 30 0 0 308 | SURF 0x30 309 | mat 1 310 | refs 3 311 | 0 0 0 312 | 50 0 0 313 | 49 0 0 314 | SURF 0x30 315 | mat 1 316 | refs 3 317 | 0 0 0 318 | 2 0 0 319 | 50 0 0 320 | SURF 0x30 321 | mat 1 322 | refs 3 323 | 33 0 0 324 | 51 0 0 325 | 34 0 0 326 | SURF 0x30 327 | mat 1 328 | refs 3 329 | 36 0 0 330 | 34 0 0 331 | 51 0 0 332 | SURF 0x30 333 | mat 1 334 | refs 3 335 | 36 0 0 336 | 51 0 0 337 | 52 0 0 338 | SURF 0x30 339 | mat 1 340 | refs 3 341 | 53 0 0 342 | 22 0 0 343 | 21 0 0 344 | SURF 0x30 345 | mat 1 346 | refs 3 347 | 53 0 0 348 | 21 0 0 349 | 54 0 0 350 | SURF 0x30 351 | mat 1 352 | refs 3 353 | 55 0 0 354 | 56 0 0 355 | 57 0 0 356 | SURF 0x30 357 | mat 1 358 | refs 3 359 | 58 0 0 360 | 56 0 0 361 | 55 0 0 362 | SURF 0x30 363 | mat 1 364 | refs 3 365 | 6 0 0 366 | 56 0 0 367 | 58 0 0 368 | SURF 0x30 369 | mat 1 370 | refs 3 371 | 59 0 0 372 | 6 0 0 373 | 58 0 0 374 | SURF 0x30 375 | mat 1 376 | refs 3 377 | 44 0 0 378 | 58 0 0 379 | 55 0 0 380 | SURF 0x30 381 | mat 1 382 | refs 3 383 | 54 0 0 384 | 21 0 0 385 | 60 0 0 386 | SURF 0x30 387 | mat 1 388 | refs 3 389 | 61 0 0 390 | 54 0 0 391 | 5 0 0 392 | SURF 0x30 393 | mat 1 394 | refs 3 395 | 5 0 0 396 | 54 0 0 397 | 56 0 0 398 | SURF 0x30 399 | mat 1 400 | refs 3 401 | 5 0 0 402 | 56 0 0 403 | 6 0 0 404 | SURF 0x30 405 | mat 1 406 | refs 3 407 | 6 0 0 408 | 56 0 0 409 | 62 0 0 410 | SURF 0x30 411 | mat 1 412 | refs 3 413 | 54 0 0 414 | 60 0 0 415 | 56 0 0 416 | SURF 0x30 417 | mat 1 418 | refs 3 419 | 25 0 0 420 | 46 0 0 421 | 14 0 0 422 | SURF 0x30 423 | mat 1 424 | refs 3 425 | 17 0 0 426 | 0 0 0 427 | 2 0 0 428 | SURF 0x30 429 | mat 1 430 | refs 3 431 | 34 0 0 432 | 63 0 0 433 | 64 0 0 434 | SURF 0x30 435 | mat 1 436 | refs 3 437 | 65 0 0 438 | 58 0 0 439 | 44 0 0 440 | SURF 0x30 441 | mat 1 442 | refs 3 443 | 66 0 0 444 | 6 0 0 445 | 59 0 0 446 | SURF 0x30 447 | mat 1 448 | refs 3 449 | 67 0 0 450 | 66 0 0 451 | 59 0 0 452 | SURF 0x30 453 | mat 1 454 | refs 3 455 | 67 0 0 456 | 59 0 0 457 | 68 0 0 458 | SURF 0x30 459 | mat 1 460 | refs 3 461 | 45 0 0 462 | 44 0 0 463 | 69 0 0 464 | SURF 0x30 465 | mat 1 466 | refs 3 467 | 45 0 0 468 | 69 0 0 469 | 53 0 0 470 | SURF 0x30 471 | mat 1 472 | refs 3 473 | 45 0 0 474 | 53 0 0 475 | 61 0 0 476 | SURF 0x30 477 | mat 1 478 | refs 3 479 | 61 0 0 480 | 53 0 0 481 | 54 0 0 482 | SURF 0x30 483 | mat 1 484 | refs 3 485 | 69 0 0 486 | 22 0 0 487 | 53 0 0 488 | SURF 0x30 489 | mat 1 490 | refs 3 491 | 44 0 0 492 | 55 0 0 493 | 69 0 0 494 | SURF 0x30 495 | mat 1 496 | refs 3 497 | 69 0 0 498 | 55 0 0 499 | 21 0 0 500 | SURF 0x30 501 | mat 1 502 | refs 3 503 | 13 0 0 504 | 23 0 0 505 | 16 0 0 506 | SURF 0x30 507 | mat 1 508 | refs 3 509 | 13 0 0 510 | 24 0 0 511 | 23 0 0 512 | SURF 0x30 513 | mat 1 514 | refs 3 515 | 13 0 0 516 | 9 0 0 517 | 70 0 0 518 | SURF 0x30 519 | mat 1 520 | refs 3 521 | 70 0 0 522 | 48 0 0 523 | 16 0 0 524 | SURF 0x30 525 | mat 1 526 | refs 3 527 | 71 0 0 528 | 70 0 0 529 | 16 0 0 530 | SURF 0x30 531 | mat 1 532 | refs 3 533 | 48 0 0 534 | 49 0 0 535 | 47 0 0 536 | SURF 0x30 537 | mat 1 538 | refs 3 539 | 65 0 0 540 | 59 0 0 541 | 58 0 0 542 | SURF 0x30 543 | mat 1 544 | refs 3 545 | 68 0 0 546 | 59 0 0 547 | 65 0 0 548 | SURF 0x30 549 | mat 1 550 | refs 3 551 | 72 0 0 552 | 61 0 0 553 | 5 0 0 554 | SURF 0x30 555 | mat 1 556 | refs 3 557 | 72 0 0 558 | 5 0 0 559 | 4 0 0 560 | SURF 0x30 561 | mat 1 562 | refs 3 563 | 73 0 0 564 | 72 0 0 565 | 4 0 0 566 | SURF 0x30 567 | mat 1 568 | refs 3 569 | 73 0 0 570 | 4 0 0 571 | 8 0 0 572 | SURF 0x30 573 | mat 1 574 | refs 3 575 | 73 0 0 576 | 43 0 0 577 | 72 0 0 578 | SURF 0x30 579 | mat 1 580 | refs 3 581 | 43 0 0 582 | 45 0 0 583 | 72 0 0 584 | SURF 0x30 585 | mat 1 586 | refs 3 587 | 72 0 0 588 | 45 0 0 589 | 61 0 0 590 | SURF 0x30 591 | mat 1 592 | refs 3 593 | 74 0 0 594 | 38 0 0 595 | 26 0 0 596 | SURF 0x30 597 | mat 1 598 | refs 3 599 | 75 0 0 600 | 38 0 0 601 | 74 0 0 602 | SURF 0x30 603 | mat 1 604 | refs 3 605 | 30 0 0 606 | 74 0 0 607 | 26 0 0 608 | SURF 0x30 609 | mat 1 610 | refs 3 611 | 49 0 0 612 | 76 0 0 613 | 47 0 0 614 | SURF 0x30 615 | mat 1 616 | refs 3 617 | 47 0 0 618 | 76 0 0 619 | 40 0 0 620 | SURF 0x30 621 | mat 1 622 | refs 3 623 | 76 0 0 624 | 77 0 0 625 | 40 0 0 626 | SURF 0x30 627 | mat 1 628 | refs 3 629 | 49 0 0 630 | 30 0 0 631 | 76 0 0 632 | SURF 0x30 633 | mat 1 634 | refs 3 635 | 76 0 0 636 | 30 0 0 637 | 29 0 0 638 | SURF 0x30 639 | mat 1 640 | refs 3 641 | 76 0 0 642 | 29 0 0 643 | 77 0 0 644 | SURF 0x30 645 | mat 1 646 | refs 3 647 | 73 0 0 648 | 78 0 0 649 | 43 0 0 650 | SURF 0x30 651 | mat 1 652 | refs 3 653 | 78 0 0 654 | 65 0 0 655 | 43 0 0 656 | SURF 0x30 657 | mat 1 658 | refs 3 659 | 43 0 0 660 | 65 0 0 661 | 44 0 0 662 | SURF 0x30 663 | mat 1 664 | refs 3 665 | 78 0 0 666 | 68 0 0 667 | 65 0 0 668 | SURF 0x30 669 | mat 1 670 | refs 3 671 | 11 0 0 672 | 17 0 0 673 | 10 0 0 674 | SURF 0x30 675 | mat 1 676 | refs 3 677 | 10 0 0 678 | 17 0 0 679 | 0 0 0 680 | SURF 0x30 681 | mat 1 682 | refs 3 683 | 17 0 0 684 | 2 0 0 685 | 0 0 0 686 | SURF 0x30 687 | mat 1 688 | refs 3 689 | 79 0 0 690 | 67 0 0 691 | 68 0 0 692 | SURF 0x30 693 | mat 1 694 | refs 3 695 | 79 0 0 696 | 68 0 0 697 | 78 0 0 698 | SURF 0x30 699 | mat 1 700 | refs 3 701 | 73 0 0 702 | 8 0 0 703 | 78 0 0 704 | SURF 0x30 705 | mat 1 706 | refs 3 707 | 66 0 0 708 | 80 0 0 709 | 6 0 0 710 | SURF 0x30 711 | mat 1 712 | refs 3 713 | 56 0 0 714 | 60 0 0 715 | 32 0 0 716 | SURF 0x30 717 | mat 1 718 | refs 3 719 | 56 0 0 720 | 32 0 0 721 | 62 0 0 722 | SURF 0x30 723 | mat 1 724 | refs 3 725 | 62 0 0 726 | 32 0 0 727 | 35 0 0 728 | SURF 0x30 729 | mat 1 730 | refs 3 731 | 56 0 0 732 | 62 0 0 733 | 32 0 0 734 | SURF 0x30 735 | mat 1 736 | refs 3 737 | 56 0 0 738 | 32 0 0 739 | 57 0 0 740 | SURF 0x30 741 | mat 1 742 | refs 3 743 | 42 0 0 744 | 81 0 0 745 | 39 0 0 746 | SURF 0x30 747 | mat 1 748 | refs 3 749 | 31 0 0 750 | 28 0 0 751 | 82 0 0 752 | SURF 0x30 753 | mat 1 754 | refs 3 755 | 9 0 0 756 | 10 0 0 757 | 70 0 0 758 | SURF 0x30 759 | mat 1 760 | refs 3 761 | 70 0 0 762 | 10 0 0 763 | 48 0 0 764 | SURF 0x30 765 | mat 1 766 | refs 3 767 | 10 0 0 768 | 0 0 0 769 | 48 0 0 770 | SURF 0x30 771 | mat 1 772 | refs 3 773 | 9 0 0 774 | 11 0 0 775 | 10 0 0 776 | SURF 0x30 777 | mat 1 778 | refs 3 779 | 8 0 0 780 | 7 0 0 781 | 83 0 0 782 | SURF 0x30 783 | mat 1 784 | refs 3 785 | 79 0 0 786 | 83 0 0 787 | 67 0 0 788 | SURF 0x30 789 | mat 1 790 | refs 3 791 | 15 0 0 792 | 3 0 0 793 | 0 0 0 794 | SURF 0x30 795 | mat 1 796 | refs 3 797 | 3 0 0 798 | 41 0 0 799 | 75 0 0 800 | SURF 0x30 801 | mat 1 802 | refs 3 803 | 47 0 0 804 | 41 0 0 805 | 3 0 0 806 | SURF 0x30 807 | mat 1 808 | refs 3 809 | 47 0 0 810 | 40 0 0 811 | 41 0 0 812 | SURF 0x30 813 | mat 1 814 | refs 3 815 | 46 0 0 816 | 40 0 0 817 | 47 0 0 818 | SURF 0x30 819 | mat 1 820 | refs 3 821 | 15 0 0 822 | 47 0 0 823 | 3 0 0 824 | SURF 0x30 825 | mat 1 826 | refs 3 827 | 14 0 0 828 | 47 0 0 829 | 15 0 0 830 | SURF 0x30 831 | mat 1 832 | refs 3 833 | 14 0 0 834 | 46 0 0 835 | 47 0 0 836 | SURF 0x30 837 | mat 1 838 | refs 3 839 | 16 0 0 840 | 25 0 0 841 | 14 0 0 842 | SURF 0x30 843 | mat 1 844 | refs 3 845 | 16 0 0 846 | 23 0 0 847 | 25 0 0 848 | SURF 0x30 849 | mat 1 850 | refs 3 851 | 13 0 0 852 | 16 0 0 853 | 12 0 0 854 | SURF 0x30 855 | mat 1 856 | refs 3 857 | 26 0 0 858 | 38 0 0 859 | 27 0 0 860 | SURF 0x30 861 | mat 1 862 | refs 3 863 | 64 0 0 864 | 51 0 0 865 | 84 0 0 866 | SURF 0x30 867 | mat 1 868 | refs 3 869 | 19 0 0 870 | 64 0 0 871 | 84 0 0 872 | SURF 0x30 873 | mat 1 874 | refs 3 875 | 57 0 0 876 | 64 0 0 877 | 19 0 0 878 | SURF 0x30 879 | mat 1 880 | refs 3 881 | 21 0 0 882 | 57 0 0 883 | 19 0 0 884 | SURF 0x30 885 | mat 1 886 | refs 3 887 | 19 0 0 888 | 84 0 0 889 | 20 0 0 890 | SURF 0x30 891 | mat 1 892 | refs 3 893 | 77 0 0 894 | 29 0 0 895 | 31 0 0 896 | SURF 0x30 897 | mat 1 898 | refs 3 899 | 41 0 0 900 | 38 0 0 901 | 75 0 0 902 | SURF 0x30 903 | mat 1 904 | refs 3 905 | 41 0 0 906 | 37 0 0 907 | 38 0 0 908 | SURF 0x30 909 | mat 1 910 | refs 3 911 | 32 0 0 912 | 36 0 0 913 | 34 0 0 914 | SURF 0x30 915 | mat 1 916 | refs 3 917 | 36 0 0 918 | 52 0 0 919 | 34 0 0 920 | SURF 0x30 921 | mat 1 922 | refs 3 923 | 22 0 0 924 | 18 0 0 925 | 21 0 0 926 | SURF 0x30 927 | mat 1 928 | refs 3 929 | 21 0 0 930 | 18 0 0 931 | 19 0 0 932 | SURF 0x30 933 | mat 1 934 | refs 3 935 | 21 0 0 936 | 19 0 0 937 | 60 0 0 938 | SURF 0x30 939 | mat 1 940 | refs 3 941 | 60 0 0 942 | 19 0 0 943 | 33 0 0 944 | SURF 0x30 945 | mat 1 946 | refs 3 947 | 18 0 0 948 | 20 0 0 949 | 19 0 0 950 | SURF 0x30 951 | mat 1 952 | refs 3 953 | 69 0 0 954 | 21 0 0 955 | 22 0 0 956 | SURF 0x30 957 | mat 1 958 | refs 3 959 | 55 0 0 960 | 57 0 0 961 | 21 0 0 962 | SURF 0x30 963 | mat 1 964 | refs 3 965 | 57 0 0 966 | 32 0 0 967 | 34 0 0 968 | SURF 0x30 969 | mat 1 970 | refs 3 971 | 48 0 0 972 | 0 0 0 973 | 49 0 0 974 | SURF 0x30 975 | mat 1 976 | refs 3 977 | 16 0 0 978 | 48 0 0 979 | 14 0 0 980 | SURF 0x30 981 | mat 1 982 | refs 3 983 | 6 0 0 984 | 62 0 0 985 | 56 0 0 986 | SURF 0x30 987 | mat 1 988 | refs 3 989 | 19 0 0 990 | 20 0 0 991 | 84 0 0 992 | SURF 0x30 993 | mat 1 994 | refs 3 995 | 19 0 0 996 | 84 0 0 997 | 33 0 0 998 | SURF 0x30 999 | mat 1 1000 | refs 3 1001 | 33 0 0 1002 | 84 0 0 1003 | 51 0 0 1004 | SURF 0x30 1005 | mat 1 1006 | refs 3 1007 | 60 0 0 1008 | 33 0 0 1009 | 32 0 0 1010 | SURF 0x30 1011 | mat 1 1012 | refs 3 1013 | 12 0 0 1014 | 15 0 0 1015 | 10 0 0 1016 | SURF 0x30 1017 | mat 1 1018 | refs 3 1019 | 11 0 0 1020 | 10 0 0 1021 | 17 0 0 1022 | SURF 0x30 1023 | mat 1 1024 | refs 3 1025 | 85 0 0 1026 | 86 0 0 1027 | 81 0 0 1028 | SURF 0x30 1029 | mat 1 1030 | refs 3 1031 | 40 0 0 1032 | 85 0 0 1033 | 87 0 0 1034 | SURF 0x30 1035 | mat 1 1036 | refs 3 1037 | 40 0 0 1038 | 77 0 0 1039 | 85 0 0 1040 | SURF 0x30 1041 | mat 1 1042 | refs 3 1043 | 77 0 0 1044 | 86 0 0 1045 | 85 0 0 1046 | SURF 0x30 1047 | mat 1 1048 | refs 3 1049 | 77 0 0 1050 | 31 0 0 1051 | 86 0 0 1052 | SURF 0x30 1053 | mat 1 1054 | refs 3 1055 | 50 0 0 1056 | 74 0 0 1057 | 30 0 0 1058 | SURF 0x30 1059 | mat 1 1060 | refs 3 1061 | 50 0 0 1062 | 1 0 0 1063 | 74 0 0 1064 | SURF 0x30 1065 | mat 1 1066 | refs 3 1067 | 35 0 0 1068 | 36 0 0 1069 | 32 0 0 1070 | SURF 0x30 1071 | mat 1 1072 | refs 3 1073 | 57 0 0 1074 | 34 0 0 1075 | 64 0 0 1076 | SURF 0x30 1077 | mat 1 1078 | refs 3 1079 | 1 0 0 1080 | 75 0 0 1081 | 74 0 0 1082 | SURF 0x30 1083 | mat 1 1084 | refs 3 1085 | 3 0 0 1086 | 75 0 0 1087 | 1 0 0 1088 | SURF 0x30 1089 | mat 1 1090 | refs 3 1091 | 2 0 0 1092 | 1 0 0 1093 | 50 0 0 1094 | kids 0 1095 | -------------------------------------------------------------------------------- /aircraft/arducopter/Models/Untitled.skp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/Untitled.skp -------------------------------------------------------------------------------- /aircraft/arducopter/Models/Y6_test.skp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/Y6_test.skp -------------------------------------------------------------------------------- /aircraft/arducopter/Models/Y6_test2.skp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/Y6_test2.skp -------------------------------------------------------------------------------- /aircraft/arducopter/Models/_propeller0_.skb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/_propeller0_.skb -------------------------------------------------------------------------------- /aircraft/arducopter/Models/_propeller0_.skp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/_propeller0_.skp -------------------------------------------------------------------------------- /aircraft/arducopter/Models/arducopter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | arducopter.ac 5 | 6 | 0.0 7 | 0 8 | 0.0 9 | 0 10 | 180 11 | 12 | 13 | 14 | noshadow 15 | propeller0 16 | 17 | 18 | spin 19 | propeller0 20 | /engines/engine[0]/rpm 21 | 100 22 | 23 | 0.000 24 | -0.288 25 | 0.046 26 | 0.000 27 | -0.288 28 | 0.012 29 | 30 | 31 | 32 | 33 | noshadow 34 | propeller1 35 | 36 | 37 | spin 38 | propeller1 39 | /engines/engine[1]/rpm 40 | 100 41 | 42 | 0.000 43 | 0.288 44 | 0.046 45 | 0.000 46 | 0.288 47 | 0.012 48 | 49 | 50 | 51 | 52 | noshadow 53 | propeller2 54 | 55 | 56 | spin 57 | propeller2 58 | /engines/engine[2]/rpm 59 | 100 60 | 61 | 0.288 62 | 0.000 63 | 0.046 64 | 0.288 65 | 0.000 66 | 0.012 67 | 68 | 69 | 70 | 71 | noshadow 72 | propeller3 73 | 74 | 75 | spin 76 | propeller3 77 | /engines/engine[3]/rpm 78 | 100 79 | 80 | -0.288 81 | 0.000 82 | 0.046 83 | -0.288 84 | 0.000 85 | 0.012 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /aircraft/arducopter/Models/plus_quad.skb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/plus_quad.skb -------------------------------------------------------------------------------- /aircraft/arducopter/Models/plus_quad.skp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/plus_quad.skp -------------------------------------------------------------------------------- /aircraft/arducopter/Models/plus_quad2.skb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/plus_quad2.skb -------------------------------------------------------------------------------- /aircraft/arducopter/Models/plus_quad2.skp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/plus_quad2.skp -------------------------------------------------------------------------------- /aircraft/arducopter/Models/plus_quad2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | plus_quad2.ac 5 | 6 | 0.0 7 | 0 8 | 0.0 9 | 0 10 | 180 11 | 12 | 13 | 14 | noshadow 15 | prop0 16 | 17 | 18 | spin 19 | prop0 20 | /controls/engines/engine[0]/throttle 21 | 12000 22 | 23 | 0.000 24 | -0.288 25 | 0.046 26 | 0.000 27 | -0.288 28 | 0.012 29 | 30 | 31 | 32 | 33 | noshadow 34 | prop1 35 | 36 | 37 | spin 38 | prop1 39 | /controls/engines/engine[1]/throttle 40 | 12000 41 | 42 | 0.000 43 | 0.288 44 | 0.046 45 | 0.000 46 | 0.288 47 | 0.012 48 | 49 | 50 | 51 | 52 | noshadow 53 | prop2 54 | 55 | 56 | spin 57 | prop2 58 | /controls/engines/engine[2]/throttle 59 | 12000 60 | 61 | 0.288 62 | 0.000 63 | 0.046 64 | 0.288 65 | 0.000 66 | 0.012 67 | 68 | 69 | 70 | 71 | noshadow 72 | prop3 73 | 74 | 75 | spin 76 | prop3 77 | /controls/engines/engine[3]/throttle 78 | 12000 79 | 80 | -0.288 81 | 0.000 82 | 0.046 83 | -0.288 84 | 0.000 85 | 0.012 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /aircraft/arducopter/Models/quad.3ds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/quad.3ds -------------------------------------------------------------------------------- /aircraft/arducopter/Models/quad.skp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/quad.skp -------------------------------------------------------------------------------- /aircraft/arducopter/Models/shareware_output.3ds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/Models/shareware_output.3ds -------------------------------------------------------------------------------- /aircraft/arducopter/README: -------------------------------------------------------------------------------- 1 | This model is based on the arducopter mode from James Goppert, and 2 | adapted for use in the ArduPilot test system. Many thanks to all who 3 | have contributed! 4 | -------------------------------------------------------------------------------- /aircraft/arducopter/arducopter-set.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Arducopter UAV (R/C) 10 | James Goppert 11 | 0.0 12 | experimental 13 | jsb 14 | arducopter 15 | 50 16 | 17 | Aircraft/Generic/generic-sound.xml 18 | 19 | 20 | false 21 | 22 | 23 | Aircraft/arducopter/Models/arducopter.xml 24 | 25 | 26 | true 27 | 28 | 0.0 29 | 0.15 30 | 0.90 31 | 0 32 | 33 | 34 | -5.5 35 | 36 | arducopter UAV 37 | Cruise speed: ? mph 38 | Never-exceed (Vne): ? mph 39 | Best Glide (Vglide): ? mph 40 | Maneuvering (Va): ? mph 41 | Approach speed: ? mph 42 | Stall speed (Vs): ? mph 43 | 44 | 45 | Arducopter UAV DIY Drones/ OPENMAV 46 | Aircraft/arducopter/arducopter.jpg 47 | 48 | 49 | 50 | 51 | 0.00 52 | 53 | 0.00 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 62 | 63 | 64 | 65 | 66 | Payload 67 | 68 | 0.0 69 | 1.0 70 | 71 | 72 | 73 | 74 | Aircraft/arducopter/quad.nas 75 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /aircraft/arducopter/arducopter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/arducopter/arducopter.jpg -------------------------------------------------------------------------------- /aircraft/arducopter/arducopter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | James Goppert 6 | 2010-03-11 7 | 0.0 8 | Arducopter DIY Drones UAV. 9 | 10 | 11 | 0.017 12 | 0.13 13 | 0.0 14 | 0.0 15 | 0.0 16 | 0.0 17 | 0.0 18 | 19 | 0.00 20 | 0.00 21 | 0.00 22 | 23 | 24 | 0.0 25 | 0.0 26 | 0.0 27 | 28 | 29 | 0 30 | 0 31 | 0 32 | 33 | 34 | 35 | 36 | 0.036 37 | 0.036 38 | 0.036 39 | 1.0 40 | 41 | 0.0 42 | 0.0 43 | 0.0 44 | 45 | 46 | 0.0 47 | 48 | 0.0 49 | 0.0 50 | 0.0 51 | 52 | 53 | 54 | 55 | 56 | 57 | -0.283 58 | 0.00 59 | -0.033 60 | 61 | 0.80 62 | 0.50 63 | 800 64 | 7 65 | 300 66 | 67 | 68 | 69 | 0.283 70 | 0.00 71 | -0.033 72 | 73 | 0.80 74 | 0.50 75 | 800 76 | 7 77 | 300 78 | 79 | 80 | 81 | 0.00 82 | 0.283 83 | -0.033 84 | 85 | 0.80 86 | 0.50 87 | 800 88 | 7 89 | 300 90 | 91 | 92 | 93 | 0.00 94 | -0.283 95 | -0.033 96 | 97 | 0.80 98 | 0.50 99 | 800 100 | 7 101 | 300 102 | 103 | 104 | 105 | 106 | 107 | 108 | -0.283 109 | 0.00 110 | 0.00 111 | 112 | 113 | 90.00 114 | 0.00 115 | 0.00 116 | 117 | 0 118 | 119 | 120 | -0.283 121 | 0.00 122 | 0.125 123 | 124 | 125 | 90.00 126 | 0.00 127 | 0.00 128 | 129 | 1 130 | 10 131 | 132 | 133 | 134 | 135 | 0.283 136 | 0.000 137 | 0.000 138 | 139 | 140 | 90.00 141 | 0.00 142 | 0.00 143 | 144 | 0 145 | 146 | 147 | 0.283 148 | 0.000 149 | 0.125 150 | 151 | 152 | 90.00 153 | 0.00 154 | 0.00 155 | 156 | 1 157 | 10 158 | 159 | 160 | 161 | 162 | 0.00 163 | 0.283 164 | 0.00 165 | 166 | 167 | 90.00 168 | 0.00 169 | 0.00 170 | 171 | 0 172 | 173 | 174 | 0.00 175 | 0.283 176 | 0.125 177 | 178 | 179 | 90.00 180 | 0.00 181 | 0.00 182 | 183 | -1 184 | 10 185 | 186 | 187 | 188 | 189 | 0.000 190 | -0.283 191 | 0.000 192 | 193 | 194 | 90.00 195 | 0.00 196 | 0.00 197 | 198 | 0 199 | 200 | 201 | 0.000 202 | -0.283 203 | 0.125 204 | 205 | 206 | 90.00 207 | 0.00 208 | 0.00 209 | 210 | -1 211 | 10 212 | 213 | 214 | 215 | 216 | 0.00 217 | 0.00 218 | -0.07 219 | 220 | 221 | 0.00000000001 222 | 0.0 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | Overall Drag 231 | 232 | aero/qbar-psf 233 | metrics/Sw-sqft 234 | 1 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /aircraft/arducopter/initfile.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | nan 4 | nan 5 | nan 6 | nan 7 | -nan 8 | nan 9 | nan 10 | nan 11 | nan 12 | 13 | -------------------------------------------------------------------------------- /aircraft/arducopter/plus_quad2-set.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Arducopter UAV (R/C) (plus quad) 10 | James Goppert 11 | 0.0 12 | experimental 13 | jsb 14 | plus_quad2 15 | 50 16 | 17 | Aircraft/Generic/generic-sound.xml 18 | 19 | 20 | false 21 | 22 | 23 | Aircraft/arducopter/Models/plus_quad2.xml 24 | 25 | 26 | true 27 | 28 | 0.0 29 | 0.15 30 | 0.90 31 | 0 32 | 33 | 34 | -5.5 35 | 36 | plus_quad UAV 37 | Cruise speed: ? mph 38 | Never-exceed (Vne): ? mph 39 | Best Glide (Vglide): ? mph 40 | Maneuvering (Va): ? mph 41 | Approach speed: ? mph 42 | Stall speed (Vs): ? mph 43 | 44 | 45 | Arducopter UAV DIY Drones/ OPENMAV 46 | Aircraft/arducopter/arducopter.jpg 47 | 48 | 49 | 50 | 51 | 0.00 52 | 53 | 0.00 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 62 | 63 | 64 | 65 | 66 | Payload 67 | 68 | 0.0 69 | 1.0 70 | 71 | 72 | 73 | 74 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /aircraft/arducopter/plus_quad2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | James Goppert 6 | 2010-03-11 7 | 0.0 8 | Arducopter DIY Drones UAV. 9 | 10 | 11 | 0.017 12 | 0.13 13 | 0.0 14 | 0.0 15 | 0.0 16 | 0.0 17 | 0.0 18 | 19 | 0.00 20 | 0.00 21 | 0.00 22 | 23 | 24 | 0.0 25 | 0.0 26 | 0.0 27 | 28 | 29 | 0 30 | 0 31 | 0 32 | 33 | 34 | 35 | 36 | 0.036 37 | 0.036 38 | 0.036 39 | 1.0 40 | 41 | 0.0 42 | 0.0 43 | 0.0 44 | 45 | 46 | 0.0 47 | 48 | 0.0 49 | 0.0 50 | 0.0 51 | 52 | 53 | 54 | 55 | 56 | 57 | -0.283 58 | 0.00 59 | -0.033 60 | 61 | 0.80 62 | 0.50 63 | 800 64 | 7 65 | 300 66 | 67 | 68 | 69 | 0.283 70 | 0.00 71 | -0.033 72 | 73 | 0.80 74 | 0.50 75 | 800 76 | 7 77 | 300 78 | 79 | 80 | 81 | 0.00 82 | 0.283 83 | -0.033 84 | 85 | 0.80 86 | 0.50 87 | 800 88 | 7 89 | 300 90 | 91 | 92 | 93 | 0.00 94 | -0.283 95 | -0.033 96 | 97 | 0.80 98 | 0.50 99 | 800 100 | 7 101 | 300 102 | 103 | 104 | 105 | 106 | 107 | 108 | -0.283 109 | 0.00 110 | 0.00 111 | 112 | 113 | 90.00 114 | 0.00 115 | 0.00 116 | 117 | 0 118 | 119 | 120 | -0.283 121 | 0.00 122 | 0.125 123 | 124 | 125 | 90.00 126 | 0.00 127 | 0.00 128 | 129 | 1 130 | 10 131 | 132 | 133 | 134 | 135 | 0.283 136 | 0.000 137 | 0.000 138 | 139 | 140 | 90.00 141 | 0.00 142 | 0.00 143 | 144 | 0 145 | 146 | 147 | 0.283 148 | 0.000 149 | 0.125 150 | 151 | 152 | 90.00 153 | 0.00 154 | 0.00 155 | 156 | 1 157 | 10 158 | 159 | 160 | 161 | 162 | 0.00 163 | 0.283 164 | 0.00 165 | 166 | 167 | 90.00 168 | 0.00 169 | 0.00 170 | 171 | 0 172 | 173 | 174 | 0.00 175 | 0.283 176 | 0.125 177 | 178 | 179 | 90.00 180 | 0.00 181 | 0.00 182 | 183 | -1 184 | 10 185 | 186 | 187 | 188 | 189 | 0.000 190 | -0.283 191 | 0.000 192 | 193 | 194 | 90.00 195 | 0.00 196 | 0.00 197 | 198 | 0 199 | 200 | 201 | 0.000 202 | -0.283 203 | 0.125 204 | 205 | 206 | 90.00 207 | 0.00 208 | 0.00 209 | 210 | -1 211 | 10 212 | 213 | 214 | 215 | 216 | 0.00 217 | 0.00 218 | -0.07 219 | 220 | 221 | 0.00000000001 222 | 0.0 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | Overall Drag 231 | 232 | aero/qbar-psf 233 | metrics/Sw-sqft 234 | 1 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /aircraft/arducopter/quad.nas: -------------------------------------------------------------------------------- 1 | round10 = func(v) { 2 | if (v == nil) return 0; 3 | return 0.1*int(v*10); 4 | } 5 | 6 | round100 = func(v) { 7 | if (v == nil) return 0; 8 | return 0.01*int(v*100); 9 | } 10 | 11 | var update_quad = func( ) { 12 | asl_ft = getprop("/position/altitude-ft"); 13 | ground = getprop("/position/ground-elev-ft"); 14 | agl_m = (asl_ft - ground) * 0.3048; 15 | 16 | setprop("/apm/altitude", round10(agl_m)); 17 | 18 | setprop("/apm/pitch", round10(getprop("/orientation/pitch-deg"))); 19 | setprop("/apm/roll", round10(getprop("/orientation/roll-deg"))); 20 | setprop("/apm/heading", round10(getprop("/orientation/heading-deg"))); 21 | 22 | # airspeed-kt is actually in feet per second (FDM NET bug) 23 | setprop("/apm/airspeed", round10(0.3048*getprop("/velocities/airspeed-kt"))); 24 | 25 | setprop("/apm/motor_right", round10(getprop("/engines/engine[0]/rpm")/10.0)); 26 | setprop("/apm/motor_left", round10(getprop("/engines/engine[1]/rpm")/10.0)); 27 | setprop("/apm/motor_front", round10(getprop("/engines/engine[2]/rpm")/10.0)); 28 | setprop("/apm/motor_back", round10(getprop("/engines/engine[3]/rpm")/10.0)); 29 | } 30 | 31 | var main_loop = func { 32 | update_quad(); 33 | settimer(main_loop, 0); 34 | } 35 | 36 | 37 | setlistener("/sim/signals/fdm-initialized", 38 | func { 39 | main_loop(); 40 | }); 41 | -------------------------------------------------------------------------------- /aircraft/easystar/.gitignore: -------------------------------------------------------------------------------- 1 | initfile.xml 2 | *.pc 3 | *_simplexTrim.log 4 | *_lin.sce 5 | -------------------------------------------------------------------------------- /aircraft/easystar/.quiltrc: -------------------------------------------------------------------------------- 1 | QUILT_PATCHES=patches 2 | -------------------------------------------------------------------------------- /aircraft/easystar/Data/MOI.gnumeric: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/easystar/Data/MOI.gnumeric -------------------------------------------------------------------------------- /aircraft/easystar/Data/aerodynamics comparison.gnumeric: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/easystar/Data/aerodynamics comparison.gnumeric -------------------------------------------------------------------------------- /aircraft/easystar/Data/shadowmaster.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/easystar/Data/shadowmaster.ods -------------------------------------------------------------------------------- /aircraft/easystar/Datcom/.gitignore: -------------------------------------------------------------------------------- 1 | *.ac 2 | *.csv 3 | *.lfi 4 | *.xml 5 | *.dat 6 | *.out 7 | *.jiff 8 | !*_aero.xml 9 | -------------------------------------------------------------------------------- /aircraft/easystar/Engines/HB2815-2000.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 250 6 | 7 | -------------------------------------------------------------------------------- /aircraft/easystar/Engines/apc6x4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0.0001 5 | 6.0 6 | 2 7 | 30 8 | 30 9 | 0 10 | 40000 11 | 12 | 13 | 14 | 0.0 0.0776 15 | 0.1 0.0744 16 | 0.2 0.0712 17 | 0.3 0.0655 18 | 0.4 0.0588 19 | 0.5 0.0518 20 | 0.6 0.0419 21 | 0.7 0.0318 22 | 0.8 0.0172 23 | 1.0 -0.0058 24 | 1.4 -0.0549 25 | 26 |
27 | 28 | 29 | 30 | 0.0 0.0902 31 | 0.1 0.0893 32 | 0.2 0.0880 33 | 0.3 0.0860 34 | 0.4 0.0810 35 | 0.5 0.0742 36 | 0.6 0.0681 37 | 0.7 0.0572 38 | 0.8 0.0467 39 | 1.0 0.0167 40 | 1.4 -0.0803 41 | 42 |
43 | 44 |
45 | -------------------------------------------------------------------------------- /aircraft/easystar/Init/cruise.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1000.0 4 | 0.0 5 | 45.0 6 | 0.0 7 | 37.62872151 8 | -122.3932853 9 |

0.0

10 | 0.0 11 | 0.0 12 | 0.0 13 | 0.0 14 |
15 | -------------------------------------------------------------------------------- /aircraft/easystar/Init/cruise_steady_turn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1000.0 4 | 0.0 5 | 120.0 6 | 0.0 7 | 37.62872151 8 | -122.3932853 9 |

0.0

10 | 0.0 11 | 1.0 12 | 0.0 13 | 0.0 14 |
15 | -------------------------------------------------------------------------------- /aircraft/easystar/Makefile: -------------------------------------------------------------------------------- 1 | name=easystar 2 | jsbsim_root=../.. 3 | 4 | all: Datcom/datcom_aero.xml 5 | 6 | clean: 7 | rm -rf *.sce *.log Datcom/fort.* Datcom/*.dat \ 8 | Datcom/*.lfi Datcom/*.csv Datcom/*.ac Datcom/*.jiff Datcom/datcom.xml Datcom/*.out 9 | 10 | dist-clean: clean 11 | rm -rf Datcom/datcom_aero.xml 12 | 13 | Datcom/datcom_aero.xml: Datcom/datcom.dcm 14 | quilt pop -a; \ 15 | cd Datcom; \ 16 | datcom datcom.dcm; \ 17 | cd ..; \ 18 | quilt push -a 19 | 20 | Datcom/datcom.jiff: Datcom/datcom_aero.xml 21 | cd Datcom; \ 22 | jiff datcom_aero.xml; 23 | 24 | plot: Datcom/datcom.jiff 25 | nautilus $^ 26 | 27 | install-deps: 28 | sudo apt-get install gnuplot 29 | 30 | jsb-fg-test: 31 | ${jsbsim_root}/scripts/fgrunExt.sh ${name}; \ 32 | sleep 10; \ 33 | jsbsim-cmd --root=${jsbsim_root} --realtime --script=aircraft/${name}/Scripts/cruise.xml --logdirectivefile=data_output/flightgear.xml 34 | 35 | jsb-test: 36 | jsbsim-cmd --root=${jsbsim_root} --realtime --script=aircraft/${name}/Scripts/cruise.xml 37 | 38 | manual-test: 39 | fgfs --heading=120 --airport=KSFO --aircraft=${name} 40 | 41 | format: 42 | find . -type f -regex ".*\.xml" -exec xmlindent -w {} \;; \ 43 | find . -type f -regex ".*\.xml~" -exec rm {} \; 44 | 45 | .PHONY: plot clean dist-clean jsb-test manual-test jsb-fg-test format install-deps 46 | 47 | -------------------------------------------------------------------------------- /aircraft/easystar/Models/aircraft.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/easystar/Models/aircraft.blend -------------------------------------------------------------------------------- /aircraft/easystar/Models/model.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aircraft-m.ac 6 | 7 | 0.0 8 | 0 9 | 0.0 10 | 0 11 | 12 | 13 | 14 | 15 | rotate 16 | Elevator 17 | /surface-positions/elevator-pos-norm 18 | 22.5 19 | 20 | 0.701 21 | -0.174 22 | -0.010 23 | 0.701 24 | 0.0174 25 | -0.010 26 | 27 | 28 | 29 | 30 | 31 | rotate 32 | Rudder 33 | /surface-positions/rudder-pos-norm 34 | 25 35 | 36 | 0.716 37 | 0.000 38 | 0.000 39 | 0.715 40 | 0.000 41 | 0.083 42 | 43 | 44 | 45 | 46 | 47 | noshadow 48 | Propeller.Spinning 49 | 50 | 51 | material 52 | Propeller.Spinning 53 | 0.001 54 | 55 | 0.2 56 | /engines/engine[0]/rpm-norm-inv 57 | 0.0 58 | 1.0 59 | 60 | 61 | 62 | select 63 | Propeller.Spinning 64 | 65 | 66 | /engines/engine[0]/rpm 67 | 350 68 | 69 | 70 | 71 | 72 | spin 73 | Propeller.Spinning 74 | /engines/engine[0]/rpm 75 | 1 76 | 77 | 0.277 78 | 0.000 79 | 0.078 80 | 0.309 81 | 0.000 82 | 0.086 83 | 84 | 85 | 86 | noshadow 87 | Propeller 88 | 89 | 90 | spin 91 | Propeller 92 | /engines/engine[0]/rpm 93 | 1 94 | 95 | 0.277 96 | 0.000 97 | 0.078 98 | 0.309 99 | 0.000 100 | 0.086 101 | 102 | 103 | 104 | select 105 | Propeller 106 | 107 | 108 | /engines/engine[0]/rpm 109 | 400 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /aircraft/easystar/Models/splash.rgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PX4/HIL/f4ae2736f1c3445a41958016e322163e60bf3ce0/aircraft/easystar/Models/splash.rgb -------------------------------------------------------------------------------- /aircraft/easystar/Nasal/systems.nas: -------------------------------------------------------------------------------- 1 | setlistener("/sim/model/start-idling", func(idle){ 2 | var run= idle.getBoolValue(); 3 | if(run){ 4 | Startup(); 5 | }else{ 6 | Shutdown(); 7 | } 8 | },0,0); 9 | 10 | var Startup = func{ 11 | 12 | setprop("controls/electric/engine[0]/generator",1); 13 | setprop("controls/electric/engine[1]/generator",1); 14 | setprop("controls/electric/avionics-switch",1); 15 | setprop("controls/electric/battery-switch",1); 16 | setprop("controls/electric/inverter-switch",1); 17 | 18 | setprop("controls/lighting/instrument-lights",1); 19 | setprop("controls/lighting/nav-lights",1); 20 | setprop("controls/lighting/beacon",1); 21 | setprop("controls/lighting/strobe",1); 22 | 23 | setprop("controls/engines/engine[0]/cutoff",0); 24 | setprop("controls/engines/engine[1]/cutoff",0); 25 | setprop("controls/engines/engine[0]/condition",1); 26 | setprop("controls/engines/engine[1]/condition",1); 27 | setprop("controls/engines/engine[0]/mixture",1); 28 | setprop("controls/engines/engine[1]/mixture",1); 29 | setprop("controls/engines/engine[0]/propeller-pitch",1); 30 | setprop("controls/engines/engine[1]/propeller-pitch",1); 31 | 32 | setprop("engines/engine[0]/running",1); 33 | setprop("engines/engine[1]/running",1); 34 | 35 | setprop("fdm/jsbsim/propulsion/engine[0]/n2",60); 36 | setprop("fdm/jsbsim/propulsion/engine[1]/n2",60); 37 | 38 | setprop("controls/electric/RH-AC-bus",1); 39 | setprop("controls/electric/LH-AC-bus",1); 40 | } 41 | 42 | var Shutdown = func{ 43 | 44 | setprop("controls/electric/engine[0]/generator",0); 45 | setprop("controls/electric/engine[1]/generator",0); 46 | setprop("controls/electric/avionics-switch",0); 47 | setprop("controls/electric/battery-switch",0); 48 | setprop("controls/electric/inverter-switch",0); 49 | 50 | setprop("controls/lighting/instrument-lights",0); 51 | setprop("controls/lighting/nav-lights",0); 52 | setprop("controls/lighting/beacon",0); 53 | setprop("controls/lighting/strobe",0); 54 | 55 | setprop("controls/engines/engine[0]/cutoff",1); 56 | setprop("controls/engines/engine[1]/cutoff",1); 57 | setprop("controls/engines/engine[0]/condition",0); 58 | setprop("controls/engines/engine[1]/condition",0); 59 | setprop("controls/engines/engine[0]/mixture",0); 60 | setprop("controls/engines/engine[1]/mixture",0); 61 | setprop("controls/engines/engine[0]/propeller-pitch",0); 62 | setprop("controls/engines/engine[1]/propeller-pitch",0); 63 | 64 | setprop("engines/engine[0]/running",0); 65 | setprop("engines/engine[1]/running",0); 66 | 67 | setprop("fdm/jsbsim/propulsion/engine[0]/n2",0); 68 | setprop("fdm/jsbsim/propulsion/engine[1]/n2",0); 69 | 70 | setprop("controls/electric/RH-AC-bus",0); 71 | setprop("controls/electric/LH-AC-bus",0); 72 | } 73 | 74 | -------------------------------------------------------------------------------- /aircraft/easystar/Scripts/cruise.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | This is a very simple script that trims the aircraft with running 9 | engines at altitude and runs out to 100 seconds. Some state data 10 | is printed out at ten second intervals. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | simulation/notify-time-trigger 19 | 20 | 21 | simulation/sim-time-sec le 0.1 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | simulation/sim-time-sec gt 0.1 41 | 42 | 43 | propulsion/engine[0]/thrust-lbs 44 | velocities/vc-kts 45 | velocities/vc-fps 46 | velocities/vt-fps 47 | attitude/phi-rad 48 | attitude/theta-rad 49 | attitude/psi-rad 50 | 51 | 52 | 53 | 54 | Output message at 5 second intervals 55 | 56 | propulsion/engine[0]/thrust-lbs 57 | position/h-agl-ft 58 | velocities/vc-kts 59 | velocities/vc-fps 60 | velocities/vt-fps 61 | attitude/phi-rad 62 | attitude/theta-rad 63 | attitude/psi-rad 64 | 65 | simulation/sim-time-sec >= simulation/notify-time-trigger 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /aircraft/easystar/Systems/aerodynamics_simple.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Lift due to alpha 7 | 8 | aero/qbar-psf 9 | metrics/Sw-sqft 10 | 11 | aero/alpha-rad 12 | 13 | -0.20 -0.750 14 | 0.00 0.250 15 | 0.23 1.400 16 | 0.60 0.710 17 | 18 |
19 |
20 |
21 | 22 | 23 | Delta Lift due to flaps 24 | 25 | aero/qbar-psf 26 | metrics/Sw-sqft 27 | fcs/flap-pos-deg 28 | 0.01333 29 | 30 | 31 | 32 | 33 | Delta Lift due to speedbrake 34 | 35 | aero/qbar-psf 36 | metrics/Sw-sqft 37 | fcs/speedbrake-pos-norm 38 | 0 39 | 40 | 41 | 42 | 43 | Lift due to Elevator Deflection 44 | 45 | aero/qbar-psf 46 | metrics/Sw-sqft 47 | fcs/elevator-pos-rad 48 | 0.2 49 | 50 | 51 | 52 |
53 | 54 | 55 | 56 | 57 | Drag at zero lift 58 | 59 | aero/qbar-psf 60 | metrics/Sw-sqft 61 | 62 | aero/alpha-rad 63 | 64 | -1.57 1.500 65 | -0.26 0.036 66 | 0.00 0.028 67 | 0.26 0.036 68 | 1.57 1.500 69 | 70 |
71 |
72 |
73 | 74 | 75 | Induced drag 76 | 77 | aero/qbar-psf 78 | metrics/Sw-sqft 79 | aero/cl-squared 80 | 0.04 81 | 82 | 83 | 84 | 85 | Drag due to mach 86 | 87 | aero/qbar-psf 88 | metrics/Sw-sqft 89 | 90 | velocities/mach 91 | 92 | 0.00 0.000 93 | 0.7 0.000 94 | 1.10 0.023 95 | 1.80 0.015 96 | 97 |
98 |
99 |
100 | 101 | 102 | Drag due to flaps 103 | 104 | aero/qbar-psf 105 | metrics/Sw-sqft 106 | fcs/flap-pos-deg 107 | 0.00100 108 | 109 | 110 | 111 | 112 | Drag due to speedbrakes 113 | 114 | aero/qbar-psf 115 | metrics/Sw-sqft 116 | fcs/speedbrake-pos-norm 117 | 0.028 118 | 119 | 120 | 121 | 122 | Drag due to sideslip 123 | 124 | aero/qbar-psf 125 | metrics/Sw-sqft 126 | 127 | aero/beta-rad 128 | 129 | -1.57 1.230 130 | -0.26 0.050 131 | 0.00 0.000 132 | 0.26 0.050 133 | 1.57 1.230 134 | 135 |
136 |
137 |
138 | 139 | 140 | Drag due to Elevator Deflection 141 | 142 | aero/qbar-psf 143 | metrics/Sw-sqft 144 | fcs/elevator-pos-norm 145 | 0.04 146 | 147 | 148 | 149 |
150 | 151 | 152 | 153 | 154 | Side force due to beta 155 | 156 | aero/qbar-psf 157 | metrics/Sw-sqft 158 | aero/beta-rad 159 | -1 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | Roll moment due to beta 169 | 170 | aero/qbar-psf 171 | metrics/Sw-sqft 172 | metrics/bw-ft 173 | aero/beta-rad 174 | -0.1 175 | 176 | 177 | 178 | 179 | Roll moment due to roll rate 180 | 181 | aero/qbar-psf 182 | metrics/Sw-sqft 183 | metrics/bw-ft 184 | aero/bi2vel 185 | velocities/p-aero-rad_sec 186 | -0.4 187 | 188 | 189 | 190 | 191 | Roll moment due to yaw rate 192 | 193 | aero/qbar-psf 194 | metrics/Sw-sqft 195 | metrics/bw-ft 196 | aero/bi2vel 197 | velocities/r-aero-rad_sec 198 | 0.15 199 | 200 | 201 | 202 | 203 | Roll moment due to aileron 204 | 205 | aero/qbar-psf 206 | metrics/Sw-sqft 207 | metrics/bw-ft 208 | fcs/left-aileron-pos-rad 209 | 210 | velocities/mach 211 | 212 | 0.0 0.170 213 | 2.0 0.057 214 | 215 |
216 |
217 |
218 | 219 | 220 | Roll moment due to rudder 221 | 222 | aero/qbar-psf 223 | metrics/Sw-sqft 224 | metrics/bw-ft 225 | fcs/rudder-pos-rad 226 | 0.01 227 | 228 | 229 | 230 |
231 | 232 | 233 | 234 | 235 | Pitch moment due to alpha 236 | 237 | aero/qbar-psf 238 | metrics/Sw-sqft 239 | metrics/cbarw-ft 240 | aero/alpha-rad 241 | -0.5 242 | 243 | 244 | 245 | 246 | Pitch moment due to elevator 247 | 248 | aero/qbar-psf 249 | metrics/Sw-sqft 250 | metrics/cbarw-ft 251 | fcs/elevator-pos-rad 252 | 253 | velocities/mach 254 | 255 | 0.0 -1.100 256 | 2.0 -0.275 257 | 258 |
259 |
260 |
261 | 262 | 263 | Pitch moment due to pitch rate 264 | 265 | aero/qbar-psf 266 | metrics/Sw-sqft 267 | metrics/cbarw-ft 268 | aero/ci2vel 269 | velocities/q-aero-rad_sec 270 | -12 271 | 272 | 273 | 274 | 275 | Pitch moment due to alpha rate 276 | 277 | aero/qbar-psf 278 | metrics/Sw-sqft 279 | metrics/cbarw-ft 280 | aero/ci2vel 281 | aero/alphadot-rad_sec 282 | -7 283 | 284 | 285 | 286 |
287 | 288 | 289 | 290 | 291 | Yaw moment due to beta 292 | 293 | aero/qbar-psf 294 | metrics/Sw-sqft 295 | metrics/bw-ft 296 | aero/beta-rad 297 | 0.12 298 | 299 | 300 | 301 | 302 | Yaw moment due to yaw rate 303 | 304 | aero/qbar-psf 305 | metrics/Sw-sqft 306 | metrics/bw-ft 307 | aero/bi2vel 308 | velocities/r-aero-rad_sec 309 | -0.15 310 | 311 | 312 | 313 | 314 | Yaw moment due to rudder 315 | 316 | aero/qbar-psf 317 | metrics/Sw-sqft 318 | metrics/bw-ft 319 | fcs/rudder-pos-rad 320 | -0.1 321 | 322 | 323 | 324 | 325 | Adverse yaw 326 | 327 | aero/qbar-psf 328 | metrics/Sw-sqft 329 | metrics/bw-ft 330 | fcs/left-aileron-pos-rad 331 | -0.01 332 | 333 | 334 | 335 | 336 | 337 |
338 | -------------------------------------------------------------------------------- /aircraft/easystar/Systems/flight_control.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | fcs/elevator-cmd-norm 8 | fcs/pitch-trim-cmd-norm 9 | 10 | -1 11 | 1 12 | 13 | 14 | 15 | 16 | fcs/pitch-trim-sum 17 | 18 | -0.454 19 | 0.244 20 | 21 | fcs/elevator-pos-rad 22 | 23 | 24 | 25 | 26 | fcs/aileron-cmd-norm 27 | fcs/roll-trim-cmd-norm 28 | 29 | -1 30 | 1 31 | 32 | 33 | 34 | 35 | fcs/roll-trim-sum 36 | 37 | -0.28 38 | 0.33 39 | 40 | fcs/left-aileron-pos-rad 41 | 42 | 43 | 44 | -fcs/roll-trim-sum 45 | 46 | -0.28 47 | 0.33 48 | 49 | fcs/right-aileron-pos-rad 50 | 51 | 52 | 53 | 54 | fcs/rudder-cmd-norm 55 | fcs/yaw-trim-cmd-norm 56 | 57 | -1 58 | 1 59 | 60 | 61 | 62 | 63 | fcs/rudder-command-sum 64 | 65 | -0.28 66 | 0.28 67 | 68 | fcs/rudder-pos-rad 69 | 70 | 71 | 72 | 73 | fcs/flap-cmd-norm 74 | 75 | 76 | 0 77 | 78 | 79 | 80 | 15 81 | 82 | 83 | 84 | 25 85 | 86 | 87 | 88 | 40 89 | 90 | 91 | 92 | fcs/flap-pos-deg 93 | 94 | 95 | 96 | fcs/flap-pos-deg 97 | 98 | 0 99 | 40 100 | 101 | 102 | 0 103 | 1 104 | 105 | fcs/flap-pos-norm 106 | 107 | 108 | 109 | 110 | 111 | fcs/speedbrake-cmd-norm 112 | 113 | 114 | 0 115 | 116 | 117 | 118 | 1 119 | 120 | 121 | 122 | fcs/speedbrake-pos-norm 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /aircraft/easystar/Systems/sound.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | engine 51 | looped 52 | Sounds/wasp.wav 53 | /engines/engine[0]/running 54 | 55 | -2.0 56 | 0.0 57 | -2.0 58 | 59 | 60 | /engines/engine[0]/mp-osi 61 | 0.009 62 | 0.15 63 | 0.6 64 | 0.15 65 | 66 | 67 | /engines/engine[0]/rpm 68 | 0.0004 69 | 0.1 70 | 2.0 71 | 0.3 72 | 73 | 74 | 75 | 76 | squeal 77 | Sounds/squeal.wav 78 | 79 | 80 | /gear/gear[0]/wow 81 | /gear/gear[1]/wow 82 | /gear/gear[2]/wow 83 | 84 | 85 | 86 | /velocities/speed-down-fps 87 | 0.05 88 | 89 | 90 | /velocities/airspeed-kt 91 | 0.01 92 | 93 | 94 | dt_stop 95 | 0.05 96 | 1.0 97 | 98 | 99 | /velocities/airspeed-kt 100 | 0.0025 101 | 1.2 102 | 103 | 104 | 105 | wind 106 | looped 107 | Sounds/wind.wav 108 | /velocities/airspeed-kt 109 | 110 | /position/altitude-ft 111 | -0.000015 112 | 1.0 113 | 0.1 114 | 1.0 115 | 116 | 117 | /velocities/airspeed-kt 118 | 0.0015 119 | 0.03 120 | 0.25 121 | 122 | 123 | /velocities/airspeed-kt 124 | 0.01 125 | 1.25 126 | 127 | 128 | 129 | stall 130 | Sounds/stall.wav 131 | /sim/alarms/stall-warning 132 | 133 | /velocities/airspeed-kt 134 | 30.0 135 | 136 | 10.0 137 | 20.0 138 | 139 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /aircraft/easystar/easystar: -------------------------------------------------------------------------------- 1 | /hsl/homes/jgoppert/git/arkhangar/aircraft/easystar -------------------------------------------------------------------------------- /aircraft/easystar/easystar-set.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | James Goppert 5 | Multiplex Easy Star (DATCOM aerodynamics) 6 | 0.0.0 7 | early-production 8 | 9 | Multiplex Easy Star (DATCOM aerodynamcis) 10 | Aircraft/easystar/Models/splash.rgb 11 | 12 | 13 | Aircraft/easystar/Models/model.xml 14 | 15 | 16 | Aircraft/easystar/Systems/sound.xml 17 | 18 | jsb 19 | easystar 20 | 21 | 22 | -------------------------------------------------------------------------------- /aircraft/easystar/easystar.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 17 | 18 | 19 | James Goppert 20 | 2010-6-3 21 | Multiplex Easy Star (DATCOM) 22 | 23 | 24 | 25 | 28 | 29 | 2.2792 30 | 4.5000 31 | .5606 32 | .4457 33 | .4280 34 | .1606 35 | .7127 36 | 40 | 41 | 4.0 42 | 0.0 43 | 0.0 44 | 45 | 46 | 47 | 0.0 48 | 0.0 49 | 0.0 50 | 51 | 52 | 53 | 0.0 54 | 0.0 55 | 0.0 56 | 57 | 58 | 59 | 62 | 63 | 0.059 64 | 0.02465 65 | 0.07869 66 | 0.0 67 | 2.0 68 | 69 | 70 | 2.0 71 | 0.0 72 | 0.0 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 27.0 90 | 0 91 | -2.0 92 | 93 | 1.0 94 | 0.8 95 | 12 96 | 1 97 | 98 | 99 | 100 | -5.0 101 | 0.0 102 | 0.0 103 | 104 | 1.0 105 | 0.8 106 | 12 107 | 1 108 | 109 | 110 | 111 | 0.0 112 | 0.0 113 | -3.0 114 | 115 | 1.0 116 | 0.8 117 | 12 118 | 1 119 | 120 | 121 | 122 | 123 | -3.0 124 | -27.5 125 | 1.0 126 | 127 | 1.0 128 | 0.8 129 | 12 130 | 1 131 | 132 | 133 | 134 | -3.0 135 | 27.5 136 | 1.0 137 | 138 | 1.0 139 | 0.8 140 | 12 141 | 1 142 | 143 | 144 | 145 | 27.0 146 | 0.0 147 | 6.5 148 | 149 | 1.0 150 | 0.8 151 | 12 152 | 1 153 | 154 | 155 | 156 | 0.0 157 | 0.0 158 | 2.0 159 | 160 | 1.0 161 | 0.8 162 | 12 163 | 1 164 | 165 | 166 | 169 | 170 | 171 | 172 | 10.0 173 | 0 174 | 3.0 175 | 176 | 177 | 0.0 178 | -5 179 | 0 180 | 181 | 0 182 | 183 | 184 | 10.0 185 | 0 186 | 3.0 187 | 188 | 189 | 0.0 190 | -5.0 191 | 0.0 192 | 193 | 1.0 194 | 195 | 196 | 197 | 198 | 199 | 0.0 200 | 0.0 201 | 0.0 202 | 203 | 0.0001 204 | 0 205 | 206 | 207 | 210 | 211 | 214 | 215 | 216 | fcs/elevator-cmd-norm 217 | fcs/pitch-trim-cmd-norm 218 | 219 | -1 220 | 1 221 | 222 | fcs/elevator-pos-norm 223 | 224 | 225 | fcs/pitch-trim-sum 226 | 0.01745 227 | 228 | -28 229 | 23 230 | 231 | fcs/elevator-pos-rad 232 | 233 | 234 | 238 | 239 | 240 | fcs/rudder-cmd-norm 241 | fcs/aileron-cmd-norm 242 | fcs/yaw-trim-cmd-norm 243 | 244 | -1 245 | 1 246 | 247 | 248 | 249 | fcs/yaw-trim-sum 250 | 251 | -1 252 | 1 253 | 254 | 255 | 256 | fcs/yaw-mix 257 | -0.01745 258 | 259 | -27 260 | 27 261 | 262 | fcs/rudder-pos-rad 263 | 264 | 265 | 268 | 269 | 270 | 271 | 272 | fcs/throttle-cmd-norm 273 | 3 274 | 275 | 276 | 277 | 278 | fcs/rpm-scaled-throttle 279 | 280 | -1 281 | 1 282 | 283 | fcs/throttle-pos-norm 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | -------------------------------------------------------------------------------- /aircraft/easystar/patches/aero-fixes: -------------------------------------------------------------------------------- 1 | Index: easystar/Datcom/datcom_aero.xml 2 | =================================================================== 3 | --- easystar.orig/Datcom/datcom_aero.xml 2012-05-24 15:34:33.000000000 -0400 4 | +++ easystar/Datcom/datcom_aero.xml 2012-05-24 15:39:49.000000000 -0400 5 | @@ -1098,6 +1098,7 @@ 6 | metrics/Sw-sqft 7 | metrics/bw-ft 8 | aero/beta-deg 9 | + -1 10 | 11 | aero/alpha-deg 12 | 13 | @@ -1230,6 +1231,7 @@ 14 | metrics/bw-ft 15 |
16 | aero/alpha-deg 17 | + fcs/left-aileron-pos-deg 18 | 19 | -56.00 -40.00 -20.00 -10.00 .000 10.00 20.00 40.00 56.00 20 | -16.00 -.1091E-01 -.9650E-02 -.6942E-02 -.3471E-02 .000 .3471E-02 .6942E-02 .9650E-02 .1091E-01 21 | -------------------------------------------------------------------------------- /aircraft/easystar/patches/series: -------------------------------------------------------------------------------- 1 | aero-fixes 2 | -------------------------------------------------------------------------------- /aircraft/easystar/reset.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 37.61982336255984 4 | -122.372117042541504 5 | 500.0 6 | 39.37 7 | 0.0 8 | 0.0 9 | 0.0 10 | 0.0 11 | 12 | -------------------------------------------------------------------------------- /aircraft/easystar/reset_template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | %(LATITUDE)s 4 | %(LONGITUDE)s 5 | %(ALTITUDE)s 6 | 72.0 7 | 0.0 8 | 0.0 9 | 0.0 10 | %(HEADING)s 11 | 12 | -------------------------------------------------------------------------------- /data/easystar_parameters_12mps.txt: -------------------------------------------------------------------------------- 1 | # Onboard parameters for system MAV 001 2 | # 3 | # MAV ID COMPONENT ID PARAM NAME VALUE (FLOAT) 4 | 1 50 BAT_N_CELLS 3 9 5 | 1 50 BAT_V_EMPTY 3.2 9 6 | 1 50 BAT_V_FULL 4.05 9 7 | 1 50 BAT_V_SCALING 0.00459341 9 8 | 1 50 FPE_DEBUG 0 6 9 | 1 50 FPE_LO_THRUST 0.4 9 10 | 1 50 FPE_SONAR_LP_L 0.2 9 11 | 1 50 FPE_SONAR_LP_U 0.5 9 12 | 1 50 FWB_CR2THR_D 0 9 13 | 1 50 FWB_CR2THR_D_LP 0 9 14 | 1 50 FWB_CR2THR_I 0 9 15 | 1 50 FWB_CR2THR_I_MAX 0 9 16 | 1 50 FWB_CR2THR_P 0.01 9 17 | 1 50 FWB_CR_MAX 1 9 18 | 1 50 FWB_H2THR_D 0 9 19 | 1 50 FWB_H2THR_D_LP 0 9 20 | 1 50 FWB_H2THR_I 0 9 21 | 1 50 FWB_H2THR_I_MAX 0 9 22 | 1 50 FWB_H2THR_P 0.01 9 23 | 1 50 FWB_P2AIL 0.3 9 24 | 1 50 FWB_PHI2P 1 9 25 | 1 50 FWB_PHI_LIM_MAX 0.7 9 26 | 1 50 FWB_PSI2PHI 1 9 27 | 1 50 FWB_P_LP 1000 9 28 | 1 50 FWB_Q2ELV 0.1 9 29 | 1 50 FWB_Q_LP 1000 9 30 | 1 50 FWB_R2RDR 0.5 9 31 | 1 50 FWB_R_HP 1 9 32 | 1 50 FWB_R_LP 1000 9 33 | 1 50 FWB_THE2Q_D 0 9 34 | 1 50 FWB_THE2Q_D_LP 0 9 35 | 1 50 FWB_THE2Q_I 0 9 36 | 1 50 FWB_THE2Q_I_MAX 0 9 37 | 1 50 FWB_THE2Q_P 1 9 38 | 1 50 FWB_THE_MAX 0.5 9 39 | 1 50 FWB_THE_MIN -0.5 9 40 | 1 50 FWB_TRIM_THR 0.55 9 41 | 1 50 FWB_TRIM_V 12 9 42 | 1 50 FWB_V2THE_D 0 9 43 | 1 50 FWB_V2THE_D_LP 0 9 44 | 1 50 FWB_V2THE_I 0 9 45 | 1 50 FWB_V2THE_I_MAX 0 9 46 | 1 50 FWB_V2THE_P 0.1 9 47 | 1 50 FWB_V_CMD 12 9 48 | 1 50 FWB_V_MAX 20 9 49 | 1 50 FWB_V_MIN 10 9 50 | 1 50 FWB_XT2YAW 0.001 9 51 | 1 50 FWB_XT2YAW_MAX 1.57 9 52 | 1 50 KF_ENV_G 9.765 9 53 | 1 50 KF_ENV_MAG_DEC 0 9 54 | 1 50 KF_ENV_MAG_DIP 60 9 55 | 1 50 KF_FAULT_ATT 10 9 56 | 1 50 KF_FAULT_POS 10 9 57 | 1 50 KF_R_ACCEL 1 9 58 | 1 50 KF_R_GPS_ALT 3 9 59 | 1 50 KF_R_GPS_POS 2 9 60 | 1 50 KF_R_GPS_VEL 0.5 9 61 | 1 50 KF_R_MAG 0.8 9 62 | 1 50 KF_R_PRESS_ALT 0.1 9 63 | 1 50 KF_V_ACCEL 1 9 64 | 1 50 KF_V_GYRO 0.008 9 65 | 1 50 MAV_COMP_ID 50 6 66 | 1 50 MAV_SYS_ID 1 6 67 | 1 50 MAV_TYPE 1 6 68 | 1 50 NAV_DUMMY 0 9 69 | 1 50 NAV_TAKEOFF_ALT 5 9 70 | 1 50 NAV_TAKEOFF_GAP 3 9 71 | 1 50 RC10_DZ 0 9 72 | 1 50 RC10_MAX 2000 9 73 | 1 50 RC10_MIN 1000 9 74 | 1 50 RC10_REV 1 9 75 | 1 50 RC10_TRIM 1500 9 76 | 1 50 RC11_DZ 0 9 77 | 1 50 RC11_MAX 2000 9 78 | 1 50 RC11_MIN 1000 9 79 | 1 50 RC11_REV 1 9 80 | 1 50 RC11_TRIM 1500 9 81 | 1 50 RC12_DZ 0 9 82 | 1 50 RC12_MAX 2000 9 83 | 1 50 RC12_MIN 1000 9 84 | 1 50 RC12_REV 1 9 85 | 1 50 RC12_TRIM 1500 9 86 | 1 50 RC13_DZ 0 9 87 | 1 50 RC13_MAX 2000 9 88 | 1 50 RC13_MIN 1000 9 89 | 1 50 RC13_REV 1 9 90 | 1 50 RC13_TRIM 1500 9 91 | 1 50 RC14_DZ 0 9 92 | 1 50 RC14_MAX 2000 9 93 | 1 50 RC14_MIN 1000 9 94 | 1 50 RC14_REV 1 9 95 | 1 50 RC14_TRIM 1500 9 96 | 1 50 RC15_DZ 0 9 97 | 1 50 RC15_MAX 2000 9 98 | 1 50 RC15_MIN 1000 9 99 | 1 50 RC15_REV 1 9 100 | 1 50 RC15_TRIM 1500 9 101 | 1 50 RC1_DZ 0 9 102 | 1 50 RC1_MAX 2000 9 103 | 1 50 RC1_MIN 1000 9 104 | 1 50 RC1_REV 1 9 105 | 1 50 RC1_TRIM 1500 9 106 | 1 50 RC2_DZ 0 9 107 | 1 50 RC2_MAX 2000 9 108 | 1 50 RC2_MIN 1000 9 109 | 1 50 RC2_REV 1 9 110 | 1 50 RC2_TRIM 1500 9 111 | 1 50 RC3_DZ 0 9 112 | 1 50 RC3_MAX 2000 9 113 | 1 50 RC3_MIN 1000 9 114 | 1 50 RC3_REV 1 9 115 | 1 50 RC3_TRIM 1500 9 116 | 1 50 RC4_DZ 30 9 117 | 1 50 RC4_MAX 2000 9 118 | 1 50 RC4_MIN 1000 9 119 | 1 50 RC4_REV 1 9 120 | 1 50 RC4_TRIM 1500 9 121 | 1 50 RC5_DZ 0 9 122 | 1 50 RC5_MAX 2000 9 123 | 1 50 RC5_MIN 1000 9 124 | 1 50 RC5_REV 1 9 125 | 1 50 RC5_TRIM 1500 9 126 | 1 50 RC6_DZ 0 9 127 | 1 50 RC6_MAX 2000 9 128 | 1 50 RC6_MIN 1000 9 129 | 1 50 RC6_REV 1 9 130 | 1 50 RC6_TRIM 1500 9 131 | 1 50 RC7_DZ 0 9 132 | 1 50 RC7_MAX 2000 9 133 | 1 50 RC7_MIN 1000 9 134 | 1 50 RC7_REV 1 9 135 | 1 50 RC7_TRIM 1500 9 136 | 1 50 RC8_DZ 0 9 137 | 1 50 RC8_MAX 2000 9 138 | 1 50 RC8_MIN 1000 9 139 | 1 50 RC8_REV 1 9 140 | 1 50 RC8_TRIM 1500 9 141 | 1 50 RC9_DZ 0 9 142 | 1 50 RC9_MAX 2000 9 143 | 1 50 RC9_MIN 1000 9 144 | 1 50 RC9_REV 1 9 145 | 1 50 RC9_TRIM 1500 9 146 | 1 50 RC_DSM_BIND -1 6 147 | 1 50 RC_MAP_ASSIST_SW 6 6 148 | 1 50 RC_MAP_AUX1 0 6 149 | 1 50 RC_MAP_AUX2 0 6 150 | 1 50 RC_MAP_AUX3 0 6 151 | 1 50 RC_MAP_FLAPS 0 6 152 | 1 50 RC_MAP_MISSIO_SW 0 6 153 | 1 50 RC_MAP_MODE_SW 5 6 154 | 1 50 RC_MAP_PITCH 2 6 155 | 1 50 RC_MAP_RETURN_SW 0 6 156 | 1 50 RC_MAP_ROLL 1 6 157 | 1 50 RC_MAP_THROTTLE 3 6 158 | 1 50 RC_MAP_YAW 4 6 159 | 1 50 RC_RL1_DSM_VCC 0 6 160 | 1 50 RC_SCALE_PITCH 0.6 9 161 | 1 50 RC_SCALE_ROLL 0.6 9 162 | 1 50 RC_SCALE_YAW 2 9 163 | 1 50 SENS_ACC_XOFF 0 9 164 | 1 50 SENS_ACC_XSCALE 1 9 165 | 1 50 SENS_ACC_YOFF 0 9 166 | 1 50 SENS_ACC_YSCALE 1 9 167 | 1 50 SENS_ACC_ZOFF 0 9 168 | 1 50 SENS_ACC_ZSCALE 1 9 169 | 1 50 SENS_BOARD_ROT 0 6 170 | 1 50 SENS_DPRES_ANA 0 6 171 | 1 50 SENS_DPRES_OFF 0 9 172 | 1 50 SENS_EXT_MAG_ROT 0 6 173 | 1 50 SENS_GYRO_XOFF 0 9 174 | 1 50 SENS_GYRO_XSCALE 1 9 175 | 1 50 SENS_GYRO_YOFF 0 9 176 | 1 50 SENS_GYRO_YSCALE 1 9 177 | 1 50 SENS_GYRO_ZOFF 0 9 178 | 1 50 SENS_GYRO_ZSCALE 1 9 179 | 1 50 SENS_MAG_XOFF 0 9 180 | 1 50 SENS_MAG_XSCALE 1 9 181 | 1 50 SENS_MAG_YOFF 0 9 182 | 1 50 SENS_MAG_YSCALE 1 9 183 | 1 50 SENS_MAG_ZOFF 0 9 184 | 1 50 SENS_MAG_ZSCALE 1 9 185 | 1 50 SYS_AUTOCONFIG 0 6 186 | 1 50 SYS_AUTOSTART 0 6 187 | 1 50 TEST_D 0.01 9 188 | 1 50 TEST_DEV 2 9 189 | 1 50 TEST_D_LP 10 9 190 | 1 50 TEST_HP 10 9 191 | 1 50 TEST_I 0.1 9 192 | 1 50 TEST_I_MAX 1 9 193 | 1 50 TEST_LP 10 9 194 | 1 50 TEST_MAX 1 9 195 | 1 50 TEST_MEAN 1 9 196 | 1 50 TEST_MIN -1 9 197 | 1 50 TEST_P 0.2 9 198 | 1 50 TEST_TRIM 0.5 9 199 | 1 50 TRIM_PITCH 0 9 200 | 1 50 TRIM_ROLL 0 9 201 | 1 50 TRIM_YAW 0 9 202 | 1 50 test 305419896 6 203 | -------------------------------------------------------------------------------- /data/easystar_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Test PX4 using EasyStar 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | simulation/notify-time-trigger 19 | 20 | 21 | simulation/sim-time-sec le 0.01 22 | 23 | 24 | 25 | 26 | 27 | simulation/sim-time-sec ge 5 28 | 29 | 30 | 31 | 32 | 33 | 34 | Output message at 5 second intervals 35 | 36 | propulsion/engine[0]/thrust-lbs 37 | position/h-agl-m 38 | 39 | simulation/sim-time-sec >= simulation/notify-time-trigger 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /data/fgout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/flightgear.xml: -------------------------------------------------------------------------------- 1 |  2 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /data/rascal_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | test ArduPlane using Rascal110 and JSBSim 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | simulation/notify-time-trigger 19 | 20 | 21 | simulation/sim-time-sec le 0.01 22 | 23 | 24 | 25 | 26 | 27 | simulation/sim-time-sec ge 5 28 | 29 | 30 | 31 | 32 | 33 | 34 | Output message at 5 second intervals 35 | 36 | propulsion/engine[0]/thrust-lbs 37 | position/h-agl-m 38 | 39 | simulation/sim-time-sec >= simulation/notify-time-trigger 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /data/rc_desktop: -------------------------------------------------------------------------------- 1 | #!nsh 2 | 3 | # Disable USB and autostart 4 | set USB no 5 | set MODE camflyer 6 | 7 | # 8 | # Start the ORB 9 | # 10 | uorb start 11 | 12 | # 13 | # Load microSD params 14 | # 15 | echo "[init] loading microSD params" 16 | param select /fs/microsd/parameters 17 | if [ -f /fs/microsd/parameters ] 18 | then 19 | param load /fs/microsd/parameters 20 | fi 21 | 22 | # 23 | # Start the sensors. 24 | # 25 | sh /etc/init.d/rc.sensors 26 | 27 | # 28 | # Start MAVLink 29 | # 30 | mavlink start -d /dev/ttyS1 -b 57600 31 | usleep 5000 32 | 33 | # 34 | # Start the commander. 35 | # 36 | commander start 37 | 38 | # 39 | # Start GPS interface 40 | # 41 | gps start -d /dev/ttyS3 -m mtkcustom 42 | 43 | # 44 | # Start the attitude estimator 45 | # 46 | #kalman_demo start 47 | 48 | # 49 | # Start PX4IO interface 50 | # 51 | px4io start 52 | 53 | # 54 | # Load mixer and start controllers 55 | # 56 | mixer load /dev/pwm_output /etc/mixers/FMU_AERT.mix 57 | #control_demo start 58 | -------------------------------------------------------------------------------- /data/rc_hil: -------------------------------------------------------------------------------- 1 | #!nsh 2 | set mode custom 3 | 4 | # 5 | # Start terminal 6 | # 7 | if sercon 8 | then 9 | echo "USB connected" 10 | fi 11 | # 12 | # Start the ORB (first app to start) 13 | # 14 | uorb start 15 | # 16 | # Load microSD params 17 | # 18 | if ramtron start 19 | then 20 | param select /ramtron/params 21 | if [ -f /ramtron/params ] 22 | then 23 | param load /ramtron/params 24 | fi 25 | else 26 | param select /fs/microsd/params 27 | if [ -f /fs/microsd/params ] 28 | then 29 | param load /fs/microsd/params 30 | fi 31 | fi 32 | 33 | # 34 | # USB HIL start 35 | # 36 | 37 | 38 | 39 | echo "[HIL] starting.." 40 | 41 | # Tell MAVLink that this link is "fast" 42 | sleep 2 43 | mavlink start -b 921600 -d /dev/ttyS1 44 | 45 | # Create a fake HIL /dev/pwm_output interface 46 | hil mode_pwm 47 | 48 | # 49 | # Force some key parameters to sane values 50 | # MAV_TYPE 1 = fixed wing, 2 = quadrotor, 13 = hexarotor 51 | # see https://pixhawk.ethz.ch/mavlink/ 52 | # 53 | param set MAV_TYPE 1 54 | 55 | # 56 | # Start the commander (depends on orb, mavlink) 57 | # 58 | commander start 59 | 60 | 61 | # 62 | # Check if we got an IO 63 | # 64 | if px4io start 65 | then 66 | echo "IO started" 67 | else 68 | fmu mode_serial 69 | echo "FMU started" 70 | fi 71 | 72 | # 73 | # Start the sensors (depends on orb, px4io) 74 | # disable for HIL to save time 75 | # 76 | #sh /etc/init.d/rc.sensors 77 | 78 | # 79 | # Start the attitude estimator (depends on orb) 80 | # disable for state mode HIL 81 | # 82 | att_pos_estimator_ekf start 83 | 84 | # 85 | # Load mixer and start controllers (depends on px4io) 86 | # 87 | mixer load /dev/pwm_output /etc/mixers/FMU_AET.mix 88 | 89 | #use either the following pos/att controllers, or the backside controller. 90 | fw_pos_control_l1 start 91 | fw_att_control start 92 | 93 | #use either the pos/att controllers directly above, or the backside (below) 94 | #fixedwing_backside start 95 | 96 | echo "[HIL] setup done, running" -------------------------------------------------------------------------------- /data/sf_waypoints.txt: -------------------------------------------------------------------------------- 1 | QGC WPL 110 2 | 0 1 0 16 0 30 0 0 37.6208091333429522 -122.374413013458252 500 1 3 | 1 0 0 16 0 30 0 0 37.6189565533130761 -122.375593185424805 500 1 4 | 2 0 0 16 0 30 0 0 37.6179707579663969 -122.373318672180176 500 1 5 | 3 0 0 16 0 30 0 0 37.619823362559849 -122.372117042541504 500 1 6 | -------------------------------------------------------------------------------- /modules/aircraft.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | classes for aircraft model 5 | ''' 6 | from __future__ import print_function 7 | 8 | import time, struct, numpy 9 | from math import sin, cos, sqrt 10 | 11 | from constants import * 12 | 13 | class Controls(object): 14 | 15 | def __init__(self, aileron, elevator, rudder, throttle, aux1, aux2, aux3, aux4, 16 | mode, nav_mode): 17 | self.aileron = aileron 18 | self.elevator = elevator 19 | self.rudder = rudder 20 | self.throttle = throttle 21 | self.aux1 = aux1 22 | self.aux2 = aux2 23 | self.aux3 = aux3 24 | self.aux4 = aux4 25 | self.mode = mode 26 | self.nav_mode = nav_mode 27 | self.C_nb = numpy.identity(3) 28 | 29 | @classmethod 30 | def default(cls): 31 | return cls(time.time(),0,0,0,0,0,0,0,0,0) 32 | 33 | def send_to_jsbsim(self, jsb_console): 34 | jsb_console.send('set %s %s\r\n' % ('fcs/aileron-cmd-norm', self.aileron)) 35 | jsb_console.send('set %s %s\r\n' % ('fcs/elevator-cmd-norm', self.elevator)) 36 | jsb_console.send('set %s %s\r\n' % ('fcs/rudder-cmd-norm', self.rudder)) 37 | jsb_console.send('set %s %s\r\n' % ('fcs/throttle-cmd-norm', self.throttle)) 38 | 39 | @classmethod 40 | def from_mavlink(cls,msg): 41 | return cls( 42 | aileron = msg.roll_ailerons, 43 | elevator = msg.pitch_elevator, 44 | rudder = msg.yaw_rudder, 45 | throttle = msg.throttle, 46 | aux1 = msg.aux1, 47 | aux2 = msg.aux2, 48 | aux3 = msg.aux3, 49 | aux4 = msg.aux4, 50 | mode = msg.mode, 51 | nav_mode = msg.nav_mode) 52 | 53 | class State(object): 54 | 55 | def __init__(self, time, 56 | phi, theta, psi, 57 | p, q, r, 58 | lat, lon, alt, 59 | vN, vE, vD, 60 | xacc, yacc, zacc): 61 | self.time = time 62 | self.set_attitude(phi, theta, psi) 63 | self.p = p 64 | self.q = q 65 | self.r = r 66 | self.lat = lat 67 | self.lon = lon 68 | self.alt = alt 69 | self.vN = vN 70 | self.vE = vE 71 | self.vD = vD 72 | self.xacc = xacc 73 | self.yacc = yacc 74 | self.zacc = zacc 75 | 76 | def set_attitude(self, phi, theta, psi): 77 | self.phi = phi 78 | self.theta = theta 79 | self.psi = psi 80 | cosPhi = cos(phi) 81 | sinPhi = sin(phi) 82 | cosThe = cos(theta) 83 | sinThe = sin(theta) 84 | cosPsi = cos(psi) 85 | sinPsi = sin(psi) 86 | self.C_nb = numpy.matrix([ 87 | [cosThe*cosPsi, 88 | -cosPhi*sinPsi + sinPhi*sinThe*cosPsi, 89 | sinPhi*sinPsi + cosPhi*sinThe*cosPsi], 90 | [cosThe*sinPsi, 91 | cosPhi*cosPsi + sinPhi*sinThe*sinPsi, 92 | -sinPhi*cosPsi + cosPhi*sinThe*sinPsi], 93 | [-sinThe, 94 | sinPhi*cosThe, 95 | cosPhi*cosThe]]) 96 | self.quat = numpy.matrix([ 97 | [cos(phi/2)*cos(theta/2)*cos(psi/2)+sin(phi/2)*sin(theta/2)*sin(psi/2)], 98 | [sin(phi/2)*cos(theta/2)*cos(psi/2)-cos(phi/2)*sin(theta/2)*sin(psi/2)], 99 | [cos(phi/2)*sin(theta/2)*cos(psi/2)+sin(phi/2)*cos(theta/2)*sin(psi/2)], 100 | [cos(phi/2)*cos(theta/2)*sin(psi/2)-sin(phi/2)*sin(theta/2)*cos(psi/2)] 101 | ]) 102 | 103 | @classmethod 104 | def default(cls): 105 | return cls(time.time(),0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) 106 | 107 | def send_to_mav(self, mav): 108 | try: 109 | v = sqrt(self.vN**2 + self.vE**2 + self.vD**2) 110 | mav.hil_state_quaternion_send( 111 | self.time*sec2usec, self.quat, 112 | self.p, self.q, self.r, 113 | int(self.lat*rad2degE7), int(self.lon*rad2degE7), int(self.alt*m2mm), 114 | int(self.vN*m2cm), int(self.vE*m2cm), int(self.vD*m2cm), 115 | int(v*m2cm), int(v*m2cm), 116 | int(self.xacc*mpss2mg), int(self.yacc*mpss2mg), int(self.zacc*mpss2mg)) 117 | except struct.error as e: 118 | print(e) 119 | print('mav hil packet data exceeds int bounds?') 120 | 121 | 122 | @classmethod 123 | def from_fdm(cls, fdm): 124 | 125 | # position 126 | lat = fdm.get('latitude', units='radians') 127 | lon = fdm.get('longitude', units='radians') 128 | alt = fdm.get('altitude', units='meters') 129 | 130 | # attitude 131 | phi = fdm.get('phi', units='radians') 132 | theta = fdm.get('theta', units='radians') 133 | psi = fdm.get('psi', units='radians') 134 | 135 | # rotation rates 136 | phidot = fdm.get('phidot', units='rps') 137 | thetadot = fdm.get('thetadot', units='rps') 138 | psidot = fdm.get('psidot', units='rps') 139 | 140 | p = phidot - psidot*sin(theta) 141 | q = cos(phi)*thetadot + sin(phi)*cos(theta)*psidot 142 | r = -sin(phi)*thetadot + cos(phi)*cos(theta)*psidot 143 | 144 | # acceleration 145 | xacc = fdm.get('A_X_pilot', units='mpss') 146 | yacc = fdm.get('A_Y_pilot', units='mpss') 147 | zacc = fdm.get('A_Z_pilot', units='mpss') 148 | 149 | # velocitiy 150 | vN = fdm.get('v_north', units='mps') 151 | vE = fdm.get('v_east', units='mps') 152 | vD = fdm.get('v_down', units='mps') 153 | #print 'vel: ', math.sqrt(vN*vN + vE*vE + vD*vD) 154 | 155 | return cls(time=time.time(), 156 | phi=phi, theta=theta, psi=psi, 157 | p=p, q=q, r=r, 158 | lat=lat, lon=lon, alt=alt, 159 | vN=vN, vE=vE, vD=vD, 160 | xacc=xacc, yacc=yacc, zacc=zacc) 161 | -------------------------------------------------------------------------------- /modules/constants.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | g = 9.80665 4 | mpss2mg = 1000.0/g 5 | m2cm = 100.0 6 | m2mm = 1000.0 7 | sec2usec = 1.0e6 8 | rad2degE7 = 1.0e7*180.0/math.pi 9 | rad2mrad = 1.0e3 10 | ga2mga = 1.0e3 11 | rad2deg = 180.0/math.pi 12 | deg2rad = 1/rad2deg 13 | T0 = 273.15 14 | R = 287.05 15 | -------------------------------------------------------------------------------- /modules/fdpexpect.py: -------------------------------------------------------------------------------- 1 | """This is like pexpect, but will work on any file descriptor that you pass it. 2 | So you are reponsible for opening and close the file descriptor. 3 | 4 | $Id: fdpexpect.py 505 2007-12-26 21:33:50Z noah $ 5 | """ 6 | 7 | from pexpect import * 8 | import os 9 | 10 | __all__ = ['fdspawn'] 11 | 12 | class fdspawn (spawn): 13 | 14 | """This is like pexpect.spawn but allows you to supply your own open file 15 | descriptor. For example, you could use it to read through a file looking 16 | for patterns, or to control a modem or serial device. """ 17 | 18 | def __init__ (self, fd, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None): 19 | 20 | """This takes a file descriptor (an int) or an object that support the 21 | fileno() method (returning an int). All Python file-like objects 22 | support fileno(). """ 23 | 24 | ### TODO: Add better handling of trying to use fdspawn in place of spawn 25 | ### TODO: (overload to allow fdspawn to also handle commands as spawn does. 26 | 27 | if type(fd) != type(0) and hasattr(fd, 'fileno'): 28 | fd = fd.fileno() 29 | 30 | if type(fd) != type(0): 31 | raise ExceptionPexpect ('The fd argument is not an int. If this is a command string then maybe you want to use pexpect.spawn.') 32 | 33 | try: # make sure fd is a valid file descriptor 34 | os.fstat(fd) 35 | except OSError: 36 | raise ExceptionPexpect, 'The fd argument is not a valid file descriptor.' 37 | 38 | self.args = None 39 | self.command = None 40 | spawn.__init__(self, None, args, timeout, maxread, searchwindowsize, logfile) 41 | self.child_fd = fd 42 | self.own_fd = False 43 | self.closed = False 44 | self.name = '' % fd 45 | 46 | def __del__ (self): 47 | 48 | return 49 | 50 | def close (self): 51 | 52 | if self.child_fd == -1: 53 | return 54 | if self.own_fd: 55 | self.close (self) 56 | else: 57 | self.flush() 58 | os.close(self.child_fd) 59 | self.child_fd = -1 60 | self.closed = True 61 | 62 | def isalive (self): 63 | 64 | """This checks if the file descriptor is still valid. If os.fstat() 65 | does not raise an exception then we assume it is alive. """ 66 | 67 | if self.child_fd == -1: 68 | return False 69 | try: 70 | os.fstat(self.child_fd) 71 | return True 72 | except: 73 | return False 74 | 75 | def terminate (self, force=False): 76 | 77 | raise ExceptionPexpect ('This method is not valid for file descriptors.') 78 | 79 | def kill (self, sig): 80 | 81 | return 82 | 83 | -------------------------------------------------------------------------------- /modules/gcs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/evn python 2 | 3 | from __future__ import print_function 4 | import time 5 | 6 | import pymavlink.mavwp as mavwp 7 | import pymavlink.mavutil as mavutil 8 | 9 | 10 | class WaypointManager(object): 11 | 12 | def __init__(self, mavfile): 13 | self.mavfile = mavfile 14 | self.loader = mavwp.MAVWPLoader(target_system=1, 15 | target_component=190) 16 | self.count = 0 17 | self.send_time = 0 18 | self.recv_time = 0 19 | self._transition_idle() 20 | 21 | def _transition_idle(self): 22 | print('transition idle') 23 | self.state = 'IDLE' 24 | self.index = -1 25 | 26 | def _transition_sending_count(self): 27 | print('transition sending count') 28 | self.state = 'SENDING_COUNT' 29 | self.index = -1 30 | self.send_time = time.time() 31 | 32 | def _transition_sending_waypoint(self): 33 | print('transition sending waypoints') 34 | self.state = 'SENDING_WAYPOINT' 35 | 36 | def set_waypoints(self, waypoints): 37 | self.count = self.loader.load(waypoints) 38 | 39 | def send_waypoints(self): 40 | self._transition_sending_count() 41 | 42 | def send_messages(self): 43 | 44 | if self.state == 'SENDING_COUNT': 45 | if (time.time() - self.send_time) > 1: 46 | self.send_time = time.time() 47 | self.mavfile.waypoint_clear_all_send() 48 | self.mavfile.waypoint_clear_all_send() 49 | self.mavfile.waypoint_count_send(self.count) 50 | self.mavfile.waypoint_count_send(self.count) 51 | print("Sent waypoint count of %u" % self.count) 52 | 53 | elif self.state == 'SENDING_WAYPOINT': 54 | 55 | if (time.time() - self.send_time) > 0.3: 56 | self.send_time = time.time() 57 | wp = self.loader.wp(self.index) 58 | self.mavfile.mav.send(wp) 59 | self.mavfile.mav.send(wp) 60 | print("Sent waypoint %u" % (self.index)) 61 | 62 | # this seems to prompt vehicle to resend request 63 | #self.mavfile.waypoint_count_send(self.count) 64 | pass 65 | 66 | def process_msg(self, msg): 67 | 68 | if msg.get_type() == 'MISSION_REQUEST': 69 | print('received request for {0:d} from {1:d}:{2:d}'.format( 70 | msg.seq, msg.get_srcSystem(), msg.get_srcComponent())) 71 | 72 | # transition to sending waypoints as soon as mission request received 73 | if self.state == 'SENDING_COUNT': 74 | 75 | if msg.get_type() == 'MISSION_REQUEST': 76 | self._transition_sending_waypoint() 77 | self.recv_time = time.time() 78 | # reprocess this message 79 | self.process_msg(msg) 80 | 81 | elif self.state == 'SENDING_WAYPOINT': 82 | 83 | if msg.get_type() == 'MISSION_ACK': 84 | if self.index == self.count - 1: 85 | print("Waypoint uploading complete") 86 | else: 87 | print("Error: received waypoint ack before sending all waypoints!") 88 | self._transition_idle() 89 | 90 | if msg.get_type() == 'MISSION_REQUEST': 91 | 92 | self.recv_time = time.time() 93 | 94 | # should never exceed waypoint count 95 | if msg.seq > self.count - 1: 96 | print("Error: {0:d} waypoints, but waypoint {1:d} requested".format( 97 | self.count,msg.seq)) 98 | self._transition_idle() 99 | elif msg.seq == self.index + 1: 100 | self.index += 1 101 | -------------------------------------------------------------------------------- /modules/hangar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | import time 5 | 6 | import aircraft 7 | import sensors 8 | from math import cos, sin, pi 9 | from collections import deque 10 | 11 | class BasicAircraft(object): 12 | 13 | def __init__(self, attack=None): 14 | t_now = time.time() 15 | self.x = aircraft.State.default() 16 | self.x_delay = deque([self.x],maxlen=10000) 17 | self.u = aircraft.Controls.default() 18 | 19 | if attack == None: 20 | self.imu = sensors.Imu.default() 21 | self.gps = sensors.Gps.default() 22 | else: 23 | import attack_sensors 24 | self.imu = attack_sensors.AttackImu.default() 25 | self.gps = attack_sensors.AttackGps.default() 26 | 27 | self.imu_period = 1.0/200; 28 | self.t_imu = t_now 29 | self.imu_count = 0 30 | 31 | self.gps_period = 1.0/10; 32 | self.t_gps = t_now 33 | self.gps_count = 0 34 | 35 | self.t_out = t_now 36 | 37 | self.attack = attack 38 | 39 | # test variables 40 | self.t0 = time.time() 41 | 42 | def update_state(self, fdm): 43 | self.x = aircraft.State.from_fdm(fdm) 44 | self.x_delay.append(self.x) 45 | 46 | def update_state_test(self, sog, cog): 47 | t = time.time() 48 | dt = t - self.t0 49 | r_earth = 6378100 50 | vN = sog*cos(cog) 51 | vE = sog*sin(cog) 52 | vD = 0 53 | phi = 0 54 | theta = 0 55 | psi = cog 56 | latDot = vN/r_earth 57 | lat = latDot*dt 58 | lonDot = vE/r_earth/cos(lat) 59 | lon = lonDot*dt 60 | alt = 1000 -vD*dt 61 | self.x = aircraft.State(time = t, 62 | phi=phi, theta=theta, psi=psi, 63 | p=0, q=0, r=0, 64 | lat=lat, lon=lon, alt=alt, 65 | vN=vN, vE=vE, vD=vD, xacc=0, yacc=0, zacc=-9.806) 66 | self.x_delay.append(self.x) 67 | #print 'latDot:', latDot, 'lonDot:', lonDot 68 | #print 'vN:', vN, 'vE:', vE, 'vD:', vD 69 | #print 'lat:', lat, 'lon:', lon, 'alt:', alt, 70 | #print 'phi:', phi, 'theta:', theta, 'psi:', psi 71 | 72 | def get_delayed_state(self, dt=1.0): 73 | tLast = self.x_delay[-1].time 74 | i = len(self.x_delay) 75 | while True: 76 | i = i - 1 77 | if i < 0: 78 | state = self.x_delay[0] 79 | break 80 | if tLast - self.x_delay[i].time > dt: 81 | state = self.x_delay[i] 82 | break 83 | #print 'delayed by:', tLast - state.time 84 | return state 85 | 86 | def update_controls(self, m): 87 | self.u = aircraft.Controls.from_mavlink(m) 88 | 89 | def send_controls(self, jsb_console): 90 | self.u.send_to_jsbsim(jsb_console) 91 | 92 | def send_state(self, mav): 93 | self.x.send_to_mav(mav) 94 | 95 | def send_imu(self, mav): 96 | self.imu.from_state(self.x, self.attack) 97 | self.imu.send_to_mav(mav) 98 | 99 | def send_gps(self, mav): 100 | self.gps.from_state( 101 | self.get_delayed_state(1.0), 102 | self.attack) 103 | self.gps.send_to_mav(mav) 104 | 105 | def send_sensors(self, mav): 106 | t_now = time.time() 107 | if t_now - self.t_gps > self.gps_period: 108 | self.t_gps = t_now 109 | self.send_gps(mav) 110 | self.gps_count += 1 111 | 112 | t_now = time.time() 113 | if t_now - self.t_imu > self.imu_period: 114 | self.t_imu = t_now 115 | self.send_imu(mav) 116 | self.imu_count += 1 117 | 118 | t_now = time.time() 119 | if t_now - self.t_out > 1: 120 | self.t_out = t_now 121 | print('imu {0:4d} Hz, gps {1:4d} Hz\n'.format( 122 | self.imu_count, self.gps_count)) 123 | self.gps_count = 0 124 | self.imu_count = 0 125 | -------------------------------------------------------------------------------- /modules/noise.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | classes for sensor noise 5 | ''' 6 | 7 | import random 8 | 9 | class GaussianNoise(object): 10 | 11 | def __init__(self, mean, variance): 12 | self.mean = mean 13 | self.variance = variance 14 | 15 | def get_noise(self): 16 | return random.gauss(self.mean, self.variance) 17 | 18 | def __add__(self, x): 19 | return x + self.get_noise() 20 | 21 | def __radd__(self, x): 22 | return x + self.get_noise() 23 | -------------------------------------------------------------------------------- /modules/rotmat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # vector3 and rotation matrix classes 4 | # This follows the conventions in the ArduPilot code, 5 | # and is essentially a python version of the AP_Math library 6 | # 7 | # Andrew Tridgell, March 2012 8 | # 9 | # This library is free software; you can redistribute it and/or modify it 10 | # under the terms of the GNU Lesser General Public License as published by the 11 | # Free Software Foundation; either version 2.1 of the License, or (at your 12 | # option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, but WITHOUT 15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 17 | # for more details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public License 20 | # along with this library; if not, write to the Free Software Foundation, 21 | # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | '''rotation matrix class 24 | ''' 25 | 26 | from math import sin, cos, sqrt, asin, atan2, pi, radians, acos 27 | 28 | class Vector3: 29 | '''a vector''' 30 | def __init__(self, x=None, y=None, z=None): 31 | if x != None and y != None and z != None: 32 | self.x = float(x) 33 | self.y = float(y) 34 | self.z = float(z) 35 | elif x != None and len(x) == 3: 36 | self.x = float(x[0]) 37 | self.y = float(x[1]) 38 | self.z = float(x[2]) 39 | elif x != None: 40 | raise ValueError('bad initialiser') 41 | else: 42 | self.x = float(0) 43 | self.y = float(0) 44 | self.z = float(0) 45 | 46 | def __repr__(self): 47 | return 'Vector3(%.2f, %.2f, %.2f)' % (self.x, 48 | self.y, 49 | self.z) 50 | 51 | def __add__(self, v): 52 | return Vector3(self.x + v.x, 53 | self.y + v.y, 54 | self.z + v.z) 55 | 56 | __radd__ = __add__ 57 | 58 | def __sub__(self, v): 59 | return Vector3(self.x - v.x, 60 | self.y - v.y, 61 | self.z - v.z) 62 | 63 | def __neg__(self): 64 | return Vector3(-self.x, -self.y, -self.z) 65 | 66 | def __rsub__(self, v): 67 | return Vector3(v.x - self.x, 68 | v.y - self.y, 69 | v.z - self.z) 70 | 71 | def __mul__(self, v): 72 | if isinstance(v, Vector3): 73 | '''dot product''' 74 | return self.x*v.x + self.y*v.y + self.z*v.z 75 | return Vector3(self.x * v, 76 | self.y * v, 77 | self.z * v) 78 | 79 | __rmul__ = __mul__ 80 | 81 | def __div__(self, v): 82 | return Vector3(self.x / v, 83 | self.y / v, 84 | self.z / v) 85 | 86 | def __mod__(self, v): 87 | '''cross product''' 88 | return Vector3(self.y*v.z - self.z*v.y, 89 | self.z*v.x - self.x*v.z, 90 | self.x*v.y - self.y*v.x) 91 | 92 | def __copy__(self): 93 | return Vector3(self.x, self.y, self.z) 94 | 95 | copy = __copy__ 96 | 97 | def length(self): 98 | return sqrt(self.x**2 + self.y**2 + self.z**2) 99 | 100 | def zero(self): 101 | self.x = self.y = self.z = 0 102 | 103 | def angle(self, v): 104 | '''return the angle between this vector and another vector''' 105 | return acos(self * v) / (self.length() * v.length()) 106 | 107 | def normalized(self): 108 | return self / self.length() 109 | 110 | def normalize(self): 111 | v = self.normalized() 112 | self.x = v.x 113 | self.y = v.y 114 | self.z = v.z 115 | 116 | class Matrix3: 117 | '''a 3x3 matrix, intended as a rotation matrix''' 118 | def __init__(self, a=None, b=None, c=None): 119 | if a is not None and b is not None and c is not None: 120 | self.a = a.copy() 121 | self.b = b.copy() 122 | self.c = c.copy() 123 | else: 124 | self.identity() 125 | 126 | def __repr__(self): 127 | return 'Matrix3((%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f))' % ( 128 | self.a.x, self.a.y, self.a.z, 129 | self.b.x, self.b.y, self.b.z, 130 | self.c.x, self.c.y, self.c.z) 131 | 132 | def identity(self): 133 | self.a = Vector3(1,0,0) 134 | self.b = Vector3(0,1,0) 135 | self.c = Vector3(0,0,1) 136 | 137 | def transposed(self): 138 | return Matrix3(Vector3(self.a.x, self.b.x, self.c.x), 139 | Vector3(self.a.y, self.b.y, self.c.y), 140 | Vector3(self.a.z, self.b.z, self.c.z)) 141 | 142 | 143 | def from_euler(self, roll, pitch, yaw): 144 | '''fill the matrix from Euler angles in radians''' 145 | cp = cos(pitch) 146 | sp = sin(pitch) 147 | sr = sin(roll) 148 | cr = cos(roll) 149 | sy = sin(yaw) 150 | cy = cos(yaw) 151 | 152 | self.a.x = cp * cy 153 | self.a.y = (sr * sp * cy) - (cr * sy) 154 | self.a.z = (cr * sp * cy) + (sr * sy) 155 | self.b.x = cp * sy 156 | self.b.y = (sr * sp * sy) + (cr * cy) 157 | self.b.z = (cr * sp * sy) - (sr * cy) 158 | self.c.x = -sp 159 | self.c.y = sr * cp 160 | self.c.z = cr * cp 161 | 162 | 163 | def to_euler(self): 164 | '''find Euler angles for the matrix''' 165 | if self.c.x >= 1.0: 166 | pitch = pi 167 | elif self.c.x <= -1.0: 168 | pitch = -pi 169 | else: 170 | pitch = -asin(self.c.x) 171 | roll = atan2(self.c.y, self.c.z) 172 | yaw = atan2(self.b.x, self.a.x) 173 | return (roll, pitch, yaw) 174 | 175 | def __add__(self, m): 176 | return Matrix3(self.a + m.a, self.b + m.b, self.c + m.c) 177 | 178 | __radd__ = __add__ 179 | 180 | def __sub__(self, m): 181 | return Matrix3(self.a - m.a, self.b - m.b, self.c - m.c) 182 | 183 | def __rsub__(self, m): 184 | return Matrix3(m.a - self.a, m.b - self.b, m.c - self.c) 185 | 186 | def __mul__(self, other): 187 | if isinstance(other, Vector3): 188 | v = other 189 | return Vector3(self.a.x * v.x + self.a.y * v.y + self.a.z * v.z, 190 | self.b.x * v.x + self.b.y * v.y + self.b.z * v.z, 191 | self.c.x * v.x + self.c.y * v.y + self.c.z * v.z) 192 | elif isinstance(other, Matrix3): 193 | m = other 194 | return Matrix3(Vector3(self.a.x * m.a.x + self.a.y * m.b.x + self.a.z * m.c.x, 195 | self.a.x * m.a.y + self.a.y * m.b.y + self.a.z * m.c.y, 196 | self.a.x * m.a.z + self.a.y * m.b.z + self.a.z * m.c.z), 197 | Vector3(self.b.x * m.a.x + self.b.y * m.b.x + self.b.z * m.c.x, 198 | self.b.x * m.a.y + self.b.y * m.b.y + self.b.z * m.c.y, 199 | self.b.x * m.a.z + self.b.y * m.b.z + self.b.z * m.c.z), 200 | Vector3(self.c.x * m.a.x + self.c.y * m.b.x + self.c.z * m.c.x, 201 | self.c.x * m.a.y + self.c.y * m.b.y + self.c.z * m.c.y, 202 | self.c.x * m.a.z + self.c.y * m.b.z + self.c.z * m.c.z)) 203 | v = other 204 | return Matrix3(self.a * v, self.b * v, self.c * v) 205 | 206 | def __div__(self, v): 207 | return Matrix3(self.a / v, self.b / v, self.c / v) 208 | 209 | def __neg__(self): 210 | return Matrix3(-self.a, -self.b, -self.c) 211 | 212 | def __copy__(self): 213 | return Matrix3(self.a, self.b, self.c) 214 | 215 | copy = __copy__ 216 | 217 | def rotate(self, g): 218 | '''rotate the matrix by a given amount on 3 axes''' 219 | temp_matrix = Matrix3() 220 | a = self.a 221 | b = self.b 222 | c = self.c 223 | temp_matrix.a.x = a.y * g.z - a.z * g.y 224 | temp_matrix.a.y = a.z * g.x - a.x * g.z 225 | temp_matrix.a.z = a.x * g.y - a.y * g.x 226 | temp_matrix.b.x = b.y * g.z - b.z * g.y 227 | temp_matrix.b.y = b.z * g.x - b.x * g.z 228 | temp_matrix.b.z = b.x * g.y - b.y * g.x 229 | temp_matrix.c.x = c.y * g.z - c.z * g.y 230 | temp_matrix.c.y = c.z * g.x - c.x * g.z 231 | temp_matrix.c.z = c.x * g.y - c.y * g.x 232 | self.a += temp_matrix.a 233 | self.b += temp_matrix.b 234 | self.c += temp_matrix.c 235 | 236 | def normalize(self): 237 | '''re-normalise a rotation matrix''' 238 | error = self.a * self.b 239 | t0 = self.a - (self.b * (0.5 * error)) 240 | t1 = self.b - (self.a * (0.5 * error)) 241 | t2 = t0 % t1 242 | self.a = t0 * (1.0 / t0.length()) 243 | self.b = t1 * (1.0 / t1.length()) 244 | self.c = t2 * (1.0 / t2.length()) 245 | 246 | def trace(self): 247 | '''the trace of the matrix''' 248 | return self.a.x + self.b.y + self.c.z 249 | 250 | def test_euler(): 251 | '''check that from_euler() and to_euler() are consistent''' 252 | m = Matrix3() 253 | from math import radians, degrees 254 | for r in range(-179, 179, 3): 255 | for p in range(-89, 89, 3): 256 | for y in range(-179, 179, 3): 257 | m.from_euler(radians(r), radians(p), radians(y)) 258 | (r2, p2, y2) = m.to_euler() 259 | v1 = Vector3(r,p,y) 260 | v2 = Vector3(degrees(r2),degrees(p2),degrees(y2)) 261 | diff = v1 - v2 262 | if diff.length() > 1.0e-12: 263 | print('EULER ERROR:', v1, v2, diff.length()) 264 | 265 | if __name__ == "__main__": 266 | import doctest 267 | doctest.testmod() 268 | test_euler() 269 | -------------------------------------------------------------------------------- /modules/sensors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | classes for sensor models 5 | ''' 6 | 7 | import struct, time, numpy 8 | from math import sin, cos 9 | 10 | import noise 11 | from constants import * 12 | 13 | 14 | def toint(num): 15 | if num < 0: 16 | return 0 17 | elif num > 65535: 18 | return 65535 19 | else: 20 | return int(num) 21 | 22 | class Imu(object): 23 | 24 | def __init__(self, time, xacc, yacc, zacc, xgyro, ygyro, zgyro, xmag, ymag, zmag, 25 | abs_pressure, diff_pressure, pressure_alt, temperature, 26 | acc_mean=0, acc_var=0, 27 | gyro_mean=0, gyro_var=0, 28 | mag_mean=0, mag_var=0, 29 | baro_mean=0, baro_var=0): 30 | 31 | self.time = time 32 | self.xacc = xacc 33 | self.yacc = yacc 34 | self.zacc = zacc 35 | self.xgyro = xgyro 36 | self.ygyro = ygyro 37 | self.zgyro = zgyro 38 | self.xmag = xmag 39 | self.ymag = ymag 40 | self.zmag = zmag 41 | self.abs_pressure = abs_pressure 42 | self.diff_pressure = diff_pressure 43 | self.pressure_alt = pressure_alt 44 | self.temperature = temperature 45 | #TODO restore noise after testing 46 | self.acc_noise = noise.GaussianNoise(acc_mean, acc_var) 47 | self.gyro_noise = noise.GaussianNoise(gyro_mean, gyro_var) 48 | self.mag_noise = noise.GaussianNoise(mag_mean, mag_var) 49 | self.baro_noise = noise.GaussianNoise(baro_mean, baro_var) 50 | #self.acc_noise = noise.GaussianNoise(0,0) 51 | #self.gyro_noise = noise.GaussianNoise(0,0) 52 | #self.mag_noise = noise.GaussianNoise(0,0) 53 | #self.baro_noise = noise.GaussianNoise(0,0) 54 | 55 | def send_to_mav(self, mav): 56 | try: 57 | bar2mbar = 1000.0 58 | # see pymavlink definition of hil_sensor_send(), and struct.pack() 59 | mav.hil_sensor_send(int(self.time*sec2usec), 60 | self.xacc, self.yacc, self.zacc, 61 | self.xgyro, self.ygyro, self.zgyro, 62 | self.xmag, self.ymag, self.zmag, 63 | self.abs_pressure*bar2mbar, 64 | self.diff_pressure*bar2mbar, 65 | self.pressure_alt, 66 | self.temperature, int(65535)) 67 | except struct.error: 68 | print 'mav hil sensor packet data exceeds int bounds' 69 | 70 | @classmethod 71 | def default(cls): 72 | return cls(time.time(), 73 | xacc=0, yacc=0, zacc=0, 74 | xgyro=0, ygyro=0, zgyro=0, 75 | xmag=0, ymag=0, zmag=0, 76 | abs_pressure=0, diff_pressure=0, 77 | pressure_alt=0, temperature=0, 78 | acc_mean = 0, acc_var = .01, 79 | gyro_mean = 0, gyro_var = .01, 80 | mag_mean = 0, mag_var = .01, 81 | baro_mean = 0, baro_var = 0.0000001) 82 | 83 | def from_state(self, state, attack=None): 84 | 85 | # accelerometer 86 | self.xacc = state.xacc + self.acc_noise 87 | self.yacc = state.yacc + self.acc_noise 88 | self.zacc = state.zacc + self.acc_noise 89 | 90 | # gyroscope 91 | self.xgyro = state.p + self.gyro_noise 92 | self.ygyro = state.q + self.gyro_noise 93 | self.zgyro = state.r + self.gyro_noise 94 | 95 | # mag field properties 96 | # setting to constants, should 97 | # depend on position 98 | magFieldStrength = 0.5 99 | dip = 60.0*deg2rad 100 | dec = 0.0*deg2rad 101 | 102 | magVectN = magFieldStrength*numpy.matrix([ 103 | [cos(dip)*cos(dec)], 104 | [cos(dip)*sin(dec)], 105 | [sin(dip)]]) 106 | magVectB = numpy.transpose(state.C_nb)*magVectN 107 | 108 | # magnetometer 109 | self.xmag = magVectB[0,0] + self.mag_noise 110 | self.ymag = magVectB[1,0] + self.mag_noise 111 | self.zmag = magVectB[2,0] + self.mag_noise 112 | 113 | # baro 114 | ground_press = 1.01325 #bar 115 | ground_tempC = 21.0 116 | tempC = 21.0 # TODO temp variation 117 | tempAvgK = T0 + (tempC + ground_tempC)/2 118 | 119 | self.abs_pressure = ground_press/math.exp(state.alt*(g/R)/tempAvgK) + self.baro_noise 120 | self.diff_pressure = (0.5*(1.225)*((state.vN)**2 +(state.vE)**2 + (state.vD)**2))*0.00001 + self.baro_noise # TODO, for velocity 121 | self.temperature = tempC 122 | self.pressure_alt = state.alt # TODO compute from pressure 123 | 124 | self.time = time.time() 125 | 126 | class Gps(object): 127 | 128 | def __init__(self, time, fix_type, lat, lon, alt, eph, epv, vel, cog, satellites_visible, 129 | pos_mean=0, pos_var=0, alt_mean=0, alt_var=0, vel_mean=0, vel_var=0): 130 | 131 | self.time = time 132 | self.fix_type = fix_type 133 | self.lat = lat 134 | self.lon = lon 135 | self.alt = alt 136 | self.eph = eph 137 | self.epv = epv 138 | self.vel = vel 139 | self.cog = cog 140 | self.satellites_visible = satellites_visible 141 | self.vn = 0 142 | self.ve = 0 143 | self.vd = 0 144 | 145 | self.pos_noise = noise.GaussianNoise(pos_mean, pos_var) 146 | self.alt_noise = noise.GaussianNoise(alt_mean, alt_var) 147 | self.vel_noise = noise.GaussianNoise(vel_mean, vel_var) 148 | 149 | def send_to_mav(self, mav): 150 | try: 151 | #see pymavlink hil_gps_send() definition and struct.pack() 152 | # for encoding information. 153 | mav.hil_gps_send(int(self.time*sec2usec), 154 | toint(self.fix_type), 155 | int(self.lat*rad2degE7), int(self.lon*rad2degE7), 156 | int(self.alt*m2mm), 157 | toint(self.eph*m2cm), toint(self.epv*m2cm), 158 | toint(self.vel*m2cm), 159 | int(self.vn), int(self.ve), int(self.vd), 160 | toint(self.cog*rad2deg*100), 161 | toint(self.satellites_visible)) 162 | except struct.error as e: 163 | raise e 164 | print 'mav hil gps packet data exceeds int bounds' 165 | 166 | def from_state(self, state, attack=None): 167 | 168 | self.vn = state.vN 169 | self.ve = state.vE 170 | self.vd = state.vD 171 | sog = math.sqrt(state.vN*state.vN + state.vE*state.vE) 172 | cog = math.atan2(state.vE, state.vN) 173 | 174 | if cog < 0: cog += 2*math.pi 175 | 176 | r_earth = 6378100 177 | pos_north_error = self.pos_noise + 0 178 | pos_east_error = self.pos_noise + 0 179 | 180 | self.time = time.time() 181 | self.fix_type = 3 182 | self.lat = state.lat + pos_north_error/r_earth 183 | self.lon = state.lon + pos_east_error*cos(state.lat)/r_earth 184 | self.alt = state.alt + self.alt_noise 185 | self.eph = 1.0 186 | self.epv = 5.0 187 | self.vel = sog + self.vel_noise 188 | self.cog = cog 189 | self.satellites_visible = 10 190 | 191 | @classmethod 192 | def default(cls): 193 | return cls(time.time(),0,0,0,0,0,0,0,0,0, 194 | pos_mean = 0, 195 | pos_var = 1, 196 | alt_mean = 0, 197 | alt_var = 5, 198 | vel_mean = 0, 199 | vel_var = 1 200 | ) 201 | -------------------------------------------------------------------------------- /modules/util.py: -------------------------------------------------------------------------------- 1 | import math 2 | from math import sqrt, acos, cos, pi, sin, atan2 3 | import os, pexpect, sys, time, random 4 | from rotmat import Vector3, Matrix3 5 | from subprocess import call, check_call,Popen, PIPE 6 | 7 | def m2ft(x): 8 | '''meters to feet''' 9 | return float(x) / 0.3048 10 | 11 | def ft2m(x): 12 | '''feet to meters''' 13 | return float(x) * 0.3048 14 | 15 | def kt2mps(x): 16 | return x * 0.514444444 17 | 18 | def mps2kt(x): 19 | return x / 0.514444444 20 | 21 | def topdir(): 22 | '''return top of git tree where hil is running from''' 23 | d = os.path.dirname(os.path.realpath(__file__)) 24 | assert(os.path.basename(d)=='pysim') 25 | d = os.path.dirname(d) 26 | assert(os.path.basename(d)=='hil') 27 | d = os.path.dirname(d) 28 | assert(os.path.basename(d)=='Tools') 29 | d = os.path.dirname(d) 30 | return d 31 | 32 | def reltopdir(path): 33 | '''return a path relative to topdir()''' 34 | return os.path.normpath(os.path.join(topdir(), path)) 35 | 36 | 37 | def run_cmd(cmd, dir=".", show=False, output=False, checkfail=True): 38 | '''run a shell command''' 39 | if show: 40 | print("Running: '%s' in '%s'" % (cmd, dir)) 41 | if output: 42 | return Popen([cmd], shell=True, stdout=PIPE, cwd=dir).communicate()[0] 43 | elif checkfail: 44 | return check_call(cmd, shell=True, cwd=dir) 45 | else: 46 | return call(cmd, shell=True, cwd=dir) 47 | 48 | def rmfile(path): 49 | '''remove a file if it exists''' 50 | try: 51 | os.unlink(path) 52 | except Exception: 53 | pass 54 | 55 | def deltree(path): 56 | '''delete a tree of files''' 57 | run_cmd('rm -rf %s' % path) 58 | 59 | 60 | 61 | def build_SIL(atype, target='sitl'): 62 | '''build desktop SIL''' 63 | run_cmd("make clean %s" % target, 64 | dir=reltopdir(atype), 65 | checkfail=True) 66 | return True 67 | 68 | def build_AVR(atype, board='mega2560'): 69 | '''build AVR binaries''' 70 | config = open(reltopdir('config.mk'), mode='w') 71 | config.write(''' 72 | BOARD=%s 73 | PORT=/dev/null 74 | ''' % board) 75 | config.close() 76 | run_cmd("make clean", dir=reltopdir(atype), checkfail=True) 77 | run_cmd("make", dir=reltopdir(atype), checkfail=True) 78 | return True 79 | 80 | 81 | # list of pexpect children to close on exit 82 | close_list = [] 83 | 84 | def pexpect_autoclose(p): 85 | '''mark for autoclosing''' 86 | global close_list 87 | close_list.append(p) 88 | 89 | def pexpect_close(p): 90 | '''close a pexpect child''' 91 | global close_list 92 | 93 | try: 94 | p.close() 95 | except Exception: 96 | pass 97 | try: 98 | p.close(force=True) 99 | except Exception: 100 | pass 101 | if p in close_list: 102 | close_list.remove(p) 103 | 104 | def pexpect_close_all(): 105 | '''close all pexpect children''' 106 | global close_list 107 | for p in close_list[:]: 108 | pexpect_close(p) 109 | 110 | def pexpect_drain(p): 111 | '''drain any pending input''' 112 | try: 113 | p.read_nonblocking(1000, timeout=0) 114 | except pexpect.TIMEOUT: 115 | pass 116 | 117 | def start_SIL(atype, valgrind=False, wipe=False, CLI=False, height=None): 118 | '''launch a SIL instance''' 119 | cmd="" 120 | if valgrind and os.path.exists('/usr/bin/valgrind'): 121 | cmd += 'valgrind -q --log-file=%s-valgrind.log ' % atype 122 | cmd += reltopdir('tmp/%s.build/%s.elf' % (atype, atype)) 123 | if wipe: 124 | cmd += ' -w' 125 | if CLI: 126 | cmd += ' -s' 127 | if height is not None: 128 | cmd += ' -H %u' % height 129 | ret = pexpect.spawn(cmd, logfile=sys.stdout, timeout=5) 130 | ret.delaybeforesend = 0 131 | pexpect_autoclose(ret) 132 | ret.expect('Waiting for connection') 133 | return ret 134 | 135 | def start_MAVProxy_SIL(atype, aircraft=None, setup=False, master='tcp:127.0.0.1:5760', 136 | options=None, logfile=sys.stdout): 137 | '''launch mavproxy connected to a SIL instance''' 138 | global close_list 139 | MAVPROXY = os.getenv('MAVPROXY_CMD', reltopdir('../MAVProxy/mavproxy.py')) 140 | cmd = MAVPROXY + ' --master=%s --out=127.0.0.1:14550' % master 141 | if setup: 142 | cmd += ' --setup' 143 | if aircraft is None: 144 | aircraft = 'test.%s' % atype 145 | cmd += ' --aircraft=%s' % aircraft 146 | if options is not None: 147 | cmd += ' ' + options 148 | ret = pexpect.spawn(cmd, logfile=logfile, timeout=60) 149 | ret.delaybeforesend = 0 150 | pexpect_autoclose(ret) 151 | return ret 152 | 153 | 154 | def expect_setup_callback(e, callback): 155 | '''setup a callback that is called once a second while waiting for 156 | patterns''' 157 | def _expect_callback(pattern, timeout=e.timeout): 158 | tstart = time.time() 159 | while time.time() < tstart + timeout: 160 | try: 161 | ret = e.expect_saved(pattern, timeout=1) 162 | return ret 163 | except pexpect.TIMEOUT: 164 | e.expect_user_callback(e) 165 | pass 166 | print("Timed out looking for %s" % pattern) 167 | raise pexpect.TIMEOUT(timeout) 168 | 169 | e.expect_user_callback = callback 170 | e.expect_saved = e.expect 171 | e.expect = _expect_callback 172 | 173 | def mkdir_p(dir): 174 | '''like mkdir -p''' 175 | if not dir: 176 | return 177 | if dir.endswith("/"): 178 | mkdir_p(dir[:-1]) 179 | return 180 | if os.path.isdir(dir): 181 | return 182 | mkdir_p(os.path.dirname(dir)) 183 | os.mkdir(dir) 184 | 185 | def loadfile(fname): 186 | '''load a file as a string''' 187 | f = open(fname, mode='r') 188 | r = f.read() 189 | f.close() 190 | return r 191 | 192 | def lock_file(fname): 193 | '''lock a file''' 194 | import fcntl 195 | f = open(fname, mode='w') 196 | try: 197 | fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB) 198 | except Exception: 199 | return None 200 | return f 201 | 202 | def check_parent(parent_pid=os.getppid()): 203 | '''check our parent process is still alive''' 204 | try: 205 | os.kill(parent_pid, 0) 206 | except Exception: 207 | print("Parent had finished - exiting") 208 | sys.exit(1) 209 | 210 | 211 | def EarthRatesToBodyRates(dcm, earth_rates): 212 | '''convert the angular velocities from earth frame to 213 | body frame. Thanks to James Goppert for the formula 214 | 215 | all inputs and outputs are in radians 216 | 217 | returns a gyro vector in body frame, in rad/s 218 | ''' 219 | from math import sin, cos 220 | 221 | (phi, theta, psi) = dcm.to_euler() 222 | phiDot = earth_rates.x 223 | thetaDot = earth_rates.y 224 | psiDot = earth_rates.z 225 | 226 | p = phiDot - psiDot*sin(theta) 227 | q = cos(phi)*thetaDot + sin(phi)*psiDot*cos(theta) 228 | r = cos(phi)*psiDot*cos(theta) - sin(phi)*thetaDot 229 | return Vector3(p, q, r) 230 | 231 | def BodyRatesToEarthRates(dcm, gyro): 232 | '''convert the angular velocities from body frame to 233 | earth frame. 234 | 235 | all inputs and outputs are in radians/s 236 | 237 | returns a earth rate vector 238 | ''' 239 | from math import sin, cos, tan, fabs 240 | 241 | p = gyro.x 242 | q = gyro.y 243 | r = gyro.z 244 | 245 | (phi, theta, psi) = dcm.to_euler() 246 | 247 | phiDot = p + tan(theta)*(q*sin(phi) + r*cos(phi)) 248 | thetaDot = q*cos(phi) - r*sin(phi) 249 | if fabs(cos(theta)) < 1.0e-20: 250 | theta += 1.0e-10 251 | psiDot = (q*sin(phi) + r*cos(phi))/cos(theta) 252 | return Vector3(phiDot, thetaDot, psiDot) 253 | 254 | def gps_newpos(lat, lon, bearing, distance): 255 | '''extrapolate latitude/longitude given a heading and distance 256 | thanks to http://www.movable-type.co.uk/scripts/latlong.html 257 | ''' 258 | from math import sin, asin, cos, atan2, radians, degrees 259 | radius_of_earth = 6378100.0 # in meters 260 | 261 | lat1 = radians(lat) 262 | lon1 = radians(lon) 263 | brng = radians(bearing) 264 | dr = distance/radius_of_earth 265 | 266 | lat2 = asin(sin(lat1)*cos(dr) + 267 | cos(lat1)*sin(dr)*cos(brng)) 268 | lon2 = lon1 + atan2(sin(brng)*sin(dr)*cos(lat1), 269 | cos(dr)-sin(lat1)*sin(lat2)) 270 | return (degrees(lat2), degrees(lon2)) 271 | 272 | 273 | class Wind(object): 274 | '''a wind generation object''' 275 | def __init__(self, windstring, cross_section=0.1): 276 | a = windstring.split(',') 277 | if len(a) != 3: 278 | raise RuntimeError("Expected wind in speed,direction,turbulance form, not %s" % windstring) 279 | self.speed = float(a[0]) # m/s 280 | self.direction = float(a[1]) # direction the wind is going in 281 | self.turbulance= float(a[2]) # turbulance factor (standard deviation) 282 | 283 | # the cross-section of the aircraft to wind. This is multiplied by the 284 | # difference in the wind and the velocity of the aircraft to give the acceleration 285 | self.cross_section = cross_section 286 | 287 | # the time constant for the turbulance - the average period of the 288 | # changes over time 289 | self.turbulance_time_constant = 5.0 290 | 291 | # wind time record 292 | self.tlast = time.time() 293 | 294 | # initial turbulance multiplier 295 | self.turbulance_mul = 1.0 296 | 297 | def current(self, deltat=None): 298 | '''return current wind speed and direction as a tuple 299 | speed is in m/s, direction in degrees 300 | ''' 301 | if deltat is None: 302 | tnow = time.time() 303 | deltat = tnow - self.tlast 304 | self.tlast = tnow 305 | 306 | # update turbulance random walk 307 | w_delta = math.sqrt(deltat)*(1.0-random.gauss(1.0, self.turbulance)) 308 | w_delta -= (self.turbulance_mul-1.0)*(deltat/self.turbulance_time_constant) 309 | self.turbulance_mul += w_delta 310 | speed = self.speed * math.fabs(self.turbulance_mul) 311 | return (speed, self.direction) 312 | 313 | 314 | # Calculate drag. 315 | def drag(self, velocity, deltat=None, testing=None): 316 | '''return current wind force in Earth frame. The velocity parameter is 317 | a Vector3 of the current velocity of the aircraft in earth frame, m/s''' 318 | from math import radians 319 | 320 | # (m/s, degrees) : wind vector as a magnitude and angle. 321 | (speed, direction) = self.current(deltat=deltat) 322 | # speed = self.speed 323 | # direction = self.direction 324 | 325 | # Get the wind vector. 326 | w = toVec(speed, radians(direction)) 327 | 328 | obj_speed = velocity.length() 329 | 330 | # Compute the angle between the object vector and wind vector by taking 331 | # the dot product and dividing by the magnitudes. 332 | d = w.length() * obj_speed 333 | if d == 0: 334 | alpha = 0 335 | else: 336 | alpha = acos((w * velocity) / d) 337 | 338 | # Get the relative wind speed and angle from the object. Note that the 339 | # relative wind speed includes the velocity of the object; i.e., there 340 | # is a headwind equivalent to the object's speed even if there is no 341 | # absolute wind. 342 | (rel_speed, beta) = apparent_wind(speed, obj_speed, alpha) 343 | 344 | # Return the vector of the relative wind, relative to the coordinate 345 | # system. 346 | relWindVec = toVec(rel_speed, beta + atan2(velocity.y, velocity.x)) 347 | 348 | # Combine them to get the acceleration vector. 349 | return Vector3( acc(relWindVec.x, drag_force(self, relWindVec.x)) 350 | , acc(relWindVec.y, drag_force(self, relWindVec.y)) 351 | , 0 ) 352 | 353 | # http://en.wikipedia.org/wiki/Apparent_wind 354 | # 355 | # Returns apparent wind speed and angle of apparent wind. Alpha is the angle 356 | # between the object and the true wind. alpha of 0 rads is a headwind; pi a 357 | # tailwind. Speeds should always be positive. 358 | def apparent_wind(wind_sp, obj_speed, alpha): 359 | delta = wind_sp * cos(alpha) 360 | x = wind_sp**2 + obj_speed**2 + 2 * obj_speed * delta 361 | rel_speed = sqrt(x) 362 | if rel_speed == 0: 363 | beta = pi 364 | else: 365 | beta = acos((delta + obj_speed) / rel_speed) 366 | 367 | return (rel_speed, beta) 368 | 369 | # See http://en.wikipedia.org/wiki/Drag_equation 370 | # 371 | # Drag equation is F(a) = cl * p/2 * v^2 * a, where cl : drag coefficient 372 | # (let's assume it's low, .e.g., 0.2), p : density of air (assume about 1 373 | # kg/m^3, the density just over 1500m elevation), v : relative speed of wind 374 | # (to the body), a : area acted on (this is captured by the cross_section 375 | # paramter). 376 | # 377 | # So then we have 378 | # F(a) = 0.2 * 1/2 * v^2 * cross_section = 0.1 * v^2 * cross_section 379 | def drag_force(wind, sp): 380 | return (sp**2.0) * 0.1 * wind.cross_section 381 | 382 | # Function to make the force vector. relWindVec is the direction the apparent 383 | # wind comes *from*. We want to compute the accleration vector in the direction 384 | # the wind blows to. 385 | def acc(val, mag): 386 | if val == 0: 387 | return mag 388 | else: 389 | return (val / abs(val)) * (0 - mag) 390 | 391 | # Converts a magnitude and angle (radians) to a vector in the xy plane. 392 | def toVec(magnitude, angle): 393 | v = Vector3(magnitude, 0, 0) 394 | m = Matrix3() 395 | m.from_euler(0, 0, angle) 396 | return m.transposed() * v 397 | 398 | 399 | if __name__ == "__main__": 400 | import doctest 401 | doctest.testmod() 402 | -------------------------------------------------------------------------------- /run_sitl_fw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import pymavlink.mavutil as mavutil 3 | import pexpect, sys, os, socket, fdpexpect, select, argparse, psutil 4 | 5 | import pymavlink.fgFDM as fgFDM 6 | 7 | sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), 'modules')) 8 | 9 | import sensors, util, aircraft 10 | 11 | class Simulator(): 12 | @classmethod 13 | def command_line(cls): 14 | ''' command line parser ''' 15 | parser = argparse.ArgumentParser() 16 | parser.add_argument('--master', help='address used for UDP communication with PX4, e.g. 127.0.0.1:14560', default='127.0.0.1:14560') 17 | parser.add_argument('--script', help='relative path to jsbsim script', default='data/easystar_test.xml') 18 | parser.add_argument('--options', help='jsbsim options', default=None) 19 | parser.add_argument('--fgout', help='address used for UDP communication with flightgear, e.g. 127.0.0.1:5503', default=None) 20 | args = parser.parse_args() 21 | 22 | inst = cls(sitl_address=args.master, fgout=args.fgout, script=args.script, options=args.options) 23 | inst.run() 24 | 25 | def __init__(self, sitl_address, fgout, script, options): 26 | self.sitl_address = sitl_address 27 | self.fg_address = fgout 28 | 29 | self.Imu = sensors.Imu.default() 30 | self.Gps = sensors.Gps.default() 31 | self.Controls = aircraft.Controls.default() 32 | 33 | self.script = script 34 | self.options = options 35 | 36 | self.jsb = None 37 | self.jsb_console = None 38 | self.jsb_in = None 39 | self.jsb_out = None 40 | self.fg_out = None 41 | 42 | for proc in psutil.process_iter(): 43 | if proc.name == "JSBSim": 44 | proc.kill() 45 | 46 | def run(self): 47 | # send something to simulator to get it running 48 | self.sitl = mavutil.mavudp(self.sitl_address, input=False) 49 | self.sitl.write("hello") 50 | 51 | #setup output to flightgear 52 | 53 | if self.fg_address is not None: 54 | fg_address = (self.fg_address.split(':')[0], int(self.fg_address.split(':')[1])) 55 | self.fg_out = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 56 | self.fg_out.connect(fg_address) 57 | 58 | self.init_JSBSim() 59 | util.pexpect_drain(self.jsb_console) 60 | self.jsb_console.send('resume\n') 61 | self.jsb_set('simulation/reset',1) 62 | self.update() 63 | self.jsb.expect("\(Trim\) executed") 64 | 65 | while self.update(): pass 66 | 67 | 68 | def update(self): 69 | # watch files 70 | rin = [self.jsb_in.fileno(), self.jsb_console.fileno(), self.jsb.fileno(), self.sitl.port.fileno()] 71 | 72 | try: 73 | (rin, win, xin) = select.select(rin, [], [], 1.0) 74 | except select.error: 75 | util.check_parent() 76 | return 77 | 78 | if self.jsb_in.fileno() in rin: 79 | self.process_sensor_data() 80 | 81 | if self.sitl.port.fileno() in rin: 82 | msg = self.sitl.recv_msg() 83 | self.Controls = aircraft.Controls.from_mavlink(msg) 84 | self.Controls.send_to_jsbsim(self.jsb_console) 85 | 86 | if self.jsb_console.fileno() in rin: 87 | util.pexpect_drain(self.jsb_console) 88 | 89 | if self.jsb.fileno() in rin: 90 | util.pexpect_drain(self.jsb) 91 | 92 | return True 93 | 94 | def process_sensor_data(self): 95 | buf = self.jsb_in.recv(self.fdm.packet_size()) 96 | if len(buf) == 408: 97 | self.fdm.parse(buf) 98 | self.Imu.from_state(aircraft.State.from_fdm(self.fdm)) 99 | self.Imu.send_to_mav(self.sitl.mav) 100 | self.Gps.from_state(aircraft.State.from_fdm(self.fdm)) 101 | self.Gps.send_to_mav(self.sitl.mav) 102 | if self.fg_address is not None: 103 | self.fg_out.send(self.fdm.pack()) 104 | 105 | def init_JSBSim(self): 106 | cmd = "JSBSim --realtime --suspend --nice --simulation-rate=400 --script=%s --logdirectivefile=data/fgout.xml" % self.script 107 | jsb = pexpect.spawn(cmd, logfile=sys.stdout, timeout=10) 108 | jsb.delaybeforesend = 0 109 | util.pexpect_autoclose(jsb) 110 | i = jsb.expect(["Successfully bound to socket for input on port (\d+)", 111 | "Could not bind to socket for input"]) 112 | if i == 1: 113 | print("Failed to start JSBSim - is another copy running?") 114 | sys.exit(1) 115 | jsb.expect("Creating UDP socket on port (\d+)") 116 | jsb.expect("Successfully connected to socket for output") 117 | jsb.expect("JSBSim Execution beginning") 118 | 119 | # setup output to jsbsim 120 | jsb_out_address = ('127.0.0.1', 5124) 121 | print("JSBSim console on %s" % str(jsb_out_address)) 122 | jsb_out = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 123 | jsb_out.connect(jsb_out_address) 124 | jsb_console = fdpexpect.fdspawn(jsb_out.fileno(), logfile=sys.stdout) 125 | jsb_console.delaybeforesend = 0 126 | jsb_console.logfile = None 127 | 128 | # setup input from jsbsim 129 | jsb_in_address = ('127.0.0.1', 5123) 130 | print("JSBSim FG FDM input on %s" % str(jsb_in_address)) 131 | jsb_in = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 132 | jsb_in.bind(jsb_in_address) 133 | jsb_in.setblocking(0) 134 | 135 | # set class data 136 | self.jsb = jsb 137 | self.jsb_in = jsb_in 138 | self.jsb_out = jsb_out 139 | self.jsb_console = jsb_console 140 | self.fdm = fgFDM.fgFDM() 141 | 142 | def jsb_set(self, variable, value): 143 | '''set a JSBSim variable''' 144 | self.jsb_console.send('set %s %s\r\n' % (variable, value)) 145 | 146 | if __name__ == '__main__': 147 | Simulator.command_line() 148 | -------------------------------------------------------------------------------- /scripts/fgStart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | aircraft=c172p 3 | portFdm=5503 4 | 5 | fgfs --fdm=external \ 6 | --aircraft=$aircraft \ 7 | --native-fdm=socket,in,30,,$portFdm,udp \ 8 | --prop:/sim/frame-rate-throttle-hz=30 \ 9 | --lat=37.6166110 \ 10 | --lon=-122.4161053 \ 11 | --timeofday=noon \ 12 | --altitude=1000 \ 13 | --heading=90 \ 14 | --geometry=400x300 \ 15 | --vc=0 \ 16 | --roll=0 \ 17 | --pitch=0 \ 18 | --wind=0@0 \ 19 | --turbulence=0.0 \ 20 | --timeofday=noon \ 21 | --disable-sound \ 22 | --notrim 23 | -------------------------------------------------------------------------------- /scripts/px4MAVProxy.start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./jsbsim/runsim.py \ 3 | --script=jsbsim/easystar_test \ 4 | --home=37.6166110,-122.4161053,25,0 \ 5 | --fgout=127.0.0.1:5503 \ 6 | --simout=127.0.0.1:5501 \ 7 | --simin=127.0.0.1:5502 \ 8 | --wind=0,0,0 9 | -------------------------------------------------------------------------------- /scripts/px4Start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./jsbsim/runsim.py \ 3 | --script=jsbsim/easystar_test \ 4 | --home=37.6166110,-122.4161053,25,0 \ 5 | --fgout=127.0.0.1:5503 \ 6 | --simout=127.0.0.1:49006 \ 7 | --simin=127.0.0.1:49000 \ 8 | --wind=0,0,0 9 | --------------------------------------------------------------------------------