├── .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 |
42 |
43 |
47 |
48 |
52 |
53 |
57 |
58 |
62 |
63 |
67 |
68 |
69 |
70 |
71 |
72 | Alternator 1
73 |
74 |
75 | /controls/engines/engine[0]/master-alt
76 |
77 |
78 |
79 |
80 | Battery 1
81 |
82 |
83 | /controls/engines/engine[0]/master-bat
84 |
85 |
86 |
87 |
88 |
89 |
90 | Master Bus
91 |
92 |
93 | /controls/engines/engine[0]/starter
94 | off
95 |
96 |
97 |
98 |
99 |
100 |
101 | Master Bus
102 |
103 |
104 | /controls/switches/landing-light
105 |
106 |
107 |
108 |
109 | Master Bus
110 |
111 |
112 | /controls/switches/flashing-beacon
113 |
114 |
115 |
116 |
117 | Master Bus
118 |
119 |
120 | /controls/switches/strobe-lights
121 |
122 |
123 |
124 |
125 | Master Bus
126 |
127 |
128 | /controls/switches/taxi-lights
129 |
130 |
131 |
132 |
133 | Master Bus
134 |
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 |
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 |
41 |
42 |
43 |
44 | -fcs/roll-trim-sum
45 |
46 | -0.28
47 | 0.33
48 |
49 |
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 |
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 |
93 |
94 |
95 |
96 | fcs/flap-pos-deg
97 |
98 | 0
99 | 40
100 |
101 |
102 | 0
103 | 1
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | fcs/speedbrake-cmd-norm
112 |
113 |
114 | 0
115 |
116 |
117 |
118 | 1
119 |
120 |
121 |
122 |
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 |
223 |
224 |
225 | fcs/pitch-trim-sum
226 | 0.01745
227 |
228 | -28
229 | 23
230 |
231 |
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 |
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 |
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 |
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 |
--------------------------------------------------------------------------------