Merge pull request #8 from WEIHAOLEE/master

Sync
This commit is contained in:
Marsdolphin 2020-05-01 16:23:16 +08:00 committed by GitHub
commit b51b70da6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 149179 additions and 16593 deletions

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<PropertyList>
<name>parkingbrake</name>
<inherits-from>/Effects/model-combined-deferred</inherits-from>
<parameters>
<!-- Light Map -->
<lightmap-enabled type="int">1</lightmap-enabled>
<lightmap-multi type="int">1</lightmap-multi>
<texture n="3">
<image>../Interior/luxury/autohold_switch.png</image>
<wrap-s>repeat</wrap-s>
<wrap-t>repeat</wrap-t>
</texture>
<lightmap-factor type="float" n="0">1</lightmap-factor>
<lightmap-factor type="float" n="1">1</lightmap-factor>
<lightmap-factor type="float" n="2">1</lightmap-factor>
<lightmap-color type="vec3d" n="0"> 1. 0. 0. </lightmap-color>
<lightmap-color type="vec3d" n="1"> 0. 1. 0. </lightmap-color>
<lightmap-color type="vec3d" n="2"> 0. 0. 1. </lightmap-color>
<lightmap-factor type="float" n="3">0</lightmap-factor>
</parameters>
</PropertyList>

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<!-- Car Starter by Mars and sidi762. -->
<PropertyList>
<path>starter_luxury.ac</path>
<!--Control-->
<animation>
<type>pick</type>
<object-name>button</object-name>
<visible>true</visible>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>engine.toggleEngine(engine.engine_1)</script>
</binding>
</action>
</animation>
</PropertyList>

View File

@ -1,8 +1,7 @@
AC3Db
MATERIAL "ac3dmat1" rgb 1 1 1 amb 0.2 0.2 0.2 emis 0 0 0 spec 0.2 0.2 0.2 shi 128 trans 0
MATERIAL "Chair" rgb 0.714 0.631 0.518 amb 0.621 0.621 0.621 emis 0 0 0 spec 0.33 0.33 0.33 shi 32 trans 0
MATERIAL "Chair" rgb 1 1 1 amb 0.621 0.621 0.621 emis 0 0 0 spec 0.423529 0.423529 0.423529 shi 128 trans 0
OBJECT world
kids 9
kids 8
OBJECT poly
name "side_airbug_l"
loc 1.80832 0.819911 -0.628532
@ -2398,10 +2397,10 @@ numvert 36
0.759211 -0.143001 0.0255946
0.638145 -0.272653 -0.0372939
-0.0246606 -0.271245 -0.0403929
-0.692478 0.0454981 0.0302902
-0.692129 0.0274779 0.0784647
-0.65987 0.0454981 0.0302902
-0.659521 0.0274779 0.0784647
-0.435045 0.171724 0.0922135
-0.783646 -0.128575 -0.00100791
-0.751038 -0.128575 -0.00100791
-0.447551 -0.140854 -0.0813236
-0.435415 0.227243 0.0100935
-0.114553 0.266611 0.0143664
@ -2409,7 +2408,7 @@ numvert 36
-0.0441413 0.190691 0.0895665
-0.114182 0.211053 0.0964926
-0.156377 -0.0296676 0.129034
-0.783151 -0.153057 0.0560281
-0.750543 -0.153057 0.0560281
-0.774286 -0.272486 -0.0270612
-0.170321 -0.256144 -0.0254373
-0.0657699 -0.116115 -0.000330627
@ -2815,7 +2814,7 @@ numvert 36
-0.0657699 -0.116115 1.18183
-0.170321 -0.256144 1.20694
-0.774286 -0.272486 1.20856
-0.783151 -0.153057 1.12547
-0.750543 -0.153057 1.12547
-0.156377 -0.0296676 1.05247
-0.114182 0.211053 1.08501
-0.0441413 0.190691 1.09194
@ -2823,10 +2822,10 @@ numvert 36
-0.114553 0.266611 1.16714
-0.435415 0.227243 1.17141
-0.447551 -0.140854 1.26283
-0.783646 -0.128575 1.18251
-0.751038 -0.128575 1.18251
-0.435045 0.171724 1.08929
-0.692129 0.0274779 1.10304
-0.692478 0.0454981 1.15121
-0.659521 0.0274779 1.10304
-0.65987 0.0454981 1.15121
-0.0246606 -0.271245 1.2219
0.638145 -0.272653 1.2188
0.759211 -0.143001 1.15591
@ -3231,440 +3230,3 @@ refs 3
34 0.762697 0.712712
35 0.743776 0.708594
kids 0
OBJECT group
name "group.013"
kids 1
OBJECT group
name "group.012"
kids 1
OBJECT group
name "group.011"
kids 1
OBJECT group
name "group.010"
kids 1
OBJECT group
name "group.009"
kids 1
OBJECT group
name "group.008"
kids 1
OBJECT group
name "group.007"
kids 1
OBJECT group
name "interior"
kids 1
OBJECT group
name "group.006"
kids 1
OBJECT group
name "group.005"
kids 3
OBJECT group
name "group.004"
kids 1
OBJECT group
name "group.003"
kids 1
OBJECT group
name "group.002"
kids 1
OBJECT poly
name "Mesh64"
loc 0.471031 -0.621415 0
data 21
Mesh64 in1 Group1 Mod
crease 30.000000
hidden
numvert 18
1.5601 1.77018 0.21088
1.59079 1.70236 0.25103
1.59085 1.70206 0.45669
1.63083 1.70857 0.45669
1.63078 1.70888 0.25103
1.61921 1.77982 0.21088
1.6044 1.87074 0.24025
1.5547 1.86395 0.24025
1.57708 1.77806 0.35254
1.55957 1.7734 0.49212
1.61869 1.78305 0.49212
1.61903 1.78098 0.35254
1.5986 1.90629 0.26777
1.55419 1.89905 0.26777
1.59908 1.90332 0.43852
1.55454 1.86496 0.4589
1.55468 1.8961 0.43852
1.60422 1.87176 0.4589
numsurf 32
SURF 0x10
mat 1
refs 3
2 0.869209 0.091477
4 0.789296 0.0731974
3 0.869071 0.0723478
SURF 0x10
mat 1
refs 3
2 0.869209 0.0914774
1 0.789434 0.0923263
4 0.789297 0.073197
SURF 0x10
mat 1
refs 3
5 0.739629 0.735822
4 0.745791 0.697674
1 0.761211 0.701364
SURF 0x10
mat 1
refs 3
1 0.761211 0.701364
0 0.762426 0.741278
5 0.739629 0.735822
SURF 0x10
mat 1
refs 3
5 0.727408 0.83027
0 0.750274 0.835285
6 0.720758 0.875203
SURF 0x10
mat 1
refs 3
6 0.720122 0.874877
0 0.749706 0.835033
7 0.73917 0.879694
SURF 0x10
mat 1
refs 3
7 0.815555 0.307874
0 0.803001 0.263993
8 0.858426 0.264923
SURF 0x10
mat 1
refs 3
8 0.858449 0.26844
0 0.803023 0.267535
1 0.818816 0.232525
SURF 0x10
mat 1
refs 3
8 0.856442 0.270744
1 0.817065 0.234417
2 0.896842 0.234271
SURF 0x10
mat 1
refs 3
9 0.906792 0.268085
8 0.852197 0.267469
2 0.892847 0.23141
SURF 0x10
mat 1
refs 3
3 0.820933 0.850081
9 0.804131 0.894024
2 0.805493 0.853645
SURF 0x10
mat 1
refs 3
10 0.826958 0.888755
9 0.804131 0.894024
3 0.820933 0.850081
SURF 0x10
mat 1
refs 3
10 0.528785 0.269834
3 0.542528 0.234203
11 0.582928 0.268846
SURF 0x10
mat 1
refs 3
11 0.582928 0.268846
3 0.542528 0.234203
4 0.622306 0.234349
SURF 0x10
mat 1
refs 3
11 0.582928 0.268846
4 0.622306 0.234349
5 0.637881 0.268291
SURF 0x10
mat 1
refs 3
6 0.626488 0.311791
11 0.582928 0.268846
5 0.637881 0.268291
SURF 0x10
mat 1
refs 3
12 0.615815 0.3288
11 0.582928 0.268846
6 0.626488 0.311791
SURF 0x10
mat 1
refs 3
12 0.708606 0.888012
6 0.712513 0.867144
7 0.731389 0.872876
SURF 0x10
mat 1
refs 3
12 0.709977 0.887328
7 0.732653 0.871953
13 0.727023 0.891872
SURF 0x10
mat 1
refs 3
13 0.826538 0.324602
7 0.815433 0.308447
8 0.858368 0.26559
SURF 0x10
mat 1
refs 3
13 0.823542 0.328912
8 0.856432 0.270766
16 0.889782 0.3275
SURF 0x10
mat 1
refs 3
16 0.883619 0.333152
8 0.851564 0.275323
15 0.89201 0.31886
SURF 0x10
mat 1
refs 3
15 0.892649 0.318218
8 0.852098 0.274825
9 0.906693 0.275457
SURF 0x10
mat 1
refs 3
10 0.800145 0.720855
15 0.787778 0.770185
9 0.77729 0.725938
SURF 0x10
mat 1
refs 3
17 0.804984 0.764381
15 0.78595 0.769278
10 0.798176 0.719896
SURF 0x10
mat 1
refs 3
17 0.541672 0.312278
10 0.528785 0.269834
11 0.582928 0.268846
SURF 0x10
mat 1
refs 3
14 0.549575 0.327382
17 0.541672 0.312278
11 0.582928 0.268846
SURF 0x10
mat 1
refs 3
12 0.615815 0.3288
14 0.549575 0.327382
11 0.582928 0.268846
SURF 0x10
mat 1
refs 3
14 0.528019 0.0536827
12 0.593924 0.0618999
13 0.592146 0.0830312
SURF 0x10
mat 1
refs 3
14 0.528018 0.0536884
13 0.592146 0.0830358
16 0.52624 0.0748202
SURF 0x10
mat 1
refs 3
16 0.784363 0.721189
17 0.798529 0.699405
14 0.801463 0.716953
SURF 0x10
mat 1
refs 3
17 0.794798 0.694757
16 0.780829 0.716728
15 0.77587 0.700231
kids 0
OBJECT poly
name "Mesh65"
data 21
Mesh65 in1 Group1 Mod
crease 30.000000
hidden
numvert 8
2.08681 1.08952 0.29567
2.08681 1.08952 0.28077
2.07796 1.09061 0.28077
2.07796 1.09061 0.29567
2.07208 1.04942 0.29567
2.08093 1.04832 0.28077
2.07208 1.04942 0.28077
2.08093 1.04832 0.29567
numsurf 12
SURF 0x10
mat 1
refs 3
3 -0.365135 -0.031541
1 -0.346733 -0.042552
2 -0.346733 -0.031541
SURF 0x10
mat 1
refs 3
0 -0.365135 -0.042552
1 -0.346733 -0.042552
3 -0.365135 -0.031541
SURF 0x10
mat 1
refs 3
0 0.098136 0.447263
3 0.087208 0.448613
4 0.079952 0.397737
SURF 0x10
mat 1
refs 3
7 0.090879 0.396386
0 0.098136 0.447263
4 0.079952 0.397737
SURF 0x10
mat 1
refs 3
0 -0.365135 0.456639
7 -0.365135 0.405247
5 -0.346733 0.405247
SURF 0x10
mat 1
refs 3
0 -0.365135 0.456639
5 -0.346733 0.405247
1 -0.346733 0.456639
SURF 0x10
mat 1
refs 3
1 -0.098136 0.447263
5 -0.090879 0.396386
2 -0.087208 0.448613
SURF 0x10
mat 1
refs 3
5 -0.090879 0.396386
6 -0.079952 0.397737
2 -0.087208 0.448613
SURF 0x10
mat 1
refs 3
2 0.346733 0.456433
6 0.346733 0.405041
3 0.365135 0.456433
SURF 0x10
mat 1
refs 3
3 0.365135 0.456433
6 0.346733 0.405041
4 0.365135 0.405041
SURF 0x10
mat 1
refs 3
6 0.346733 -0.030569
7 0.365135 -0.04158
4 0.365135 -0.030569
SURF 0x10
mat 1
refs 3
7 0.365135 -0.04158
6 0.346733 -0.030569
5 0.346733 -0.04158
kids 0
OBJECT poly
name "Mesh66"
data 21
Mesh66 in1 Group1 Mod
crease 30.000000
hidden
numvert 8
2.08701 1.08924 0.41585
2.08701 1.08924 0.40055
2.07808 1.09034 0.40055
2.07808 1.09034 0.41585
2.07227 1.04948 0.41585
2.08119 1.04838 0.40055
2.07227 1.04948 0.40055
2.08119 1.04838 0.41585
numsurf 12
SURF 0x10
mat 1
refs 3
3 -0.513556 -0.031556
1 -0.494663 -0.042661
2 -0.494663 -0.031556
SURF 0x10
mat 1
refs 3
0 -0.513556 -0.042661
1 -0.494663 -0.042661
3 -0.513556 -0.031556
SURF 0x10
mat 1
refs 3
0 0.098386 0.446912
3 0.087366 0.448278
4 0.080181 0.39782
SURF 0x10
mat 1
refs 3
7 0.091201 0.396453
0 0.098386 0.446912
4 0.080181 0.39782
SURF 0x10
mat 1
refs 3
0 -0.513556 0.456319
7 -0.513556 0.40535
5 -0.494663 0.40535
SURF 0x10
mat 1
refs 3
0 -0.513556 0.456319
5 -0.494663 0.40535
1 -0.494663 0.456319
SURF 0x10
mat 1
refs 3
1 -0.098386 0.446912
5 -0.091201 0.396453
2 -0.087366 0.448278
SURF 0x10
mat 1
refs 3
5 -0.091201 0.396453
6 -0.080181 0.39782
2 -0.087366 0.448278
SURF 0x10
mat 1
refs 3
2 0.494663 0.456118
6 0.494663 0.40515
3 0.513556 0.456118
SURF 0x10
mat 1
refs 3
3 0.513556 0.456118
6 0.494663 0.40515
4 0.513556 0.40515
SURF 0x10
mat 1
refs 3
6 0.494663 -0.030605
7 0.513556 -0.04171
4 0.513556 -0.030605
SURF 0x10
mat 1
refs 3
7 0.513556 -0.04171
6 0.494663 -0.030605
5 0.494663 -0.04171
kids 0

View File

@ -31585,7 +31585,7 @@ name "handbrake.001"
loc -0.00712359 -0.30269 0.0188993
data 25
Mesh61 in1 Group1 Mod.001
texture "../../Instruments/parkingbrake/parkingbrake.png"
texture "../Instruments/parkingbrake/parkingbrake.png"
crease 30.000000
numvert 8
1.47621 1.00512 -0.00831

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
Models/Interior/luxury/ESC.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
Models/Interior/luxury/SRS.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
Models/Interior/luxury/cd.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

59775
Models/Interior/luxury/interior.ac Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,417 @@
<PropertyList>
<path>interior.ac</path>
<effect>
<inherits-from>Aircraft/followme_e-tron/Models/Effects/interior</inherits-from>
<object-name>Mesh63</object-name>
<object-name>Mesh64</object-name>
<object-name>Mesh68</object-name>
<object-name>Mesh69</object-name>
</effect>
<!-- Decoration -->
<animation>
<type>select</type>
<object-name>etc</object-name>
<object-name>card</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/bool[0]</property>
<value>1</value>
</equals>
</condition>
</animation>
<!-- STEERINGWHEEL -->
<animation>
<type>rotate</type>
<object-name>steeringwheel</object-name>
<property>sim/multiplay/generic/float[18]</property>
<factor>-1</factor>
<center>
<x-m> 1.50</x-m>
<y-m>-0.33</y-m>
<z-m> 0.97</z-m>
</center>
<axis>
<x1-m>0.98</x1-m>
<y1-m>-0.33</y1-m>
<z1-m>0.72</z1-m>
<x2-m>2.00</x2-m>
<y2-m>-0.33</y2-m>
<z2-m>1.20</z2-m>
</axis>
</animation>
<!-- Engine Starter -->
<model>
<path>Aircraft/followme_e-tron/Models/Interior/Instruments/starter/starter_luxury.xml</path>
<offsets>
<x-m>1.3</x-m>
<y-m>-0.18</y-m>
<z-m>0.93</z-m>
<pitch-deg>-10</pitch-deg>
</offsets>
</model>
<!-- MUG -->
<model>
<condition>
<equals>
<property>sim/multiplay/generic/bool[0]</property>
<value>1</value>
</equals>
</condition>
<path>Aircraft/followme_e-tron/Models/Interior/mug/mug.ac</path>
<name>mug</name>
<offsets>
<x-m>2.15</x-m>
<y-m>-0.027</y-m>
<z-m>0.755</z-m>
</offsets>
</model>
<!-- GEAR HANDLE -->
<animation>
<type>pick</type>
<object-name>gearbox</object-name>
<action>
<button>0</button>
<binding>
<command>nasal</command>
<script>engine.engine_1.toggleDirection();</script>
</binding>
</action>
</animation>
<!-- Auto hold -->
<!--<effect>
<inherits-from>Aircraft/followme_e-tron/Models/Effects/autohold</inherits-from>
<object-name>autohold_switch</object-name>
</effect>-->
<animation>
<type>pick</type>
<object-name>autohold_switch</object-name>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>autohold.toggleAutoHold()</script>
</binding>
</action>
</animation>
<animation>
<type>material</type>
<object-name>autohold_switch</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/bool[2]</property>
<value>1</value>
</equals>
</condition>
<texture>autohold_switch_LIT.png</texture>
</animation>
<animation>
<type>material</type>
<object-name>autohold_switch</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/bool[2]</property>
<value>0</value>
</equals>
</condition>
<texture>autohold_switch.png</texture>
</animation>
<animation>
<type>material</type>
<object-name>autohold_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/bool[3]</property>
<value>1</value>
</equals>
</condition>
<texture>autohold_LIT.png</texture>
</animation>
<animation>
<type>material</type>
<object-name>autohold_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/bool[3]</property>
<value>0</value>
</equals>
</condition>
<texture>panel_black.png</texture>
</animation>
<!-- Hand brake -->
<effect>
<inherits-from>Aircraft/followme_e-tron/Models/parkingbrake</inherits-from>
<object-name>handbrake.001</object-name>
</effect>
<animation>
<type>pick</type>
<object-name>handbrake.001</object-name>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>followme.toggleHandBrake()</script>
</binding>
</action>
</animation>
<animation>
<type>material</type>
<object-name>handbrake.001</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/float[19]</property>
<value>1</value>
</equals>
</condition>
<texture>parkingbrake_LIT.png</texture>
</animation>
<animation>
<type>material</type>
<object-name>handbrake.001</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/float[19]</property>
<value>0</value>
</equals>
</condition>
<texture>parkingbrake.png</texture>
</animation>
<animation>
<type>material</type>
<object-name>handbrake_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/float[19]</property>
<value>1</value>
</equals>
</condition>
<texture>handbrake_LIT.png</texture>
</animation>
<animation>
<type>material</type>
<object-name>handbrake_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/float[19]</property>
<value>0</value>
</equals>
</condition>
<texture>panel_black.png</texture>
</animation>
<!-- AEB -->
<animation>
<type>material</type>
<object-name>AEB_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/bool[4]</property>
<value>1</value>
</equals>
</condition>
<texture>AEB_LIT.png</texture>
</animation>
<animation>
<type>material</type>
<object-name>AEB_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/bool[4]</property>
<value>0</value>
</equals>
</condition>
<texture>panel_black.png</texture>
</animation>
<!-- Headlight -->
<animation>
<type>material</type>
<object-name>headlight_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/int[3]</property>
<value>1</value>
</equals>
</condition>
<texture>headlight_LIT.png</texture>
</animation>
<animation>
<type>material</type>
<object-name>headlight_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/int[3]</property>
<value>0</value>
</equals>
</condition>
<texture>panel_black.png</texture>
</animation>
<!-- HighBeam -->
<animation>
<type>material</type>
<object-name>longheadlight_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/bool[5]</property>
<value>1</value>
</equals>
</condition>
<texture>longheadlight_LIT.png</texture>
</animation>
<animation>
<type>material</type>
<object-name>longheadlight_LIT</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/bool[5]</property>
<value>0</value>
</equals>
</condition>
<texture>panel_black.png</texture>
</animation>
<!-- Indicator -->
<animation>
<type>material</type>
<object-name>inside_indicater_left</object-name>
<emission>
<red>0.33</red>
<green>1.0</green>
<blue>0</blue>
<factor-prop>sim/multiplay/generic/int[0]</factor-prop>
</emission>
</animation>
<animation>
<type>material</type>
<object-name>inside_indicater_right</object-name>
<emission>
<red>0.33</red>
<green>1.0</green>
<blue>0</blue>
<factor-prop>sim/multiplay/generic/int[1]</factor-prop>
</emission>
</animation>
<animation>
<type>pick</type>
<object-name>doubleflash</object-name>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>followme.indicatorController.false_light_toggle()</script>
</binding>
</action>
</animation>
<animation>
<type>material</type>
<object-name>doubleflash</object-name>
<condition>
<and>
<equals>
<property>sim/multiplay/generic/int[0]</property>
<value>1</value>
</equals>
<equals>
<property>sim/multiplay/generic/int[1]</property>
<value>1</value>
</equals>
</and>
</condition>
<emission>
<red>0.1</red>
<green>0</green>
<blue>0</blue>
<factor-prop>sim/multiplay/generic/int[1]</factor-prop>
</emission>
</animation>
<!-- storage_cover -->
<animation>
<type>pick</type>
<object-name>storage_cover</object-name>
<action>
<button>0</button>
<binding>
<command>property-cycle</command>
<property>controls/interior/luxury/storage_cover_pos</property>
<value type="double">0</value>
<value type="double">1</value>
</binding>
</action>
</animation>
<animation>
<type>translate</type>
<object-name>storage_cover</object-name>
<property>sim/multiplay/generic/float[23]</property>
<factor>0.13</factor>
<offset-m>0</offset-m>
<axis>
<x>1</x>
<y>0</y>
<z>0</z>
</axis>
</animation>
<!-- storage -->
<animation>
<type>select</type>
<object-name>stroage</object-name>
<condition>
<equals>
<property>sim/multiplay/generic/float[24]</property>
<value>1</value>
</equals>
</condition>
</animation>
<!-- Accelerator -->
<animation>
<type>translate</type>
<object-name>accelerator</object-name>
<property>sim/multiplay/generic/float[22]</property>
<factor> 0.05 </factor>
<axis>
<x> -1 </x>
<y> 0 </y>
<z> 0 </z>
</axis>
</animation>
<!-- Brake pedal -->
<animation>
<type>translate</type>
<object-name>brake</object-name>
<property>sim/multiplay/generic/int[4]</property>
<factor> 0.03 </factor>
<axis>
<x> -1 </x>
<y> 0 </y>
<z> 0 </z>
</axis>
</animation>
</PropertyList>

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 KiB

31946
Models/followme.ac Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,15 @@
</condition>
<path>Aircraft/followme_e-tron/Models/Interior/sport/interior.xml</path>
</model>
<model>
<condition>
<equals>
<property>sim/multiplay/generic/string[3]</property>
<value>Luxury</value>
</equals>
</condition>
<path>Aircraft/followme_e-tron/Models/Interior/luxury/interior.xml</path>
</model>
<animation>
<type>material</type>
@ -64,15 +73,6 @@
</animation>
<effect>
<inherits-from>Aircraft/followme_e-tron/Models/Effects/interior</inherits-from>
<object-name>Mesh63</object-name>
<object-name>Mesh64</object-name>
<object-name>Mesh68</object-name>
<object-name>Mesh69</object-name>
</effect>
<model>
<path>Aircraft/followme_e-tron/Models/warninglight.xml</path>
<offsets>
@ -777,6 +777,88 @@
</axis>
</animation>
<!-- COMPOSITOR LIGHTS -->
<light>
<name>left-headlight-compositor</name>
<type>spot</type>
<position>
<x-m>0.15</x-m>
<y-m>0.57</y-m>
<z-m>0.7</z-m>
</position>
<direction>
<pitch-deg>90</pitch-deg>
<roll-deg>0</roll-deg>
<heading-deg>0</heading-deg>
</direction>
<ambient>
<r>0.6</r>
<g>0.6</g>
<b>0.6</b>
<a>1</a>
</ambient>
<diffuse>
<r>0.95</r>
<g>0.9</g>
<b>0.9</b>
<a>1</a>
</diffuse>
<specular>
<r>0.95</r>
<g>0.9</g>
<b>0.9</b>
<a>1</a>
</specular>
<attenuation>
<c>1.0</c>
<l>0.09</l>
<q>0.032</q>
</attenuation>
<spot-exponent>5</spot-exponent>
<spot-cutoff>10</spot-cutoff>
<range-m>15</range-m>
</light>
<light>
<name>right-headlight-compositor</name>
<type>spot</type>
<position>
<x-m>0.15</x-m>
<y-m>-0.57</y-m>
<z-m>0.7</z-m>
</position>
<direction>
<pitch-deg>90</pitch-deg>
<roll-deg>0</roll-deg>
<heading-deg>0</heading-deg>
</direction>
<ambient>
<r>0.6</r>
<g>0.6</g>
<b>0.6</b>
<a>1</a>
</ambient>
<diffuse>
<r>0.95</r>
<g>0.9</g>
<b>0.9</b>
<a>1</a>
</diffuse>
<specular>
<r>0.95</r>
<g>0.9</g>
<b>0.9</b>
<a>1</a>
</specular>
<attenuation>
<c>1.0</c>
<l>0.09</l>
<q>0.032</q>
</attenuation>
<spot-exponent>5</spot-exponent>
<spot-cutoff>10</spot-cutoff>
<range-m>15</range-m>
</light>
<!-- LIGHTS -->
<effect>
@ -866,7 +948,7 @@
<red>1.0</red>
<green>0.8</green>
<blue>0.2</blue>
<factor-prop>sim/multiplay/generic/int[0]</factor-prop>
<factor-prop>sim/multiplay/generic/int[1]</factor-prop>
</emission>
</animation>

69
Nasal/auto_hold.nas Normal file
View File

@ -0,0 +1,69 @@
#//Auto hold system by Sidi Liang
#//Contact: sidi.liang@gmail.com
print("Auto hold system loaded");
var active = 0;
var activeNode = props.getNode("systems/auto_hold_enabled", 1);
var working = 0;
var workingNode = props.getNode("systems/auto_hold_working", 1);
var targetSpeed = 0;
var throttleNode = props.getNode("/controls/engines/engine/throttle",1);
var speedNode = props.getNode("sim/multiplay/generic/float[15]", 1);
var engineNode = props.getNode("/controls/engines/engine/started",1);
var door1 = followme.frontleft_door;
var door2 = followme.frontright_door;
var door3 = followme.rearleft_door;
var door4 = followme.rearright_door;
var autoHoldMainLoop = func(){
if(active){
throttle = throttleNode.getValue();
currentSpeed = speedNode.getValue();
if(!throttle and !math.round(currentSpeed)){
if(!door1.getpos() and !door2.getpos() and !door3.getpos() and !door4.getpos() and engineNode.getValue()){
followme.brakeController.applyBrakes(1);
working = 1;
workingNode.setValue(1);
}else{
stopAndSwitchToParking();
}
}else if(!math.round(currentSpeed)){
followme.brakeController.applyBrakes(0);
working = 0;
workingNode.setValue(0);
}
}
}
var stopAndSwitchToParking = func(){
followme.brakeController.applyBrakes(0);
working = 0;
workingNode.setValue(0);
followme.brakeController.enableHandBrake();
}
var autoHoldTimer = maketimer(0.05,autoHoldMainLoop);
var startAutoHold = func(){
autoHoldTimer.start();
active = 1;
activeNode.setValue(1);
}
var stopAutoHold = func(){
active = 0;
activeNode.setValue(0);
autoHoldTimer.stop();
currentSpeed = speedNode.getValue();
if(followme.brakeController.applyingFeetBrake){
working = 0;
workingNode.setValue(0);
followme.brakeController.applyBrakes(0);
}else if(!math.round(currentSpeed)){
stopAndSwitchToParking();
}
}
var toggleAutoHold = func(){
if(!autoHoldTimer.isRunning) startAutoHold();
else stopAutoHold();
}

View File

@ -1,4 +1,6 @@
#//Auto speed system by Sidi Liang
#//Contact: sidi.liang@gmail.com
print("Auto speed system loaded");
var active = 0;
var targetSpeed = 0;
@ -25,7 +27,8 @@ var autoSpeedMainLoop = func(){
}else{
throttle = 0;
}
throttleNode.setValue(throttle);
if(active) throttleNode.setValue(throttle);
else throttleNode.setValue(0);
leftBrakes.setValue(brakes);
rightBrakes.setValue(brakes);
lastDeltaSpeed = deltaSpeed;
@ -43,9 +46,9 @@ var startAutoSpeed = func(){
}
var stopAutoSpeed = func(){
active = 0;
autoSpeedTimer.stop();
props.getNode("/sim/messages/copilot",1).setValue("ze dong chao sue see tong yee guan bee. Auto Speeding System is off.");
active = 0;
throttleNode.setValue(0);
}
@ -84,4 +87,4 @@ var targetSpeedChange = func(speed){
return 0;
}
targetSpeed = speed;
}
}

View File

@ -1,4 +1,6 @@
#//Followme EV electrical system by Sidi Liang
#//Contact: sidi.liang@gmail.com
var kWh2kWs = func(kWh){
return kWh * 3600;
}
@ -18,7 +20,7 @@ var Series = {
isSwitch: func(){
return 0;
},
totalResistance: func(){
var total = 0;
foreach(elem; me.units){
@ -26,7 +28,7 @@ var Series = {
}
return total;
},
totalActivePower: func(){
var total = 0;
foreach(elem; me.units){
@ -36,7 +38,7 @@ var Series = {
#print("totalAP: "~total);
return total;
},
totalPower: func(){
var total = 0;
foreach(elem; me.units){
@ -44,8 +46,8 @@ var Series = {
}
return total;
},
voltage: 0, #//Volt
current: func(){
foreach(elem; me.units){
@ -61,8 +63,8 @@ var Series = {
var d = b - c;
return d / (2 * a); #//Ampere
},
calculateSeriesVoltage: func(){
var tR = me.totalResistance();
foreach(elem; me.units){
@ -74,7 +76,7 @@ var Series = {
elem.voltage = (elem.resistance/tR) * me.voltage;
}
},
calculateSeriesCurrent: func(){
foreach(elem; me.units){
elem.current = me.current();
@ -91,10 +93,10 @@ var Circuit = {
new_circuit.addNewSeriesWithUnitToParallel(cSource);
return new_circuit;
},
parallelConnection: [],
newSeriesWithUnits: func(addedUnits...){
var newSeries = Series.new();
foreach(elem; addedUnits){
@ -102,27 +104,27 @@ var Circuit = {
}
return newSeries;
},
addUnitToSeries: func(seriesNum, unit){
me.parallelConnection[seriesNum].addUnit(unit);
},
addParallel: func(units){
append(me.parallelConnection, units);
append(me.parallelConnection, units);
},
addNewSeriesWithUnitToParallel: func(units){
var new_series = me.newSeriesWithUnits(units);
me.addParallel(new_series);
},
current: 0, #//Ampere
voltage: func(){
return me.parallelConnection[0].units[0].electromotiveForce;
}, #//Volt
calculateParallelVoltage: func(){
var setVoltage = me.voltage();
foreach(elem; me.parallelConnection){
@ -134,13 +136,13 @@ var Circuit = {
elem.voltage = setVoltage;
}
}, #//Volt
calculateSeriesVoltage: func(){
foreach(elem; me.parallelConnection){
elem.calculateSeriesVoltage();
}
}, #//Volt
calculateTotalParalleCurrent: func(){
var total = 0;
foreach(elem; me.parallelConnection){
@ -155,38 +157,38 @@ var Circuit = {
me.current = total;
return total;
}, #//Ampere
calculateTotalPower: func(){
var total = 0;
foreach(elem; me.parallelConnection){
total += elem.totalPower();
}
}
return total;
},
updateInterval: 1, #//Seconds between each update
debugMode: 0,
loopCount: 0,
update: func(){
if(me.debugMode) print("Loop Count: "~me.loopCount);
me.calculateParallelVoltage();
if(me.debugMode == 2) print("Parallel Voltage Calculated");
me.calculateSeriesVoltage();
if(me.debugMode == 2) print("Series Voltage Calculated");
foreach(elem; me.parallelConnection){
elem.calculateSeriesCurrent();
}
if(me.debugMode == 2) print("Series Current Calculated");
me.calculateTotalParalleCurrent();
if(me.debugMode == 2) print("Parallel Current Calculated");
foreach(elem; me.parallelConnection){
foreach(unit; elem.units){
if(unit.isCurrentSource()) unit.currentSourceUpdate(me.calculateTotalPower(), me.updateInterval); #//Pass in negetive power for charging
@ -194,39 +196,39 @@ var Circuit = {
}
if(me.debugMode == 2) print("Power Calculated");
if(me.debugMode) print("Power: "~me.calculateTotalPower());
props.getNode("/systems/electrical/e-tron/battery-kWh", 1).setValue(me.parallelConnection[0].units[0].getRemainingInkWh());
props.getNode("/systems/electrical/e-tron/battery-remaining-percent", 1).setValue(me.parallelConnection[0].units[0].getRemainingPercentage());
props.getNode("/systems/electrical/e-tron/battery-remaining-percent-float", 1).setValue(me.parallelConnection[0].units[0].getRemainingPercentageFloat());
if(me.debugMode) print("current: "~me.current);
if(me.debugMode) print("voltage: "~me.voltage());
if(me.debugMode) print("Main Battery Remaining: "~me.parallelConnection[0].units[0].remaining);
#//if(me.debugMode)
#//if(me.debugMode)
#//print("Secondery Battery Remaining: "~me.parallelConnection[0].units[0].remaining);
me.loopCount += 1;
},
};
var Appliance = {
#//Class for any electrical appliance
new: func() {
return { parents:[Appliance] };
new: func() {
return { parents:[Appliance] };
},
isCurrentSource: func(){
return 0;
},
ratedPower: 0, #//rate power , Watt, 0 if isResistor
isSwitch: func(){
return 0;
},
resistance: 0, #//electric resistance, Ωμέγα
resistivity: 0,#//Ω·m
voltage: 0, #//electric voltage, Volt
@ -237,15 +239,15 @@ var Appliance = {
return me.current * me.current * me.resistance;
},#//heating Power
power: func(){
return me.activePower + me.activePower_kW*1000 + me.heatingPower();
return me.activePower + me.activePower_kW*1000 + me.heatingPower();
},
isResistor: 0,
applianceName: "Appliance",
applianceDescription: "This is a electric appliance",
setName: func(text){
me.applianceName = text;
},
@ -265,18 +267,18 @@ var CurrentSource = {
newCS.resetRemainingToFull();
return newCS;
},
isCurrentSource: func(){
return 1;
},
direction: 1, #//1 means it is connected in the current direction, -1 means the opposite
ratedElectromotiveForce: 0, #//Volt
electromotiveForce: 0, #//Volt
electricalCapacity: 0, #//kWs
remaining: 0, #//kWs
currentSourceUpdate: func(power, interval){
me.remaining -= power * 0.001 * interval; #//Pass in negetive power for charging
if(me.remaining <= 0){
@ -285,7 +287,7 @@ var CurrentSource = {
me.electromotiveForce = me.ratedElectromotiveForce;
}
},
#//Usage: followme.circuit_1.parallelConnection[0].units[0].resetRemainingToFull();
resetRemainingToFull: func(){
me.remaining = me.electricalCapacity;
@ -305,7 +307,7 @@ var CurrentSource = {
addToBattery: func(num){
me.remaining += num;
},
};
var Switch = {
@ -324,9 +326,9 @@ var Switch = {
isSwitch: func(){
return 1;
},
switchState: 1, #//0 for disconnect, 1 for connect
isConnected: func(){
if(me.switchState){
return 1;
@ -334,7 +336,7 @@ var Switch = {
return 0;
}
},
switchConnect: func(){
me.switchState = 1;
return 1;
@ -350,15 +352,15 @@ var Switch = {
return me.switchConnect();
}
},
};
var Cable = {
#//Class for any copper electrical cable
new: func(l = 0, s = 0.008) {
new: func(l = 0, s = 0.008) {
var newCable = { parents:[Cable, Appliance.new()], resistivity: 1.75 * 0.00000001, length: l, crossSection: s};
print("Created Cable with resistance of " ~ newCable.setResistance());
return newCable;
return newCable;
},
length: 0,#//Meter
crossSection: 0,#//Meter^2
@ -386,4 +388,4 @@ var electricTimer1 = maketimer(circuit_1.updateInterval, func circuit_1.update()
var L = setlistener("/sim/signals/fdm-initialized", func{
electricTimer1.start();
});
});

View File

@ -1,4 +1,6 @@
#//Followme EV electric engine by Sidi Liang
#//Contact: sidi.liang@gmail.com
var N2LBS = 0.2248089;
var Engine = {
#//Class for any electric engine
@ -231,6 +233,8 @@ var startEngine = func(my_engine){
var signal = my_engine.startEngine();
if(signal){
print("Engine started");
followme.safety.init();
followme.safety.enableFrontRadar();
if(props.getNode("systems/welcome-message", 1).getValue() == 1){
props.getNode("/sim/messages/copilot", 1).setValue("Beijing di san tsui jiao tong wei ti xing nin, Dao lu tsian wan tiao, ann tsuan di yi tiao, xing che bull gui fun, tsin ren liang hang lei");
}else if(props.getNode("systems/welcome-message", 1).getValue() == 2){
@ -250,6 +254,7 @@ var startEngine = func(my_engine){
var stopEngine = func(my_engine){
my_engine.stopEngine();
followme.safety.stop();
print("Engine stopped");
}

55
Nasal/library.nas Normal file
View File

@ -0,0 +1,55 @@
#//Follow Me Library by Sidi Liang
#//Contact: sidi.liang@gmail.com
var isInternalView = func(){ #// return 1 if is in internal view, otherwise return 0.
return props.getNode("sim/current-view/internal", 1).getValue();
}
var Sound = {
new: func(filename, volume = 1, path=nil) {
var m = props.Node.new({
path : path,
file : filename,
volume : volume,
});
return m;
},
};
var window = screen.window.new(10, 10, 3, 10);
var outputUI = func(content, timeout = 10){
window.autoscroll = timeout;
timeNow = systime();
if(content != getprop("/systems/outputUIContent") or (timeNow - timeout) >= getprop("/systems/lastOutputUITime")){
window.write(content);
setprop("/systems/outputUIContent",content);
setprop("/systems/lastOutputUITime",systime());
#print("Outputed");
}
}
var playAudio = func(file){ #//Plays audio files in Aircrafts/Sounds
fgcommand("play-audio-sample", Sound.new(filename: file, volume: 1, path: props.getNode("/",1).getValue("sim/aircraft-dir") ~ '/Sounds'));
}
var runCode = func(url, addition = nil){
#var params = {url:"http://fgprc.org:11415/", targetnode:"/systems/code", complete: completed};
http.save(url~addition, getprop('/sim/fg-home') ~ '/cache/code.xml').done(func(r){
var blob = io.read_properties(getprop('/sim/fg-home') ~ '/cache/code.xml');
var filename = "/cache/code.xml";
var script = blob.getValues().code; # Get the nasal string
var code = call(func {
compile(script, filename);
}, nil, nil, var compilation_errors = []);
if(size(compilation_errors)){
die("Error compiling code in: " ~ filename);
}
call(code, [], nil, nil, var runtime_errors = []);
if(size(runtime_errors)){
die("Error calling code compiled loaded from: " ~ filename);
}
var path = os.path.new(getprop('/sim/fg-home') ~ '/cache/code.xml');
path.remove();
print("Code loaded");
});
}

View File

@ -12,7 +12,7 @@ var cur_alt = 0;
var light_manager = {
run: 0,
lat_to_m: 110952.0,
lon_to_m: 0.0,
@ -35,7 +35,7 @@ var light_manager = {
light2_size: 0.0,
light2_stretch: 0.0,
light2_is_on: 0,
light3_xpos: 0.0,
light3_ypos: 0.0,
light3_zpos: 0.0,
@ -45,7 +45,7 @@ var light_manager = {
light3_size: 0.0,
light3_stretch: 0.0,
light3_is_on: 0,
light4_xpos: 0.0,
light4_ypos: 0.0,
light4_zpos: 0.0,
@ -55,7 +55,7 @@ var light_manager = {
light4_size: 0.0,
light4_stretch: 0.0,
light4_is_on: 0,
light5_xpos: 0.0,
light5_ypos: 0.0,
light5_zpos: 0.0,
@ -65,10 +65,10 @@ var light_manager = {
light5_size: 0.0,
light5_stretch: 0.0,
light5_is_on: 0,
flcpt: 0,
prev_view : 1,
nd_ref_light1_x: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/eyerel-x-m", 1),
nd_ref_light1_y: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/eyerel-y-m", 1),
nd_ref_light1_z: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/eyerel-z-m", 1),
@ -88,56 +88,56 @@ var light_manager = {
nd_ref_light4_y: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/eyerel-y-m[3]", 1),
nd_ref_light4_z: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/eyerel-z-m[3]", 1),
nd_ref_light4_dir: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/dir[3]", 1),
nd_ref_light5_x: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/eyerel-x-m[4]", 1),
nd_ref_light5_y: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/eyerel-y-m[4]", 1),
nd_ref_light5_z: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/eyerel-z-m[4]", 1),
nd_ref_light5_dir: props.globals.getNode("/sim/rendering/als-secondary-lights/lightspot/dir[4]", 1),
init: func {
# define your lights here
# lights ########
# offsets to aircraft center
me.light1_xpos = 30.0;
me.light1_ypos = 0.0;
me.light1_zpos = 2.0;
me.light2_xpos = 15.0;
me.light2_ypos = 0.0;
me.light2_zpos = 2.0;
me.light3_xpos = -2.0;
me.light3_ypos = 18.0;
me.light3_zpos = 2.0;
me.light4_xpos = -2.0;
me.light4_ypos = -18.0;
me.light4_zpos = 2.0;
me.light5_xpos = -25.0;
me.light5_ypos = 0.0;
me.light5_zpos = 2.0;
# color values
me.light1_r = 0.7;
me.light1_g = 0.7;
me.light1_b = 0.7;
me.light2_r = 0.6;
me.light2_g = 0.6;
me.light2_b = 0.6;
me.light3_r = 0.4;
me.light3_g = 0.0;
me.light3_b = 0.0;
me.light4_r = 0.0;
me.light4_g = 0.4;
me.light4_b = 0.0;
me.light5_r = 0.4;
me.light5_g = 0.4;
me.light5_b = 0.4;
@ -145,15 +145,15 @@ var light_manager = {
# spot size
me.light1_size = 12;
me.light1_stretch = 3;
me.light2_size = 6;
me.light2_stretch = 2.1;
me.light3_size = 4;
me.light4_size = 4;
me.light5_size = 5;
setprop("sim/rendering/als-secondary-lights/flash-radius", 13);
me.start();
@ -161,17 +161,17 @@ var light_manager = {
start: func {
setprop("/sim/rendering/als-secondary-lights/num-lightspots", 5);
setprop("/sim/rendering/als-secondary-lights/lightspot/size", me.light1_size);
setprop("/sim/rendering/als-secondary-lights/lightspot/size[1]", me.light2_size);
setprop("/sim/rendering/als-secondary-lights/lightspot/size[2]", me.light3_size);
setprop("/sim/rendering/als-secondary-lights/lightspot/size[3]", me.light4_size);
setprop("/sim/rendering/als-secondary-lights/lightspot/size[4]", me.light5_size);
setprop("/sim/rendering/als-secondary-lights/lightspot/stretch", me.light1_stretch);
setprop("/sim/rendering/als-secondary-lights/lightspot/stretch[1]", me.light2_stretch);
me.run = 1;
me.run = 1;
me.update();
},
@ -183,16 +183,16 @@ var light_manager = {
if (me.run == 0) {
return;
}
cur_alt = alt_agl.getValue();
if (als_on.getValue() == 1 and alt_agl.getValue() < 100.0) {
highBeam = getprop("controls/lighting/highBeam");
headlight = getprop("controls/lighting/headlight-als");
ll3 = getprop("sim/model/lights/nose-lights");
nav = getprop("/sim/model/lights/nav-lights");
var apos = geo.aircraft_position();
var vpos = geo.viewer_position();
@ -206,7 +206,7 @@ var light_manager = {
var sh = math.sin(heading);
var ch = math.cos(heading);
if (highBeam == 1) {
me.light1_ypos = 0.0;
me.light1_setSize(6);
@ -214,7 +214,7 @@ var light_manager = {
} else {
me.light1_off();
}
if (headlight == 1) {
me.light2_ypos = 0.0;
me.light2_xpos = 5.0;
@ -233,8 +233,8 @@ var light_manager = {
props.getNode("/controls/lighting/headlight", 1).setValue(0);
}
}
if (nav == 1) {
me.light3_on();
me.light4_on();
@ -244,85 +244,85 @@ var light_manager = {
me.light4_off();
me.light5_off();
}
# light 1 position
var proj_x = cur_alt;
var proj_z = cur_alt/10.0;
apos.set_lat(lat + ((me.light1_xpos + proj_x) * ch + me.light1_ypos * sh) / me.lat_to_m);
apos.set_lon(lon + ((me.light1_xpos + proj_x)* sh - me.light1_ypos * ch) / me.lon_to_m);
delta_x = (apos.lat() - vpos.lat()) * me.lat_to_m;
delta_y = -(apos.lon() - vpos.lon()) * me.lon_to_m;
var delta_z = apos.alt()- proj_z - vpos.alt();
me.nd_ref_light1_x.setValue(delta_x);
me.nd_ref_light1_y.setValue(delta_y);
me.nd_ref_light1_z.setValue(delta_z);
me.nd_ref_light1_dir.setValue(heading);
me.nd_ref_light1_dir.setValue(heading);
# light 2 position
apos.set_lat(lat + (me.light2_xpos * ch + me.light2_ypos * sh) / me.lat_to_m);
apos.set_lon(lon + (me.light2_xpos * sh - me.light2_ypos * ch) / me.lon_to_m);
delta_x = (apos.lat() - vpos.lat()) * me.lat_to_m;
delta_y = -(apos.lon() - vpos.lon()) * me.lon_to_m;
delta_z = apos.alt() - vpos.alt();
me.nd_ref_light2_x.setValue(delta_x);
me.nd_ref_light2_y.setValue(delta_y);
me.nd_ref_light2_z.setValue(delta_z);
me.nd_ref_light2_dir.setValue(heading);
# light 3 position
apos.set_lat(lat + (me.light3_xpos * ch + me.light3_ypos * sh) / me.lat_to_m);
apos.set_lon(lon + (me.light3_xpos * sh - me.light3_ypos * ch) / me.lon_to_m);
delta_x = (apos.lat() - vpos.lat()) * me.lat_to_m;
delta_y = -(apos.lon() - vpos.lon()) * me.lon_to_m;
delta_z = apos.alt() - vpos.alt();
me.nd_ref_light3_x.setValue(delta_x);
me.nd_ref_light3_y.setValue(delta_y);
me.nd_ref_light3_z.setValue(delta_z);
me.nd_ref_light3_dir.setValue(heading);
me.nd_ref_light3_dir.setValue(heading);
# light 4 position
apos.set_lat(lat + (me.light4_xpos * ch + me.light4_ypos * sh) / me.lat_to_m);
apos.set_lon(lon + (me.light4_xpos * sh - me.light4_ypos * ch) / me.lon_to_m);
delta_x = (apos.lat() - vpos.lat()) * me.lat_to_m;
delta_y = -(apos.lon() - vpos.lon()) * me.lon_to_m;
delta_z = apos.alt() - vpos.alt();
me.nd_ref_light4_x.setValue(delta_x);
me.nd_ref_light4_y.setValue(delta_y);
me.nd_ref_light4_z.setValue(delta_z);
me.nd_ref_light4_dir.setValue(heading);
# light 5 position
apos.set_lat(lat + (me.light5_xpos * ch + me.light5_ypos * sh) / me.lat_to_m);
apos.set_lon(lon + (me.light5_xpos * sh - me.light5_ypos * ch) / me.lon_to_m);
delta_x = (apos.lat() - vpos.lat()) * me.lat_to_m;
delta_y = -(apos.lon() - vpos.lon()) * me.lon_to_m;
delta_z = apos.alt() - vpos.alt();
me.nd_ref_light5_x.setValue(delta_x);
me.nd_ref_light5_y.setValue(delta_y);
me.nd_ref_light5_z.setValue(delta_z);
me.nd_ref_light5_dir.setValue(heading);
}
settimer ( func me.update(), 0.00);
},
@ -333,7 +333,7 @@ var light_manager = {
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-b", me.light1_b);
me.light1_is_on = 1;
},
light1_off : func {
if (me.light1_is_on == 0) {return;}
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-r", 0.0);
@ -341,11 +341,11 @@ var light_manager = {
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-b", 0.0);
me.light1_is_on = 0;
},
light1_setSize : func(size) {
setprop("/sim/rendering/als-secondary-lights/lightspot/size[0]", size);
},
light2_on : func {
if (me.light2_is_on == 1) {return;}
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-r[1]", me.light2_r);
@ -353,7 +353,7 @@ var light_manager = {
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-b[1]", me.light2_b);
me.light2_is_on = 1;
},
light2_off : func {
if (me.light2_is_on == 0) {return;}
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-r[1]", 0.0);
@ -361,11 +361,11 @@ var light_manager = {
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-b[1]", 0.0);
me.light2_is_on = 0;
},
light2_setSize : func(size) {
setprop("/sim/rendering/als-secondary-lights/lightspot/size[1]", size);
},
light3_on : func {
if (me.light3_is_on == 1) {return;}
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-r[2]", me.light3_r);
@ -373,7 +373,7 @@ var light_manager = {
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-b[2]", me.light3_b);
me.light3_is_on = 1;
},
light3_off : func {
if (me.light3_is_on == 0) {return;}
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-r[2]", 0.0);
@ -389,7 +389,7 @@ var light_manager = {
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-b[3]", me.light4_b);
me.light4_is_on = 1;
},
light4_off : func {
if (me.light4_is_on == 0) {return;}
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-r[3]", 0.0);
@ -397,7 +397,7 @@ var light_manager = {
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-b[3]", 0.0);
me.light4_is_on = 0;
},
light5_on : func {
if (me.light5_is_on == 1) {return;}
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-r[4]", me.light5_r);
@ -405,7 +405,7 @@ var light_manager = {
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-b[4]", me.light5_b);
me.light5_is_on = 1;
},
light5_off : func {
if (me.light5_is_on == 0) {return;}
setprop("/sim/rendering/als-secondary-lights/lightspot/lightspot-r[4]", 0.0);
@ -416,6 +416,3 @@ var light_manager = {
};
light_manager.init();

View File

@ -1,5 +1,5 @@
#Custom plate selection system by Sidi Liang for follow me EV
#Contact: sidi.liang@gmail.com
#//Custom plate selection system by Sidi Liang for follow me EV
#//Contact: sidi.liang@gmail.com
#
#Instructions: This code scans the Models/plate/texture folder
#whenever the vehicle config dialog (config-dialog.xml) is opened.
@ -24,7 +24,7 @@ var scan = func(){
}
var updateList = func(){
var allPlates = scan();
var data = props.globals.getNode("/sim/gui/dialogs/vehicle_config/dialog/group[3]/combo/", 1);
var data = props.globals.getNode("/sim/gui/dialogs/vehicle_config/dialog/group[4]/combo/", 1);
data.removeChildren("value");
data.getChild("value", 0, 1).setValue("NONE");
forindex(var i; allPlates){

View File

@ -1,13 +1,25 @@
#Parking radar by Sidi Liang
#//Parking radar by Sidi Liang
#//Contact: sidi.liang@gmail.com
var Radar = {
#//Class for any Parking Radar (currently only support terrain detection) which scans in a sector
#//height: height of installation above ground;installCoordX: X coord of installation; installCoordY: Y coord of installation; maxRange: max radar range; maxWidth: width of the sector
#//orientationMode 0:towards back, 180:towards front, 90: towards left, 270:towards right, custom values are accepted(in degrees)
#//Node that 0 degrees is the backward(180 degrees heading of the vehicle), which is a little weird because I forget about it when designing the system
#//and the support of other install orientations are added afterwards
#//For a typical parking radar, set orientationMode=0(or leave it as default)
#//warnEnabled: set it to 1 (or leave it as default) enables the internal warning system(typecally used for a parking radar)
#//Notice: when warnEnabled set to 1, there's nothing being outputed to radarOutput!
#//For follow me EV: height 0.3m; installCoordX:0m; installCoordY:3.8m; maxRange:3m;maxWidth:3m
#//To start scanning: myRadar.init();
#//To Stop: myRadar.stop();
new: func(height, installCoordX, installCoordY, maxRange, maxWidth) {
return { parents:[Radar, followme.Appliance.new()], height: height, installCoordX:installCoordX, installCoordY:installCoordY, maxRange:maxRange, maxWidth:maxWidth};
new: func(height, installCoordX, installCoordY, maxRange, maxWidth, orientationMode=0, warnEnabled=1, debug=0) {
return { parents:[Radar, Appliance.new()], height: height, installCoordX:installCoordX, installCoordY:installCoordY, maxRange:maxRange, maxWidth:maxWidth, orientationMode:orientationMode, warnEnabled:warnEnabled, debug:debug, radarOutput:10000};
},
debug: 0,#if debug = 1, shows marker and prints info
warnEnabled: 1,#1 enables the internal warning system(typecally used for a parking radar) as 0 disables it
height: 0.3, #METERS
installCoordX: 0, #METERS
installCoordY: 3.8, #METERS
@ -17,6 +29,7 @@ var Radar = {
updateInterval:0.25,#SEC
searchAngle: 0, #RAD, half of the search angle
tanSearchAngle: 0,
orientationMode:0, #Deg
vehiclePosition: nil,
coord: nil,
@ -33,6 +46,8 @@ var Radar = {
warningSound: "parking_radar.wav",
lastDis: 0,
radarOutput: 10000,#The value which radar returns in meters
init: func(){
me.searchAngle = math.acos(me.maxRange / math.sqrt((2/me.maxWidth)*(2/me.maxWidth) + me.maxRange*me.maxRange));
me.tanSearchAngle = math.tan(me.searchAngle);
@ -42,14 +57,23 @@ var Radar = {
me.widthLatRange = me.calculateLatChange(me.maxWidth);
me.widthLonRange = me.calculateLonChange(me.maxWidth, me.coord);
if(me.radarTimer == nil) me.radarTimer = maketimer(me.updateInterval, func me.update());
if(me.warningTimer == nil) me.warningTimer = maketimer(me.warningInterval, func me.warn());
if(me.warnEnabled and me.warningTimer == nil) me.warningTimer = maketimer(me.warningInterval, func me.warn());
me.radarTimer.start();
print("Parking radar initialized!");
playAudio("parking_radar_init.wav");
if(me.warnEnabled){
print("Parking radar initialized!");
playAudio("parking_radar_init.wav");
}else{
#print("Radar initialized!");
}
},
stop: func(){
print("Parking radar stopped!");
me.warningTimer.stop();
if(me.warnEnabled){
print("Parking radar stopped!");
playAudio("parking_radar_init.wav");
}else{
#print("Radar Stopped!");
}
if(me.warnEnabled) me.warningTimer.stop();
me.radarTimer.stop();
},
toggle: func(){
@ -61,7 +85,7 @@ var Radar = {
},
getCoord: func(){
me.vehicleHeading = props.getNode("/orientation/heading-deg",1).getValue();
me.vehicleHeading = geo.normdeg(props.getNode("/orientation/heading-deg",1).getValue() + me.orientationMode);
me.vehiclePosition = geo.aircraft_position();
me.coord = geo.Coord.new(me.vehiclePosition);
me.coord.apply_course_distance(geo.normdeg(me.vehicleHeading-90), me.installCoordX);
@ -113,14 +137,14 @@ var Radar = {
if(meters <= 0.5){
me.warningInterval = 0.2;
me.warningSound = "parking_radar_long.wav";
#print("Caution! Something behind at less than 0.5 meters!");
if(me.debug) print("Caution! Something detected at less than 0.5 meters!");
return;
}else{
me.warningSound = "parking_radar.wav";
}
meters = sprintf("%.3f", meters);
if(meters != me.lastDis) me.warningInterval = (meters)/me.maxRange;
#print("Caution! Something behind at approximatly "~meters~" meters");
if(me.debug) print("Caution! Something detected at approximatly "~meters~" meters");
me.lastDis = meters;
},
sample: func(stepLat, stepLon, searchLat, searchLon){ # returns an elevtion
@ -128,7 +152,7 @@ var Radar = {
var lonChange = -math.cos(me.vehicleHeading * D2R);
var sampleCoord = geo.Coord.new();
sampleCoord.set_latlon(me.position_change(searchLat,stepLat*latChange), me.position_change(searchLon,stepLon*lonChange));
#var model = geo.put_model(getprop("sim/aircraft-dir")~"/Nasal/waypoint.ac", sampleCoord.lat(), sampleCoord.lon(), me.coord.alt());
if(me.debug) var model = geo.put_model(getprop("sim/aircraft-dir")~"/Nasal/waypoint.ac", sampleCoord.lat(), sampleCoord.lon(), me.coord.alt());
return sampleCoord;
},
update: func(){
@ -150,8 +174,9 @@ var Radar = {
targetElev = me.getElevByCoord(targetCoord);
if(me.judgeElev(targetElev)){
var meters = me.coord.distance_to(targetCoord);
#var model = geo.put_model(getprop("sim/aircraft-dir")~"/Nasal/waypoint.ac", targetCoord.lat(), targetCoord.lon(), me.coord.alt());
me.warnControl(meters);
if(me.debug) var model = geo.put_model(getprop("sim/aircraft-dir")~"/Nasal/waypoint.ac", targetCoord.lat(), targetCoord.lon(), me.coord.alt());
if(me.warnEnabled) me.warnControl(meters);
else me.radarOutput = meters;
return;
}
}
@ -162,16 +187,18 @@ var Radar = {
targetElev = me.getElevByCoord(targetCoord);
if(me.judgeElev(targetElev)){
var meters = me.coord.distance_to(targetCoord);
#var model = geo.put_model(getprop("sim/aircraft-dir")~"/Nasal/waypoint.ac", targetCoord.lat(), targetCoord.lon(), me.coord.alt());
me.warnControl(meters);
if(me.debug) var model = geo.put_model(getprop("sim/aircraft-dir")~"/Nasal/waypoint.ac", targetCoord.lat(), targetCoord.lon(), me.coord.alt());
if(me.warnEnabled) me.warnControl(meters);
else me.radarOutput = meters;
return;
}
}
searchStep += 0.1;
searchDis += searchStep;
}
#print("All clear");
me.warnControl(10000);
if(me.debug) print("All clear");
if(me.warnEnabled) me.warnControl(10000);
else me.radarOutput = 10000;
},
};

View File

@ -1,4 +1,6 @@
#//Followme EV steering system by Sidi Liang
#//Followme EV steering system by Sidi Liang
#//Contact: sidi.liang@gmail.com
var cache = {
new: func return { parents:[cache] };
};
@ -21,49 +23,51 @@ memoize.lookup = func(value) {
}
var Steering = {
new: func() {
print("Steering system initialized!");
return {parents:[Steering]};
var steering = { parents:[Steering] };
props.getNode("/controls/steering_wheel/steering_limit-deg", 1).setValue(steering.steeringLimit * R2D);
return steering;
},
mode: 0, #//0: direct; 1: advanced
debugMode: 0,
input: 0, #//-1: left, 1:right, 0: none
command: 0, #//Steering command, range from -1 to 1
steeringAngle: 0, #//in rad
steeringAngleDeg: 0, #//in degrees
#steeringAngleDeg: 0, #//in degrees
steeringLimit: 15.707963, #// 5 * 3.1415926
powPointThree: memoize.new( func(value){
return math.pow(value, 0.3);
}),
powPointOne: memoize.new( func(value){
return math.pow(value, 0.1);
}),
steeringStep:func(rad){
return 0.1 * me.powPointOne.lookup(sprintf("%.1f", math.abs(rad))) + 0.04;
},
neutralStep: func(rad){
var speed = props.getNode("/", 1).getValue("sim/multiplay/generic/float[15]");
return 0.01 * me.powPointThree.lookup(sprintf("%.1f", math.abs(speed))) * math.abs(rad);
return 0.03 * me.powPointThree.lookup(sprintf("%.1f", math.abs(speed))) * math.abs(rad);
},
mainLoop: func(){
if(me.input == 0)
{
if(math.abs(me.steeringAngle) <=0.2)
{
me.steeringAngle = 0;
me.steeringAngleDeg = me.steeringAngle * R2D;
props.getNode("/",1).setValue("/controls/flight/rudder", me.command);
props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
#me.steeringAngleDeg = me.steeringAngle * R2D;
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
}
if(me.steeringAngle == 0)
{
@ -95,11 +99,11 @@ var Steering = {
else
me.steeringAngle -= me.steeringStep(me.steeringAngle);
}
me.command = me.steeringAngle / me.steeringLimit; #//The steering wheel could rotate for two circles and a half
me.steeringAngleDeg = me.steeringAngle * R2D;
#me.steeringAngleDeg = me.steeringAngle * R2D;
props.getNode("/",1).setValue("/controls/flight/rudder", me.command);
props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
if(me.debugMode)
{
print("Steering system command:" ~ me.command);
@ -107,14 +111,14 @@ var Steering = {
print("Steering system angle degrees:" ~ me.steeringAngleDeg);
}
},
inputLeft: func(){
me.input = -1;
if(!me.mode){
me.command = -0.5;
me.steeringAngleDeg = me.steeringLimit * me.command * R2D;
me.command = -0.5;
props.getNode("/",1).setValue("/controls/flight/rudder", me.command);
props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
#me.steeringAngleDeg = me.steeringLimit * me.command * R2D;
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
}else if(me.mode and !me.timerStarted){
me.startTimer();
}
@ -123,9 +127,9 @@ var Steering = {
me.input = 1;
if(!me.mode){
me.command = 0.5;
me.steeringAngleDeg = me.steeringLimit * me.command * R2D;
props.getNode("/",1).setValue("/controls/flight/rudder", me.command);
props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
#me.steeringAngleDeg = me.steeringLimit * me.command * R2D;
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
}else if(me.mode and !me.timerStarted){
me.startTimer();
}
@ -134,14 +138,14 @@ var Steering = {
me.input = 0;
if(!me.mode){
me.command = 0;
me.steeringAngleDeg = me.steeringLimit * me.command * R2D;
props.getNode("/",1).setValue("/controls/flight/rudder", me.command);
props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
#me.steeringAngleDeg = me.steeringLimit * me.command * R2D;
#props.getNode("/",1).setValue("/controls/steering_wheel", me.steeringAngleDeg);
}else if(me.mode and !me.timerStarted){
me.startTimer();
}
},
steeringTimer: nil,
timerCreated: 0,
timerStarted: 0,
@ -172,4 +176,4 @@ addcommand("enableAdvancedSteering", func() {
addcommand("disableAdvancedSteering", func() {
steeringAssistance.mode = 0;
print("Advanced Steering Disabled");
});
});

View File

@ -2,6 +2,8 @@
#### Gijs de Rooy (Original) ####
#### Sidi Liang ####
io.include("library.nas");
props.getNode("/sim/gui/dialogs/vehicle_config/dialog",1);
var configDialog = gui.Dialog.new("/sim/gui/dialogs/vehicle_config/dialog", "Aircraft/followme_e-tron/gui/dialogs/config-dialog.xml");
@ -35,44 +37,6 @@ var tyreSmoke_2 = aircraft.tyresmoke.new(2, auto = 1, diff_norm = 0.4, check_vsp
var tyreSmoke_3 = aircraft.tyresmoke.new(3, auto = 1, diff_norm = 0.4, check_vspeed = 0);
props.getNode("/",1).setValue("/systems/horn", 0);
props.getNode("/",1).setValue("/controls/mode", 1);
props.getNode("/",1).setValue("/controls/direction", 1);
props.getNode("/",1).setValue("/systems/instruments/enable_switches", 0);
props.getNode("/",1).setValue("/systems/instruments/enable_cdu", 0);
props.getNode("/",1).setValue("/instrumentation/cdu/ident/model", "Follow me EV");
props.getNode("/",1).setValue("/instrumentation/cdu/ident/engines", "EV Motor");
var isInternalView = func(){ #// return 1 if is in internal view, otherwise return 0.
return props.getNode("sim/current-view/internal", 1).getValue();
}
var Sound = {
new: func(filename, volume = 1, path=nil) {
var m = props.Node.new({
path : path,
file : filename,
volume : volume,
});
return m;
},
};
var window = screen.window.new(10, 10, 3, 10);
var outputUI = func(content, timeout = 10){
window.autoscroll = timeout;
timeNow = systime();
if(content != getprop("/systems/outputUIContent") or (timeNow - timeout) >= getprop("/systems/lastOutputUITime")){
window.write(content);
setprop("/systems/outputUIContent",content);
setprop("/systems/lastOutputUITime",systime());
#print("Outputed");
}
}
var playAudio = func(file){ #//Plays audio files in Aircrafts/Sounds
fgcommand("play-audio-sample", Sound.new(filename: file, volume: 1, path: props.getNode("/",1).getValue("sim/aircraft-dir") ~ '/Sounds'));
}
var frontleft_door = aircraft.door.new("/controls/doors/frontleft", 1);
var frontright_door = aircraft.door.new("/controls/doors/frontright", 1);
var rearleft_door = aircraft.door.new("/controls/doors/rearleft", 1);
@ -92,15 +56,23 @@ aircraft.door.toggle = func(){
beacon_switch = props.globals.getNode("controls/switches/warninglight", 2);
var beacon = aircraft.light.new( "/sim/model/lights/warning", [0.5, 0.5], "/controls/lighting/warning" );
beacon_switch = props.globals.getNode("controls/switches/indicator-left", 2);
var beacon = aircraft.light.new( "/sim/model/lights/indicator-left", [0.8, 0.5], "/controls/lighting/indicator-left");
var beacon = aircraft.light.new( "/sim/model/lights/indicator-left", [0.5, 0.5], "/controls/lighting/indicator-left");
beacon_switch = props.globals.getNode("controls/switches/indicator-right", 2);
var beacon = aircraft.light.new( "/sim/model/lights/indicator-right", [0.8, 0.5], "/controls/lighting/indicator-right");
var beacon = aircraft.light.new( "/sim/model/lights/indicator-right", [0.5, 0.5], "/controls/lighting/indicator-right");
props.getNode("/",1).setValue("/controls/lighting/indicator-left", 0);
props.getNode("/",1).setValue("/controls/lighting/indicator-right", 0);
props.getNode("/",1).setValue("/systems/horn", 0);
props.getNode("/",1).setValue("/controls/mode", 1);
props.getNode("/",1).setValue("/controls/direction", 1);
props.getNode("/",1).setValue("/systems/instruments/enable_switches", 0);
props.getNode("/",1).setValue("/systems/instruments/enable_cdu", 0);
props.getNode("/",1).setValue("/instrumentation/cdu/ident/model", "Follow me EV");
props.getNode("/",1).setValue("/instrumentation/cdu/ident/engines", "EV Motor");
props.getNode("/",1).setValue("services/service-truck/enable", 0);
props.getNode("/controls/is-recharging", 1).setValue(0);
props.getNode("controls/is-recharging", 1).setValue(0);
props.getNode("systems/welcome-message", 1).setValue(0);
props.getNode("systems/display-speed", 1).setValue(0);
props.getNode("systems/speedometer/type", 1).setValue("Type_A");
@ -108,12 +80,18 @@ props.getNode("systems/battery-gauge/type", 1).setValue("Type_A");
props.getNode("systems/plate/file", 1).setValue("NONE");
props.getNode("systems/plate/name", 1).setValue("NONE");
props.getNode("controls/lighting/headlight-als", 1).setValue(0);
props.getNode("controls/lighting/highBeam", 1).setValue(0);
props.getNode("/controls/steering_wheel", 1).setValue(0);
props.getNode("controls/interior/luxury/storage_cover_pos", 1).setValue(0);
props.getNode("sim/remote/pilot-callsign", 1).setValue("");
props.getNode("/systems/codriver-enable", 1).setValue(0);
props.getNode("systems/codriver-enable", 1).setValue(0);
props.getNode("systems/screen-enable", 1).setValue(0);
props.getNode("systems/pmodel-enable", 1).setValue(1);
props.getNode("systems/decorations-enable", 1).setValue(0);
props.getNode("systems/interior/type", 1).setValue("Default");
props.getNode("systems/safety/aeb_activated", 1).setValue(0);
props.getNode("systems/auto_hold_enabled", 1).setValue(0);
props.getNode("systems/auto_hold_working", 1).setValue(0);
#var Led = {
#
@ -130,7 +108,6 @@ props.getNode("systems/interior/type", 1).setValue("Default");
#
#};
var Indicator = {
# Usage: #
@ -212,9 +189,6 @@ var IndicatorController = {
name: "Left",
},
saveLedMessage: func(){
me.savedMessage.texture = me.ledMessage.getValue();
me.savedMessage.file = me.ledMessageFile.getValue();
@ -316,6 +290,7 @@ var IndicatorController = {
},
falseLightOn : func(){
if(isInternalView()) playAudio("electric_handbrake.wav");
me.falseLight = 1;
if(me.mode == 1 or me.mode == 2 or me.mode == 4 or me.mode == 5){
print("falseLight mode on");
@ -326,6 +301,7 @@ var IndicatorController = {
},
falseLightOff : func(){
if(isInternalView()) playAudio("electric_handbrake.wav");
me.falseLight = 0;
if(me.mode == 1 or me.mode == 2 or me.mode == 4 or me.mode == 5){
print("falseLight mode off");
@ -335,7 +311,6 @@ var IndicatorController = {
}
},
false_light_toggle : func(){
if(isInternalView()) playAudio('IndicatorEnd.wav');
if(me.falseLight == 0){
me.falseLightOn();
}else if(me.falseLight == 1){
@ -346,38 +321,98 @@ var IndicatorController = {
var indicatorController = IndicatorController.new();
var toggleHandBrake = func(){
if(isInternalView()) playAudio("electric_handbrake.wav");
var handBrake = props.getNode("/controls/gear/brake-parking", 1);
if(!handBrake.getValue()){
handBrake.setValue(1);
}else{
handBrake.setValue(0);
var BrakeController = {
new: func() { return { parents:[BrakeController]}; },
leftBrakeNode: props.getNode("/controls/gear/brake-left",1),
rightBrakeNode: props.getNode("/controls/gear/brake-right",1),
parkingBrakeNode: props.getNode("/controls/gear/brake-parking",1),
applyingFeetBrake: 0,
handBrakeIsOn: 0,
leftBrakeValue: 0,
rightBrakeValue: 0,
applyLeftBrake: func(value){
#For internal use
me.leftBrakeNode.setValue(value);
me.leftBrakeValue = value;
},
applyRightBrake: func(value){
#For internal use
me.rightBrakeNode.setValue(value);
me.rightBrakeValue = value;
},
applyBrakes: func(value){
#For internal use
me.rightBrakeNode.setValue(value);
me.rightBrakeValue = value;
me.leftBrakeNode.setValue(value);
me.leftBrakeValue = value;
},
applyFeetBrakes: func(value){
#For feet brakes
if(value) applyingFeetBrake = 1;
else applyingFeetBrake = 0;
me.rightBrakeNode.setValue(value);
me.rightBrakeValue = value;
me.leftBrakeNode.setValue(value);
me.leftBrakeValue = value;
},
enableHandBrake: func(){
settimer(func(){ #Delay for 0.8 seconds
me.parkingBrakeNode.setValue(1);
me.handBrakeIsOn = 1;
}, 0.8);
},
disableHandBrake: func(){
settimer(func(){ #Delay for 0.8 seconds
me.parkingBrakeNode.setValue(0);
me.handBrakeIsOn = 0;
}, 0.8);
},
toggleHandBrake: func(){
#Toggle handbrake from button
if(isInternalView()) playAudio("electric_handbrake.wav");
if(!me.handBrakeIsOn){
me.enableHandBrake();
}else{
me.disableHandBrake();
}
},
activeEmergencyBrake: func(){
me.applyLeftBrake(1);
me.applyRightBrake(1);
me.enableHandBrake();
safety.emergencyMode();
},
keyboardBrake: func(){
me.applyFeetBrakes(0.8);
},
keyboardBrakeRelease: func(){
me.applyFeetBrakes(0);
},
releaseBrake: func(){
me.applyLeftBrake(0);
me.applyRightBrake(0);
}
}
releaseAllBrakes: func(){
me.applyLeftBrake(0);
me.applyRightBrake(0);
me.disableHandBrake();
},
};
var brakeController = BrakeController.new();
var runCode = func(url, addition = nil){
#var params = {url:"http://fgprc.org:11415/", targetnode:"/systems/code", complete: completed};
http.save(url~addition, getprop('/sim/fg-home') ~ '/cache/code.xml').done(func(r){
var blob = io.read_properties(getprop('/sim/fg-home') ~ '/cache/code.xml');
var filename = "/cache/code.xml";
var script = blob.getValues().code; # Get the nasal string
var code = call(func {
compile(script, filename);
}, nil, nil, var compilation_errors = []);
if(size(compilation_errors)){
die("Error compiling code in: " ~ filename);
}
call(code, [], nil, nil, var runtime_errors = []);
if(size(runtime_errors)){
die("Error calling code compiled loaded from: " ~ filename);
}
var path = os.path.new(getprop('/sim/fg-home') ~ '/cache/code.xml');
path.remove();
print("Code loaded");
});
var toggleHandBrake = func(){
#//Depreciated as BrakeController has it internally now
if(isInternalView()) playAudio("electric_handbrake.wav");
if(!brakeController.handBrakeIsOn){
brakeController.enableHandBrake();
}else{
brakeController.disableHandBrake();
}
}
var chargeBatterySec = func(){
@ -428,8 +463,6 @@ var chargeBatteryStop = func(bef){
props.getNode("/controls/is-recharging", 1).setValue(0);
}
var calculateSpeed = func(){
var gs = props.getNode("velocities/groundspeed-kt", 1).getValue();
var speedKmh = 1.852 * gs;
@ -453,7 +486,6 @@ var calculateSpeed = func(){
}
var calculateSpeedTimer = maketimer(0.1, calculateSpeed);
var resetOnPosition = func(){
var latProp = props.getNode("/position/latitude-deg");
var lonProp = props.getNode("/position/longitude-deg");
@ -468,63 +500,13 @@ var resetOnPosition = func(){
setprop("/fdm/jsbsim/simulation/pause", 0);
}
var Safety = {
new: func(airbagAccelerationLimit=72){
return {parents: [Safety], airbagAccelerationLimit:airbagAccelerationLimit};
},
isOn: 0,
safetySystemTimer: nil,
updateInterval: 0.01,
accXProp: props.getNode("/fdm/jsbsim/accelerations/a-pilot-x-ft_sec2", 1),
accYProp: props.getNode("/fdm/jsbsim/accelerations/a-pilot-y-ft_sec2", 1),
frontAirbagProp: props.getNode("/systems/safety/airbag/front", 1),
sideAirbagProp: props.getNode("/systems/safety/airbag/side", 1),
airbagAccelerationLimit: 72, #To be configured,m/s^2
update: func(){
#print("running");
#Front airbag
if(math.abs(me.accXProp.getValue() * FT2M) > me.airbagAccelerationLimit){
#active Front
me.frontAirbagProp.setValue(1);
me.safetySystemTimer.stop();
}
#side airbag
if(math.abs(me.accYProp.getValue() * FT2M) > me.airbagAccelerationLimit){
#active side
me.sideAirbagProp.setValue(1);
me.safetySystemTimer.stop();
}
},
reset: func(){
me.frontAirbagProp.setValue(0);
me.frontAirbagProp.setValue(0);
},
init: func(){
me.frontAirbagProp.setValue(0);
me.sideAirbagProp.setValue(0);
if(me.safetySystemTimer == nil) me.safetySystemTimer = maketimer(me.updateInterval, func me.update());
me.safetySystemTimer.start();
me.isOn = 1;
print("Safety system initialized");
},
stop: func(){
me.isOn = 0;
me.safetySystemTimer.stop();
print("Safety system stoped");
},
toggle: func(){
if(!me.isOn) me.init();
else me.stop();
},
};
var safety = Safety.new();
safety.init();
var brakesABS = func(){
var gearFrtLftSpeed = math.round(props.getNode("/",1).getValue("/fdm/jsbsim/gear/unit/wheel-speed-fps"));
var gearFrtRgtSpeed = math.round(props.getNode("/",1).getValue("/fdm/jsbsim/gear/unit[1]/wheel-speed-fps"));
var gearBckLftSpeed = math.round(props.getNode("/",1).getValue("/fdm/jsbsim/gear/unit[2]/wheel-speed-fps"));
var gearBckRgtSpeed = math.round(props.getNode("/",1).getValue("/fdm/jsbsim/gear/unit[3]/wheel-speed-fps"));
if(gearFrtLftSpeed == 0 or gearBckLftSpeed == 0 or gearFrtRgtSpeed == 0 or gearBckRgtSpeed == 0){
safety.emergencyMode();
props.getNode("/",1).setValue("/controls/gear/brake-left", 0);
props.getNode("/",1).setValue("/controls/gear/brake-right", 0);
}else{
@ -533,10 +515,159 @@ var brakesABS = func(){
}
}
var absTimer = maketimer(0.001, brakesABS);
var Safety = {
new: func(airbagAccelerationLimit=140, sideAirbagAccelerationLimit=72){
var newSafety = { parents:[Safety] };
newSafety.airbagAccelerationLimit = airbagAccelerationLimit;
newSafety.sideAirbagAccelerationLimit = sideAirbagAccelerationLimit;
newSafety.frontRadar = Radar.new(0.3, 0, 0, 9, 0.1, 180, 0, 0);#For AEB
newSafety.absTimer = maketimer(0.001, brakesABS);
return newSafety;
},
isOn: 0,
safetySystemTimer: nil,
updateInterval: 0.01,
frontRadarEnabled: 0,
aebActivated: 0,
lastRadarOutput:10000,
throttleNode: props.getNode("/controls/engines/engine/throttle",1),
#Airbag
accXProp: props.getNode("/fdm/jsbsim/accelerations/a-pilot-x-ft_sec2", 1),
accYProp: props.getNode("/fdm/jsbsim/accelerations/a-pilot-y-ft_sec2", 1),
frontAirbagProp: props.getNode("/systems/safety/airbag/front", 1),
sideAirbagProp: props.getNode("/systems/safety/airbag/side", 1),
aebStateProp: props.getNode("/systems/safety/aeb_activated", 1),
airbagAccelerationLimit: 140, #To be configured,m/s^2
sideAirbagAccelerationLimit: 72, #To be configured,m/s^2
#Frontwards radar
frontRadar: nil,
enableFrontRadar: func(){
#Enables the front radar
me.frontRadarEnabled = 1;
me.frontRadar.init();
me.frontRadar.stop();
print("Front radar enabled");
},
disableFrontRadar: func(){
#Disables the front radar
me.frontRadar.stop();
me.frontRadarEnabled = 0;
},
toggleFrontRadar: func(){
if(!me.frontRadarEnabled){
me.enableFrontRadar();
playAudio("parking_radar_init.wav");
}
else me.disableFrontRadar();
},
aebActive: func(){
me.aebActivated = 1;
#engine.engine_1.engineSwitch.switchDisconnect();
me.throttleNode.setValue(0);
brakeController.activeEmergencyBrake();
playAudio("parking_radar_init.wav");
me.aebStateProp.setValue(1);
print("AEB Activated!");
},
aebStop: func(){
me.aebActivated = 0;
print("AEB Stopped");
me.aebStateProp.setValue(0);
#engine.engine_1.engineSwitch.switchConnect();
brakeController.releaseAllBrakes();
},
update: func(){
#print("running");
#Front airbag
if(math.abs(me.accXProp.getValue() * FT2M) > me.airbagAccelerationLimit){
#active Front
me.frontAirbagProp.setValue(1);
me.emergencyMode();
}
#side airbag
if(math.abs(me.accYProp.getValue() * FT2M) > me.sideAirbagAccelerationLimit){
#active side
me.sideAirbagProp.setValue(1);
me.emergencyMode();
}
var currentSpeed = props.getNode("/", 1).getValue("sim/multiplay/generic/float[15]")*1.852;#In km/h
#AEB, Automatic Emergency Brake
var radarOutput = me.frontRadar.radarOutput;
var deltaX = me.lastRadarOutput - radarOutput;
var reletiveSpeed = 3.6 * (deltaX / me.updateInterval);#In km/h
if(currentSpeed > 30 and engine.engine_1.getDirection() == 1){
#Enable AEB when speed is greater then 30kmh
if(me.frontRadarEnabled){
me.frontRadar.init();
if(me.frontRadar.radarOutput <= 8 and reletiveSpeed > 30 and !me.aebActivated){
me.aebActive();
}else if((me.frontRadar.radarOutput >= 8 or reletiveSpeed <= 0) and me.aebActivated){
me.aebStop();
}
}
}else{
if(me.frontRadarEnabled and me.frontRadar.radarTimer.isRunning) me.frontRadar.stop();
if(reletiveSpeed <= 0 and me.aebActivated) me.aebStop();
}
#ABS
#var brakeCmd = props.getNode("/",1).getValue("/controls/gear/brake-left");
#if(brakeCmd and currentSpeed){
# me.absTimer.start();
#}else{
# me.absTimer.stop();
#}
},
emergencyMode: func(){
indicatorController.setMode(3); #Active malfunction light
indicatorController.falseLight = 1;
if(autospeed.autoSpeedTimer.isRunning) autospeed.stopAutoSpeed();
if(autopilot.road_check_timer.isRunning) autopilot.road_check_timer.stop();
},
reset: func(){
#resetting stops the safety system
me.safetySystemTimer.stop();
me.disableFrontRadar();
me.frontAirbagProp.setValue(0);
me.sideAirbagProp.setValue(0);
me.aebStateProp.setValue(0);
},
init: func(){
#initialize or reinitialize
me.frontAirbagProp.setValue(0);
me.sideAirbagProp.setValue(0);
me.aebStateProp.setValue(0);
if(me.safetySystemTimer == nil) me.safetySystemTimer = maketimer(me.updateInterval, func me.update());
me.safetySystemTimer.start();
if(me.frontRadarEnabled) me.enableFrontRadar();
me.isOn = 1;
print("Safety system initialized");
},
stop: func(){
me.isOn = 0;
me.aebStateProp.setValue(0);
me.disableFrontRadar();
me.safetySystemTimer.stop();
print("Safety system stoped");
},
toggle: func(){
if(!me.isOn) me.init();
else me.stop();
},
};
var safety = Safety.new(140, 72);
var brakeWithABS = func(){ #//Doesn't seems to work because it seems that jsbsim wheels never overbrake?
var brakeCmd = props.getNode("/",1).getValue("/controls/gear/brake-cmd");
#//abondoned since the new safety system
var brakeCmd = props.getNode("/",1).getValue("/controls/gear/brake-left");
if(brakeCmd){
absTimer.start();
}else{
@ -544,4 +675,28 @@ var brakeWithABS = func(){ #//Doesn't seems to work because it seems that jsbsim
}
}
#setlistener("/controls/gear/brake-cmd", brakeWithABS);
var testingProgram_1_Entry = func(){
autospeed.startAutoSpeed();
autospeed.targetSpeedChange(100);
settimer(testingProgram_1, 10);
}
var testingProgram_1 = func(){
props.getNode("/",1).setValue("/controls/gear/brake-left", 1);
props.getNode("/",1).setValue("/controls/gear/brake-right", 1);
props.getNode("/",1).setValue("/controls/gear/brake-parking", 1);
}
var testingProgram_2_Entry = func(){
autospeed.startAutoSpeed();
autospeed.targetSpeedChange(100);
settimer(testingProgram_2, 10);
}
var testingProgram_2 = func(){
props.getNode("/",1).setValue("/controls/gear/brake-left", 1);
props.getNode("/",1).setValue("/controls/gear/brake-right", 1);
#props.getNode("/",1).setValue("/controls/gear/brake-parking", 1);
}
#setlistener("/controls/gear/brake-left", brakeWithABS);

View File

@ -508,6 +508,10 @@
<generic>
<bool n="0" alias="/systems/decorations-enable"/>
<bool n="1" alias="/systems/pmodel-enable"/>
<bool n="2" alias="/systems/auto_hold_enabled"/>
<bool n="3" alias="/systems/auto_hold_working"/>
<bool n="4" alias="/systems/safety/aeb_activated"/>
<bool n="5" alias="/controls/lighting/highBeam"/>
<int n="0" alias="/sim/model/lights/indicator-left/state"/>
<int n="1" alias="/sim/model/lights/indicator-right/state"/>
@ -555,10 +559,13 @@
<float n="16" alias="/systems/electrical/e-tron/battery-kWh"/>
<float n="17" alias="/systems/electrical/e-tron/battery-remaining-percent-float"/>
<float n="18" alias="/controls/steering_wheel"/>
<float n="18" alias="/fdm/jsbsim/animation/steering_wheel_pos"/>
<float n="19" alias="/controls/gear/brake-parking"/>
<float n="22" alias="/controls/engines/engine/throttle"/>
<float n="23" alias="/fdm/jsbsim/animation/storage_cover_pos"/>
<float n="24" alias="/controls/interior/luxury/storage_cover_pos"/>
<!--<string n="0" alias="/systems/plate"/>-->
<string n="1" alias="/systems/battery-gauge/type"/>
@ -681,25 +688,13 @@
<desc>break</desc>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>/controls/gear/brake-left</property>
<value>1</value>
</binding>
<binding>
<command>property-assign</command>
<property>/controls/gear/brake-right</property>
<value>1</value>
<command>nasal</command>
<script>followme.brakeController.keyboardBrake();</script>
</binding>
<mod-up>
<binding>
<command>property-assign</command>
<property>/controls/gear/brake-left</property>
<value>0</value>
</binding>
<binding>
<command>property-assign</command>
<property>/controls/gear/brake-right</property>
<value>0</value>
<command>nasal</command>
<script>followme.brakeController.keyboardBrakeRelease();</script>
</binding>
</mod-up>
</key>
@ -829,7 +824,7 @@
<desc>handbrake</desc>
<binding>
<command>nasal</command>
<script>followme.toggleHandBrake();</script>
<script>followme.brakeController.toggleHandBrake();</script>
</binding>
</key>
</keyboard>
@ -838,11 +833,11 @@
<nasal>
<followme>
<file>Aircraft/followme_e-tron/Nasal/electrical.nas</file>
<file>Aircraft/followme_e-tron/Nasal/radar.nas</file>
<file>Aircraft/followme_e-tron/Nasal/systems.nas</file>
<file>Aircraft/followme_e-tron/Nasal/plate.nas</file>
<file>Aircraft/followme_e-tron/Nasal/steering.nas</file>
<file>Aircraft/followme_e-tron/Nasal/radar.nas</file>
<file>Aircraft/followme_e-tron/Nasal/save.nas</file>
<file>Aircraft/followme_e-tron/Nasal/save.nas</file>
</followme>
<!--<screen>
<file>Aircraft/followme_e-tron/Nasal/SmartScreen.nas</file>
@ -868,6 +863,9 @@
<autospeed>
<file>Aircraft/followme_e-tron/Nasal/auto_speed.nas</file>
</autospeed>
<autohold>
<file>Aircraft/followme_e-tron/Nasal/auto_hold.nas</file>
</autohold>
<cdu>
<file>Aircraft/followme_e-tron/Models/Interior/Instruments/CDU/boeing.nas</file>
<file>Aircraft/followme_e-tron/Models/Interior/Instruments/CDU/library.nas</file>

View File

@ -430,6 +430,10 @@
</clipto>
<output>fcs/rudder-pos-norm</output>
</summer>
<lag_filter name="fcs/rudder-pos-norm">
<input>fcs/rudder-cmd-norm</input>
<c1>30</c1>
</lag_filter>
</channel>
</flight_control>
@ -498,4 +502,41 @@
</direction>
</force>
</external_reactions>
<system name="Followme EV animations">
<channel name="Stroage" execrate="2">
<fcs_function name="animation/storage_nul">
<function>
<table>
<independentVar lookup="row">/controls/interior/luxury/storage_cover_pos</independentVar>
<tableData>
0.00 0.0
0.05 0.1
0.10 0.1
0.30 0.2
0.75 0.7
0.95 1.0
</tableData>
</table>
</function>
</fcs_function>
<lag_filter name="animation/storage_cover_pos">
<input>animation/storage_nul</input>
<c1>3</c1>
</lag_filter>
</channel>
<channel name="SteeringWheel">
<fcs_function name="animation/steering_wheel_pos">
<function>
<product>
<property>/controls/steering_wheel/steering_limit-deg</property>
<property>/controls/flight/rudder</property>
</product>
</function>
</fcs_function>
</channel>
</system>
</fdm_config>

View File

@ -63,6 +63,7 @@
<property>/systems/interior/type</property>
<value>Default</value>
<value>Sport</value>
<value>Luxury</value>
<binding>
<command>dialog-apply</command>
<object-name>interiorStyle</object-name>
@ -135,15 +136,39 @@
</button>
<button>
<halign>left</halign>
<legend>Toggle Airbag</legend>
<legend>(Re)Initialize Safety</legend>
<pref-width>120</pref-width>
<pref-height>28</pref-height>
<binding>
<command>nasal</command>
<script>followme.safety.toggle()</script>
<script>followme.safety.init()</script>
</binding>
</button>
<button>
<halign>left</halign>
<legend>Disable Safety</legend>
<pref-width>120</pref-width>
<pref-height>28</pref-height>
<binding>
<command>nasal</command>
<script>followme.safety.stop()</script>
</binding>
</button>
<button>
<halign>left</halign>
<legend>Toggle AEB</legend>
<pref-width>120</pref-width>
<pref-height>28</pref-height>
<binding>
<command>nasal</command>
<script>followme.safety.toggleFrontRadar()</script>
</binding>
</button>
<text>
<label>To repair Airbag, reinitialize safety system</label>
</text>
</group>
<hrule/>
<group>
<layout>vbox</layout>
<text><label>Plate</label></text>

View File

@ -295,7 +295,7 @@
<button>
<halign>left</halign>
<legend>Flip Vehicle</legend>
<pref-width>120</pref-width>
<pref-width>150</pref-width>
<pref-height>28</pref-height>
<enable>
<and>
@ -323,7 +323,7 @@
<button>
<halign>left</halign>
<legend>Quick Recharge</legend>
<pref-width>120</pref-width>
<pref-width>150</pref-width>
<pref-height>28</pref-height>
<enable>
<and>
@ -346,10 +346,11 @@
</button>
</group>
<group>
<layout>hbox</layout>
<button>
<halign>left</halign>
<legend>Reset Airbag</legend>
<pref-width>120</pref-width>
<pref-width>150</pref-width>
<pref-height>28</pref-height>
<enable>
<not>
@ -365,7 +366,7 @@
<button>
<halign>left</halign>
<legend>Reset Here</legend>
<pref-width>120</pref-width>
<pref-width>150</pref-width>
<pref-height>28</pref-height>
<enable>
<not>
@ -378,6 +379,9 @@
</binding>
</button>
</group>
<text>
<label>Resetting Airbag stops the entire safety system!</label>
</text>
</group>