Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nikola Balog
erp5
Commits
d63ec839
Commit
d63ec839
authored
Mar 01, 2024
by
Léo-Paul Géneau
👾
Browse files
Options
Browse Files
Download
Plain Diff
Rename functions for multicopters
See merge request
!1891
parents
760e47a9
d240b5c2
Changes
20
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
272 additions
and
349 deletions
+272
-349
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_enemydrone_js.js
...eItem/web_page_module/drone_capture_flag_enemydrone_js.js
+19
-21
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_enemydrone_js.xml
...Item/web_page_module/drone_capture_flag_enemydrone_js.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_fixedwingdrone_js.js
...m/web_page_module/drone_capture_flag_fixedwingdrone_js.js
+30
-70
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_fixedwingdrone_js.xml
.../web_page_module/drone_capture_flag_fixedwingdrone_js.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_logic_js.js
...mplateItem/web_page_module/drone_capture_flag_logic_js.js
+103
-100
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_logic_js.xml
...plateItem/web_page_module/drone_capture_flag_logic_js.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_html.html
...web_page_module/ojs_drone_capture_flag_API_page_html.html
+43
-28
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_html.xml
.../web_page_module/ojs_drone_capture_flag_API_page_html.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_js.xml
...web_page_module/ojs_drone_capture_flag_script_page_js.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag_test/PathTemplateItem/web_page_module/test_capture_drone_flight_js.js
...plateItem/web_page_module/test_capture_drone_flight_js.js
+3
-3
bt5/erp5_officejs_drone_capture_flag_test/PathTemplateItem/web_page_module/test_capture_drone_flight_js.xml
...lateItem/web_page_module/test_capture_drone_flight_js.xml
+2
-2
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_dronelogfollower_js.js
...em/web_page_module/drone_simulator_dronelogfollower_js.js
+2
-5
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_dronelogfollower_js.xml
...m/web_page_module/drone_simulator_dronelogfollower_js.xml
+2
-2
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_fixedwingdrone_js.js
...Item/web_page_module/drone_simulator_fixedwingdrone_js.js
+25
-65
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_fixedwingdrone_js.xml
...tem/web_page_module/drone_simulator_fixedwingdrone_js.xml
+2
-2
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_logic_js.js
...hTemplateItem/web_page_module/drone_simulator_logic_js.js
+22
-32
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_logic_js.xml
...TemplateItem/web_page_module/drone_simulator_logic_js.xml
+2
-2
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/ojs_drone_simulator_script_page_js.xml
...em/web_page_module/ojs_drone_simulator_script_page_js.xml
+2
-2
bt5/erp5_officejs_drone_simulator_test/PathTemplateItem/web_page_module/test_drone_simulator_flight_js.js
...ateItem/web_page_module/test_drone_simulator_flight_js.js
+3
-3
bt5/erp5_officejs_drone_simulator_test/PathTemplateItem/web_page_module/test_drone_simulator_flight_js.xml
...teItem/web_page_module/test_drone_simulator_flight_js.xml
+2
-2
No files found.
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_enemydrone_js.js
View file @
d63ec839
...
@@ -23,6 +23,8 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -23,6 +23,8 @@ var EnemyDroneAPI = /** @class */ (function () {
this
.
_drone_dict_list
=
[];
this
.
_drone_dict_list
=
[];
this
.
_acceleration
=
DEFAULT_ACCELERATION
;
this
.
_acceleration
=
DEFAULT_ACCELERATION
;
this
.
_collision_sector
=
COLLISION_SECTOR
;
this
.
_collision_sector
=
COLLISION_SECTOR
;
this
.
_is_landing
=
false
;
this
.
_is_ready_to_fly
=
true
;
}
}
/*
/*
** Function called on start phase of the drone, just before onStart AI script
** Function called on start phase of the drone, just before onStart AI script
...
@@ -49,7 +51,6 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -49,7 +51,6 @@ var EnemyDroneAPI = /** @class */ (function () {
if
(
drone
.
_maxSinkRate
>
drone
.
_maxSpeed
)
{
if
(
drone
.
_maxSinkRate
>
drone
.
_maxSpeed
)
{
throw
new
Error
(
'
max sink rate cannot be superior to max speed
'
);
throw
new
Error
(
'
max sink rate cannot be superior to max speed
'
);
}
}
drone
.
_maxOrientation
=
this
.
getMaxOrientation
();
return
;
return
;
};
};
/*
/*
...
@@ -57,10 +58,12 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -57,10 +58,12 @@ var EnemyDroneAPI = /** @class */ (function () {
*/
*/
EnemyDroneAPI
.
prototype
.
internal_update
=
function
(
context
,
delta_time
)
{
EnemyDroneAPI
.
prototype
.
internal_update
=
function
(
context
,
delta_time
)
{
context
.
_speed
+=
context
.
_acceleration
*
delta_time
/
1000
;
context
.
_speed
+=
context
.
_acceleration
*
delta_time
/
1000
;
if
(
context
.
_speed
>
context
.
_maxSpeed
)
if
(
context
.
_speed
>
context
.
_maxSpeed
)
{
context
.
_speed
=
context
.
_maxSpeed
;
context
.
_speed
=
context
.
_maxSpeed
;
if
(
context
.
_speed
<
-
context
.
_maxSpeed
)
}
if
(
context
.
_speed
<
-
context
.
_maxSpeed
)
{
context
.
_speed
=
-
context
.
_maxSpeed
;
context
.
_speed
=
-
context
.
_maxSpeed
;
}
var
updateSpeed
=
context
.
_speed
*
delta_time
/
1000
;
var
updateSpeed
=
context
.
_speed
*
delta_time
/
1000
;
if
(
context
.
_direction
.
x
!==
0
||
if
(
context
.
_direction
.
x
!==
0
||
context
.
_direction
.
y
!==
0
||
context
.
_direction
.
y
!==
0
||
...
@@ -68,13 +71,9 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -68,13 +71,9 @@ var EnemyDroneAPI = /** @class */ (function () {
context
.
_controlMesh
.
position
.
addInPlace
(
context
.
_controlMesh
.
position
.
addInPlace
(
new
BABYLON
.
Vector3
(
context
.
_direction
.
x
*
updateSpeed
,
new
BABYLON
.
Vector3
(
context
.
_direction
.
x
*
updateSpeed
,
context
.
_direction
.
y
*
updateSpeed
,
context
.
_direction
.
y
*
updateSpeed
,
context
.
_direction
.
z
*
updateSpeed
));
context
.
_direction
.
z
*
updateSpeed
)
);
}
}
var
orientationValue
=
context
.
_maxOrientation
*
(
context
.
_speed
/
context
.
_maxSpeed
);
context
.
_mesh
.
rotation
=
new
BABYLON
.
Vector3
(
orientationValue
*
context
.
_direction
.
z
,
0
,
-
orientationValue
*
context
.
_direction
.
x
);
context
.
_controlMesh
.
computeWorldMatrix
(
true
);
context
.
_controlMesh
.
computeWorldMatrix
(
true
);
context
.
_mesh
.
computeWorldMatrix
(
true
);
context
.
_mesh
.
computeWorldMatrix
(
true
);
return
;
return
;
...
@@ -119,7 +118,9 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -119,7 +118,9 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI
.
prototype
.
internal_setTargetCoordinates
=
EnemyDroneAPI
.
prototype
.
internal_setTargetCoordinates
=
function
(
drone
,
coordinates
)
{
function
(
drone
,
coordinates
)
{
if
(
!
drone
.
_canPlay
)
return
;
if
(
!
drone
.
_canPlay
)
{
return
;
}
var
x
=
coordinates
.
x
,
y
=
coordinates
.
y
,
z
=
coordinates
.
z
;
var
x
=
coordinates
.
x
,
y
=
coordinates
.
y
,
z
=
coordinates
.
z
;
if
(
isNaN
(
x
)
||
isNaN
(
y
)
||
isNaN
(
z
))
{
if
(
isNaN
(
x
)
||
isNaN
(
y
)
||
isNaN
(
z
))
{
throw
new
Error
(
'
Target coordinates must be numbers
'
);
throw
new
Error
(
'
Target coordinates must be numbers
'
);
...
@@ -279,20 +280,17 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -279,20 +280,17 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI
.
prototype
.
getMaxAcceleration
=
function
()
{
EnemyDroneAPI
.
prototype
.
getMaxAcceleration
=
function
()
{
return
this
.
_flight_parameters
.
drone
.
maxAcceleration
;
return
this
.
_flight_parameters
.
drone
.
maxAcceleration
;
};
};
EnemyDroneAPI
.
prototype
.
getMaxOrientation
=
function
()
{
EnemyDroneAPI
.
prototype
.
land
=
function
(
drone
)
{
//TODO should be a game parameter (but how to force value to PI quarters?)
return
Math
.
PI
/
4
;
};
EnemyDroneAPI
.
prototype
.
triggerParachute
=
function
(
drone
)
{
var
drone_pos
=
drone
.
getCurrentPosition
();
var
drone_pos
=
drone
.
getCurrentPosition
();
drone
.
setTargetCoordinates
(
drone_pos
.
latitude
,
drone_pos
.
longitude
,
5
);
drone
.
setTargetCoordinates
(
drone_pos
.
latitude
,
drone_pos
.
longitude
,
0
);
this
.
_is_ready_to_fly
=
false
;
this
.
_is_landing
=
true
;
};
};
EnemyDroneAPI
.
prototype
.
landed
=
function
(
drone
)
{
EnemyDroneAPI
.
prototype
.
isReadyToFly
=
function
()
{
var
drone_pos
=
drone
.
getCurrentPosition
();
return
this
.
_is_ready_to_fly
;
return
Math
.
floor
(
drone_pos
.
altitude
)
<
10
;
};
};
EnemyDroneAPI
.
prototype
.
exit
=
function
()
{
EnemyDroneAPI
.
prototype
.
isLanding
=
function
()
{
return
;
return
this
.
_is_landing
;
};
};
EnemyDroneAPI
.
prototype
.
getInitialAltitude
=
function
()
{
EnemyDroneAPI
.
prototype
.
getInitialAltitude
=
function
()
{
return
0
;
return
0
;
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_enemydrone_js.xml
View file @
d63ec839
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
101
1.46035.33513.61849
</string>
</value>
<value>
<string>
101
4.56714.1017.16076
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
1
697031010.9
9
</float>
<float>
1
709221104.1
9
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_fixedwingdrone_js.js
View file @
d63ec839
...
@@ -31,6 +31,8 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -31,6 +31,8 @@ var FixedWingDroneAPI = /** @class */ (function () {
this
.
_loiter_radius
=
100
;
this
.
_loiter_radius
=
100
;
//this._start_altitude = 0;
//this._start_altitude = 0;
this
.
_loiter_mode
=
false
;
this
.
_loiter_mode
=
false
;
this
.
_is_landing
=
false
;
this
.
_is_ready_to_fly
=
true
;
this
.
_drone_dict_list
=
[];
this
.
_drone_dict_list
=
[];
}
}
/*
/*
...
@@ -86,45 +88,15 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -86,45 +88,15 @@ var FixedWingDroneAPI = /** @class */ (function () {
if
(
drone
.
_maxClimbRate
>
drone
.
_maxSpeed
)
{
if
(
drone
.
_maxClimbRate
>
drone
.
_maxSpeed
)
{
throw
new
Error
(
'
max climb rate cannot be superior to max speed
'
);
throw
new
Error
(
'
max climb rate cannot be superior to max speed
'
);
}
}
drone
.
_maxOrientation
=
this
.
getMaxOrientation
();
return
;
return
;
};
};
/*
/*
** Function called on every drone update, right before onUpdate AI script
** Function called on every drone update, right before onUpdate AI script
*/
*/
FixedWingDroneAPI
.
prototype
.
internal_update
=
function
(
context
,
delta_time
)
{
FixedWingDroneAPI
.
prototype
.
internal_update
=
function
(
context
,
delta_time
)
{
var
diff
,
newrot
,
orientationValue
,
rotStep
;
//TODO rotation
if
(
context
.
_rotationTarget
)
{
rotStep
=
BABYLON
.
Vector3
.
Zero
();
diff
=
context
.
_rotationTarget
.
subtract
(
context
.
_controlMesh
.
rotation
);
rotStep
.
x
=
(
diff
.
x
>=
1
)
?
1
:
diff
.
x
;
rotStep
.
y
=
(
diff
.
y
>=
1
)
?
1
:
diff
.
y
;
rotStep
.
z
=
(
diff
.
z
>=
1
)
?
1
:
diff
.
z
;
if
(
rotStep
===
BABYLON
.
Vector3
.
Zero
())
{
context
.
_rotationTarget
=
null
;
return
;
}
newrot
=
new
BABYLON
.
Vector3
(
context
.
_controlMesh
.
rotation
.
x
+
(
rotStep
.
x
*
context
.
_rotationSpeed
),
context
.
_controlMesh
.
rotation
.
y
+
(
rotStep
.
y
*
context
.
_rotationSpeed
),
context
.
_controlMesh
.
rotation
.
z
+
(
rotStep
.
z
*
context
.
_rotationSpeed
)
);
context
.
_controlMesh
.
rotation
=
newrot
;
}
this
.
_updateSpeed
(
context
,
delta_time
);
this
.
_updateSpeed
(
context
,
delta_time
);
this
.
_updatePosition
(
context
,
delta_time
);
this
.
_updatePosition
(
context
,
delta_time
);
//TODO rotation
orientationValue
=
context
.
_maxOrientation
*
(
context
.
_speed
/
context
.
_maxSpeed
);
context
.
_mesh
.
rotation
=
new
BABYLON
.
Vector3
(
orientationValue
*
context
.
_direction
.
z
,
0
,
-
orientationValue
*
context
.
_direction
.
x
);
context
.
_controlMesh
.
computeWorldMatrix
(
true
);
context
.
_controlMesh
.
computeWorldMatrix
(
true
);
context
.
_mesh
.
computeWorldMatrix
(
true
);
context
.
_mesh
.
computeWorldMatrix
(
true
);
};
};
...
@@ -144,7 +116,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -144,7 +116,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
'
latitude
'
:
drone_position
.
latitude
,
'
latitude
'
:
drone_position
.
latitude
,
'
longitude
'
:
drone_position
.
longitude
,
'
longitude
'
:
drone_position
.
longitude
,
'
yaw
'
:
drone
.
getYaw
(),
'
yaw
'
:
drone
.
getYaw
(),
'
speed
'
:
drone
.
get
Air
Speed
(),
'
speed
'
:
drone
.
getSpeed
(),
'
climbRate
'
:
drone
.
getClimbRate
()
'
climbRate
'
:
drone
.
getClimbRate
()
};
};
_this
.
_drone_dict_list
[
_this
.
_id
]
=
drone_info
;
_this
.
_drone_dict_list
[
_this
.
_id
]
=
drone_info
;
...
@@ -158,7 +130,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -158,7 +130,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
};
};
FixedWingDroneAPI
.
prototype
.
_updateSpeed
=
function
(
drone
,
delta_time
)
{
FixedWingDroneAPI
.
prototype
.
_updateSpeed
=
function
(
drone
,
delta_time
)
{
var
speed
=
drone
.
get
Air
Speed
(),
speedDiff
,
speedUpdate
;
var
speed
=
drone
.
get
3D
Speed
(),
speedDiff
,
speedUpdate
;
if
(
speed
!==
this
.
_targetSpeed
)
{
if
(
speed
!==
this
.
_targetSpeed
)
{
speedDiff
=
this
.
_targetSpeed
-
speed
;
speedDiff
=
this
.
_targetSpeed
-
speed
;
speedUpdate
=
drone
.
_acceleration
*
delta_time
/
1000
;
speedUpdate
=
drone
.
_acceleration
*
delta_time
/
1000
;
...
@@ -231,7 +203,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -231,7 +203,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed
=
this
.
_getVerticalSpeed
(
drone
);
verticalSpeed
=
this
.
_getVerticalSpeed
(
drone
);
groundSpeed
=
Math
.
sqrt
(
groundSpeed
=
Math
.
sqrt
(
Math
.
pow
(
drone
.
get
Air
Speed
(),
2
)
-
Math
.
pow
(
verticalSpeed
,
2
)
Math
.
pow
(
drone
.
get
3D
Speed
(),
2
)
-
Math
.
pow
(
verticalSpeed
,
2
)
);
);
distance
=
(
groundSpeed
*
delta_time
/
1000
)
/
R
;
distance
=
(
groundSpeed
*
delta_time
/
1000
)
/
R
;
...
@@ -293,39 +265,27 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -293,39 +265,27 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed
=
this
.
_computeVerticalSpeed
(
verticalSpeed
=
this
.
_computeVerticalSpeed
(
altitudeDiff
,
altitudeDiff
,
this
.
getMaxClimbRate
(),
this
.
getMaxClimbRate
(),
drone
.
get
Air
Speed
(),
drone
.
get
3D
Speed
(),
this
.
getMaxPitchAngle
()
this
.
getMaxPitchAngle
()
);
);
}
else
{
}
else
{
verticalSpeed
=
-
this
.
_computeVerticalSpeed
(
verticalSpeed
=
-
this
.
_computeVerticalSpeed
(
Math
.
abs
(
altitudeDiff
),
Math
.
abs
(
altitudeDiff
),
this
.
getMaxSinkRate
(),
this
.
getMaxSinkRate
(),
drone
.
get
Air
Speed
(),
drone
.
get
3D
Speed
(),
-
this
.
getMinPitchAngle
()
-
this
.
getMinPitchAngle
()
);
);
}
}
return
verticalSpeed
;
return
verticalSpeed
;
};
};
FixedWingDroneAPI
.
prototype
.
setRotation
=
function
(
drone
,
x
,
y
,
z
)
{
//TODO rotation
drone
.
_rotationTarget
=
new
BABYLON
.
Vector3
(
x
,
z
,
y
);
};
FixedWingDroneAPI
.
prototype
.
setRotationBy
=
function
(
drone
,
x
,
y
,
z
)
{
//TODO rotation
drone
.
_rotationTarget
=
new
BABYLON
.
Vector3
(
drone
.
rotation
.
x
+
x
,
drone
.
rotation
.
y
+
z
,
drone
.
rotation
.
z
+
y
);
};
FixedWingDroneAPI
.
prototype
.
setSpeed
=
function
(
drone
,
speed
)
{
FixedWingDroneAPI
.
prototype
.
setSpeed
=
function
(
drone
,
speed
)
{
this
.
_targetSpeed
=
Math
.
max
(
this
.
_targetSpeed
=
Math
.
max
(
Math
.
min
(
speed
,
this
.
getMaxSpeed
()),
Math
.
min
(
speed
,
this
.
getMaxSpeed
()),
this
.
getMinSpeed
()
this
.
getMinSpeed
()
);
);
drone
.
_acceleration
=
(
this
.
_targetSpeed
>
drone
.
get
Air
Speed
())
?
drone
.
_acceleration
=
(
this
.
_targetSpeed
>
drone
.
get
3D
Speed
())
?
this
.
getMaxAcceleration
()
:
-
this
.
getMaxDeceleration
();
this
.
getMaxAcceleration
()
:
-
this
.
getMaxDeceleration
();
};
};
...
@@ -490,14 +450,10 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -490,14 +450,10 @@ var FixedWingDroneAPI = /** @class */ (function () {
FixedWingDroneAPI
.
prototype
.
getMaxClimbRate
=
function
()
{
FixedWingDroneAPI
.
prototype
.
getMaxClimbRate
=
function
()
{
return
this
.
_flight_parameters
.
drone
.
maxClimbRate
;
return
this
.
_flight_parameters
.
drone
.
maxClimbRate
;
};
};
FixedWingDroneAPI
.
prototype
.
getMaxOrientation
=
function
()
{
//TODO should be a game parameter (but how to force value to PI quarters?)
return
Math
.
PI
/
4
;
};
FixedWingDroneAPI
.
prototype
.
getYawVelocity
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
getYawVelocity
=
function
(
drone
)
{
return
360
*
EARTH_GRAVITY
*
return
360
*
EARTH_GRAVITY
*
Math
.
tan
(
this
.
_toRad
(
this
.
getMaxRollAngle
()))
/
Math
.
tan
(
this
.
_toRad
(
this
.
getMaxRollAngle
()))
/
(
2
*
Math
.
PI
*
drone
.
get
Air
Speed
());
(
2
*
Math
.
PI
*
drone
.
get
3D
Speed
());
};
};
FixedWingDroneAPI
.
prototype
.
getYaw
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
getYaw
=
function
(
drone
)
{
var
direction
=
drone
.
worldDirection
;
var
direction
=
drone
.
worldDirection
;
...
@@ -533,30 +489,34 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -533,30 +489,34 @@ var FixedWingDroneAPI = /** @class */ (function () {
return
angle
*
180
/
Math
.
PI
;
return
angle
*
180
/
Math
.
PI
;
};
};
FixedWingDroneAPI
.
prototype
.
getClimbRate
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
getClimbRate
=
function
(
drone
)
{
return
drone
.
worldDirection
.
y
*
drone
.
get
Air
Speed
();
return
drone
.
worldDirection
.
y
*
drone
.
get
3D
Speed
();
};
};
FixedWingDroneAPI
.
prototype
.
get
Ground
Speed
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
getSpeed
=
function
(
drone
)
{
var
direction
=
drone
.
worldDirection
;
var
direction
=
drone
.
worldDirection
;
return
Math
.
sqrt
(
return
Math
.
sqrt
(
Math
.
pow
(
direction
.
x
*
drone
.
get
Air
Speed
(),
2
)
+
Math
.
pow
(
direction
.
x
*
drone
.
get
3D
Speed
(),
2
)
+
Math
.
pow
(
direction
.
z
*
drone
.
getAir
Speed
(),
2
)
Math
.
pow
(
direction
.
z
*
drone
.
get3D
Speed
(),
2
)
);
);
};
};
FixedWingDroneAPI
.
prototype
.
triggerParachute
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
takeOff
=
function
()
{
return
console
.
log
(
"
Fixed-wing drones can only be taken off manually.
"
);
};
FixedWingDroneAPI
.
prototype
.
land
=
function
(
drone
)
{
var
drone_pos
=
drone
.
getCurrentPosition
();
var
drone_pos
=
drone
.
getCurrentPosition
();
drone
.
setTargetCoordinates
(
drone
.
setTargetCoordinates
(
drone_pos
.
latitude
,
drone_pos
.
latitude
,
drone_pos
.
longitude
,
drone_pos
.
longitude
,
5
,
0
,
drone
.
get
Air
Speed
()
drone
.
get
3D
Speed
()
);
);
this
.
_is_ready_to_fly
=
false
;
this
.
_is_landing
=
true
;
};
};
FixedWingDroneAPI
.
prototype
.
landed
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
isReadyToFly
=
function
()
{
var
drone_pos
=
drone
.
getCurrentPosition
();
return
this
.
_is_ready_to_fly
;
return
Math
.
floor
(
drone_pos
.
altitude
)
<
10
;
};
};
FixedWingDroneAPI
.
prototype
.
exit
=
function
()
{
FixedWingDroneAPI
.
prototype
.
isLanding
=
function
()
{
return
;
return
this
.
_is_landing
;
};
};
FixedWingDroneAPI
.
prototype
.
getInitialAltitude
=
function
()
{
FixedWingDroneAPI
.
prototype
.
getInitialAltitude
=
function
()
{
return
this
.
_map_dict
.
start_AMSL
;
return
this
.
_map_dict
.
start_AMSL
;
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_fixedwingdrone_js.xml
View file @
d63ec839
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1014.
48041.44620.29337
</string>
</value>
<value>
<string>
1014.
56746.48697.2713
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
1709
113157.81
</float>
<float>
1709
223091.4
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_logic_js.js
View file @
d63ec839
This diff is collapsed.
Click to expand it.
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_logic_js.xml
View file @
d63ec839
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1014.
48183.45277.76
97
</string>
</value>
<value>
<string>
1014.
56745.33504.261
97
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
1709
113192.28
</float>
<float>
1709
223446.72
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_html.html
View file @
d63ec839
...
@@ -340,6 +340,24 @@
...
@@ -340,6 +340,24 @@
<div
class=
"line"
></div>
<div
class=
"line"
></div>
<!-- takeOff -->
<h4
class=
"item-name"
id=
"takeOff"
><span>
takeOff
</span><span>
: void
</span></h4>
<p
class=
"item-descr"
>
Trigger drone's takeoff (has only effect on multicopters as fixed wings drones need to take off manually).
</p>
<div>
<h5
class=
"item-param-1"
>
Param
</h5>
<h5
class=
"item-param-2"
>
Description
</h5>
</div>
<div>
<h5
class=
"item-param-1"
>
Example
</h5>
</div>
<p
class=
"item-param-1"
>
me.takeOff();
<br>
</p>
<div
class=
"line"
></div>
<!-- setTargetCoordinates -->
<!-- setTargetCoordinates -->
<h4
class=
"item-name"
id=
"setTargetCoordinates"
><span>
setTargetCoordinates
</span><span>
: void
</span></h4>
<h4
class=
"item-name"
id=
"setTargetCoordinates"
><span>
setTargetCoordinates
</span><span>
: void
</span></h4>
<p
class=
"item-descr"
>
<p
class=
"item-descr"
>
...
@@ -439,9 +457,9 @@
...
@@ -439,9 +457,9 @@
<div
class=
"line"
></div>
<div
class=
"line"
></div>
<!--
triggerParachute
-->
<!--
land
-->
<h4
class=
"item-name"
id=
"
triggerParachute"
><span>
triggerParachute
</span><span>
: void
</span></h4>
<h4
class=
"item-name"
id=
"
land"
><span>
land
</span><span>
: void
</span></h4>
<p
class=
"item-descr"
>
Indicates the drone to
deploy the parachute to finish the
landing.
</p>
<p
class=
"item-descr"
>
Indicates the drone to
trigger
landing.
</p>
<div>
<div>
<h5
class=
"item-param-1"
>
Param
</h5>
<h5
class=
"item-param-1"
>
Param
</h5>
...
@@ -452,23 +470,33 @@
...
@@ -452,23 +470,33 @@
<h5
class=
"item-param-1"
>
Example
</h5>
<h5
class=
"item-param-1"
>
Example
</h5>
</div>
</div>
<p
class=
"item-param-1"
>
me.
triggerParachute
();
<br>
<p
class=
"item-param-1"
>
me.
land
();
<br>
</p>
</p>
<div
class=
"line"
></div>
<div
class=
"line"
></div>
<!--
landed
-->
<!--
isReadyToFly
-->
<h4
class=
"item-name"
id=
"
landed"
><span>
landed
</span><span>
: boolean
</span></h4>
<h4
class=
"item-name"
id=
"
isReadyToFly"
><span>
isReadyToFly
</span><span>
: void
</span></h4>
<p
class=
"item-descr"
>
Indicates if the drone has landed (reached the floor altitude)
.
</p>
<p
class=
"item-descr"
>
Check if drone takeoff is finished
.
</p>
<div>
<div>
<h5
class=
"item-param-1"
>
Example
</h5>
<h5
class=
"item-param-1"
>
Example
</h5>
</div>
</div>
<p
class=
"item-example"
>
<p
class=
"item-param-1"
>
me.isReadyToFly();
<br>
if (me.landed()) {
<br>
</p>
//do something
<br>
}
<br>
<div
class=
"line"
></div>
<!-- isLanding -->
<h4
class=
"item-name"
id=
"isLanding"
><span>
isLanding
</span><span>
: void
</span></h4>
<p
class=
"item-descr"
>
Check if drone landing has been triggered.
</p>
<div>
<h5
class=
"item-param-1"
>
Example
</h5>
</div>
<p
class=
"item-param-1"
>
me.isLanding();
<br>
</p>
</p>
<div
class=
"line"
></div>
<div
class=
"line"
></div>
...
@@ -501,15 +529,15 @@
...
@@ -501,15 +529,15 @@
<div
class=
"line"
></div>
<div
class=
"line"
></div>
<!-- get
Air
Speed -->
<!-- getSpeed -->
<h4
class=
"item-name"
id=
"get
AirSpeed"
><span>
getAir
Speed
</span><span>
: Float
</span></h4>
<h4
class=
"item-name"
id=
"get
Speed"
><span>
get
Speed
</span><span>
: Float
</span></h4>
<p
class=
"item-descr"
>
Get drone
air speed in meters/secon
d.
</p>
<p
class=
"item-descr"
>
Get drone
ground speed in meters/second as wind is neglected in simulation. In real flights with fixed wings drones the returned value is the airspee
d.
</p>
<div>
<div>
<h5
class=
"item-param-1"
>
Example
</h5>
<h5
class=
"item-param-1"
>
Example
</h5>
</div>
</div>
<p
class=
"item-param-1"
>
me.get
Air
Speed();
<br>
<p
class=
"item-param-1"
>
me.getSpeed();
<br>
</p>
</p>
<div
class=
"line"
></div>
<div
class=
"line"
></div>
...
@@ -553,19 +581,6 @@
...
@@ -553,19 +581,6 @@
<div
class=
"line"
></div>
<div
class=
"line"
></div>
<!-- getSinkRate -->
<h4
class=
"item-name"
id=
"getSinkRate"
><span>
getSinkRate
</span><span>
: Float
</span></h4>
<p
class=
"item-descr"
>
Get drone sink rate in meters/second.
</p>
<div>
<h5
class=
"item-param-1"
>
Example
</h5>
</div>
<p
class=
"item-param-1"
>
me.getSinkRate();
<br>
</p>
<div
class=
"line"
></div>
<h3>
Drone properties
</h3>
<h3>
Drone properties
</h3>
<div
class=
"line"
></div>
<div
class=
"line"
></div>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_html.xml
View file @
d63ec839
...
@@ -244,7 +244,7 @@
...
@@ -244,7 +244,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1014.4
5296.39536.30276
</string>
</value>
<value>
<string>
1014.4
6767.47211.3123
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -264,7 +264,7 @@
...
@@ -264,7 +264,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
1708
536065.15
</float>
<float>
1708
688564.0
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_js.xml
View file @
d63ec839
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1014.
55204.2137.9676
</string>
</value>
<value>
<string>
1014.
46368.9372.48435
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
170
9130500.2
</float>
<float>
170
8616910.25
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag_test/PathTemplateItem/web_page_module/test_capture_drone_flight_js.js
View file @
d63ec839
...
@@ -53,7 +53,7 @@
...
@@ -53,7 +53,7 @@
'
}
\n
'
+
'
}
\n
'
+
'
\n
'
+
'
\n
'
+
'
me.onStart = function () {
\n
'
+
'
me.onStart = function () {
\n
'
+
'
assert(me.get
Air
Speed(),
'
+
DEFAULT_SPEED
+
'
, "Initial speed");
\n
'
+
'
assert(me.getSpeed(),
'
+
DEFAULT_SPEED
+
'
, "Initial speed");
\n
'
+
'
assert(me.getYaw(), 0, "Yaw angle")
\n
'
+
'
assert(me.getYaw(), 0, "Yaw angle")
\n
'
+
'
me.initialPosition = me.getCurrentPosition();
\n
'
+
'
me.initialPosition = me.getCurrentPosition();
\n
'
+
'
me.setTargetCoordinates(
\n
'
+
'
me.setTargetCoordinates(
\n
'
+
...
@@ -73,7 +73,7 @@
...
@@ -73,7 +73,7 @@
'
me.getCurrentPosition().longitude
\n
'
+
'
me.getCurrentPosition().longitude
\n
'
+
'
).toFixed(8),
\n
'
+
'
).toFixed(8),
\n
'
+
'
time_interval = 1000 / 60,
\n
'
+
'
time_interval = 1000 / 60,
\n
'
+
'
expectedDistance = (me.get
Air
Speed() * time_interval / 1000).toFixed(8);
\n
'
+
'
expectedDistance = (me.getSpeed() * time_interval / 1000).toFixed(8);
\n
'
+
'
assert(timestamp, Math.floor(time_interval), "Timestamp");
\n
'
+
'
assert(timestamp, Math.floor(time_interval), "Timestamp");
\n
'
+
'
assert(realDistance, expectedDistance, "Distance");
\n
'
+
'
assert(realDistance, expectedDistance, "Distance");
\n
'
+
'
current_position.latitude = current_position.latitude.toFixed(7);
\n
'
+
'
current_position.latitude = current_position.latitude.toFixed(7);
\n
'
+
...
@@ -82,7 +82,7 @@
...
@@ -82,7 +82,7 @@
'
longitude: me.initialPosition.longitude,
\n
'
+
'
longitude: me.initialPosition.longitude,
\n
'
+
'
altitude: me.initialPosition.altitude
\n
'
+
'
altitude: me.initialPosition.altitude
\n
'
+
'
});
\n
'
+
'
});
\n
'
+
'
me.exit(me.
triggerParachute
());
\n
'
+
'
me.exit(me.
land
());
\n
'
+
'
};
'
,
'
};
'
,
DRAW
=
true
,
DRAW
=
true
,
LOG
=
true
,
LOG
=
true
,
...
...
bt5/erp5_officejs_drone_capture_flag_test/PathTemplateItem/web_page_module/test_capture_drone_flight_js.xml
View file @
d63ec839
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1014.552
02.48917.18107
</string>
</value>
<value>
<string>
1014.552
87.25371.8430
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
170913
0419.
7
</float>
<float>
170913
6147.5
7
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_dronelogfollower_js.js
View file @
d63ec839
...
@@ -207,11 +207,8 @@ var DroneLogAPI = /** @class */ (function () {
...
@@ -207,11 +207,8 @@ var DroneLogAPI = /** @class */ (function () {
DroneLogAPI
.
prototype
.
getFlightParameters
=
function
()
{
DroneLogAPI
.
prototype
.
getFlightParameters
=
function
()
{
return
this
.
_flight_parameters
;
return
this
.
_flight_parameters
;
};
};
DroneLogAPI
.
prototype
.
exit
=
function
(
drone
)
{
DroneLogAPI
.
prototype
.
isReadyToFly
=
function
()
{
return
;
return
true
;
};
DroneLogAPI
.
prototype
.
set_loiter_mode
=
function
(
loiter
)
{
return
;
};
};
return
DroneLogAPI
;
return
DroneLogAPI
;
...
...
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_dronelogfollower_js.xml
View file @
d63ec839
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
101
1.48679.53693.47701
</string>
</value>
<value>
<string>
101
4.12050.13065.34372
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
1
697030760.4
8
</float>
<float>
1
706542267.2
8
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_fixedwingdrone_js.js
View file @
d63ec839
...
@@ -30,6 +30,8 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -30,6 +30,8 @@ var FixedWingDroneAPI = /** @class */ (function () {
this
.
_loiter_radius
=
100
;
this
.
_loiter_radius
=
100
;
//this._start_altitude = 0;
//this._start_altitude = 0;
this
.
_loiter_mode
=
false
;
this
.
_loiter_mode
=
false
;
this
.
_is_landing
=
false
;
this
.
_is_ready_to_fly
=
true
;
this
.
_drone_dict_list
=
[];
this
.
_drone_dict_list
=
[];
}
}
Object
.
defineProperty
(
FixedWingDroneAPI
.
prototype
,
"
isCollidable
"
,
{
Object
.
defineProperty
(
FixedWingDroneAPI
.
prototype
,
"
isCollidable
"
,
{
...
@@ -90,45 +92,15 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -90,45 +92,15 @@ var FixedWingDroneAPI = /** @class */ (function () {
if
(
drone
.
_maxClimbRate
>
drone
.
_maxSpeed
)
{
if
(
drone
.
_maxClimbRate
>
drone
.
_maxSpeed
)
{
throw
new
Error
(
'
max climb rate cannot be superior to max speed
'
);
throw
new
Error
(
'
max climb rate cannot be superior to max speed
'
);
}
}
drone
.
_maxOrientation
=
this
.
getMaxOrientation
();
return
;
return
;
};
};
/*
/*
** Function called on every drone update, right before onUpdate AI script
** Function called on every drone update, right before onUpdate AI script
*/
*/
FixedWingDroneAPI
.
prototype
.
internal_update
=
function
(
context
,
delta_time
)
{
FixedWingDroneAPI
.
prototype
.
internal_update
=
function
(
context
,
delta_time
)
{
var
diff
,
newrot
,
orientationValue
,
rotStep
;
//TODO rotation
if
(
context
.
_rotationTarget
)
{
rotStep
=
BABYLON
.
Vector3
.
Zero
();
diff
=
context
.
_rotationTarget
.
subtract
(
context
.
_controlMesh
.
rotation
);
rotStep
.
x
=
(
diff
.
x
>=
1
)
?
1
:
diff
.
x
;
rotStep
.
y
=
(
diff
.
y
>=
1
)
?
1
:
diff
.
y
;
rotStep
.
z
=
(
diff
.
z
>=
1
)
?
1
:
diff
.
z
;
if
(
rotStep
===
BABYLON
.
Vector3
.
Zero
())
{
context
.
_rotationTarget
=
null
;
return
;
}
newrot
=
new
BABYLON
.
Vector3
(
context
.
_controlMesh
.
rotation
.
x
+
(
rotStep
.
x
*
context
.
_rotationSpeed
),
context
.
_controlMesh
.
rotation
.
y
+
(
rotStep
.
y
*
context
.
_rotationSpeed
),
context
.
_controlMesh
.
rotation
.
z
+
(
rotStep
.
z
*
context
.
_rotationSpeed
)
);
context
.
_controlMesh
.
rotation
=
newrot
;
}
this
.
_updateSpeed
(
context
,
delta_time
);
this
.
_updateSpeed
(
context
,
delta_time
);
this
.
_updatePosition
(
context
,
delta_time
);
this
.
_updatePosition
(
context
,
delta_time
);
//TODO rotation
orientationValue
=
context
.
_maxOrientation
*
(
context
.
_speed
/
context
.
_maxSpeed
);
context
.
_mesh
.
rotation
=
new
BABYLON
.
Vector3
(
orientationValue
*
context
.
_direction
.
z
,
0
,
-
orientationValue
*
context
.
_direction
.
x
);
context
.
_controlMesh
.
computeWorldMatrix
(
true
);
context
.
_controlMesh
.
computeWorldMatrix
(
true
);
context
.
_mesh
.
computeWorldMatrix
(
true
);
context
.
_mesh
.
computeWorldMatrix
(
true
);
};
};
...
@@ -148,7 +120,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -148,7 +120,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
'
latitude
'
:
drone_position
.
latitude
,
'
latitude
'
:
drone_position
.
latitude
,
'
longitude
'
:
drone_position
.
longitude
,
'
longitude
'
:
drone_position
.
longitude
,
'
yaw
'
:
drone
.
getYaw
(),
'
yaw
'
:
drone
.
getYaw
(),
'
speed
'
:
drone
.
get
Air
Speed
(),
'
speed
'
:
drone
.
getSpeed
(),
'
climbRate
'
:
drone
.
getClimbRate
()
'
climbRate
'
:
drone
.
getClimbRate
()
};
};
_this
.
_drone_dict_list
[
_this
.
_id
]
=
drone_info
;
_this
.
_drone_dict_list
[
_this
.
_id
]
=
drone_info
;
...
@@ -162,7 +134,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -162,7 +134,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
};
};
FixedWingDroneAPI
.
prototype
.
_updateSpeed
=
function
(
drone
,
delta_time
)
{
FixedWingDroneAPI
.
prototype
.
_updateSpeed
=
function
(
drone
,
delta_time
)
{
var
speed
=
drone
.
get
Air
Speed
(),
speedDiff
,
speedUpdate
;
var
speed
=
drone
.
get
3D
Speed
(),
speedDiff
,
speedUpdate
;
if
(
speed
!==
this
.
_targetSpeed
)
{
if
(
speed
!==
this
.
_targetSpeed
)
{
speedDiff
=
this
.
_targetSpeed
-
speed
;
speedDiff
=
this
.
_targetSpeed
-
speed
;
speedUpdate
=
drone
.
_acceleration
*
delta_time
/
1000
;
speedUpdate
=
drone
.
_acceleration
*
delta_time
/
1000
;
...
@@ -235,7 +207,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -235,7 +207,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed
=
this
.
_getVerticalSpeed
(
drone
);
verticalSpeed
=
this
.
_getVerticalSpeed
(
drone
);
groundSpeed
=
Math
.
sqrt
(
groundSpeed
=
Math
.
sqrt
(
Math
.
pow
(
drone
.
get
Air
Speed
(),
2
)
-
Math
.
pow
(
verticalSpeed
,
2
)
Math
.
pow
(
drone
.
get
3D
Speed
(),
2
)
-
Math
.
pow
(
verticalSpeed
,
2
)
);
);
distance
=
(
groundSpeed
*
delta_time
/
1000
)
/
R
;
distance
=
(
groundSpeed
*
delta_time
/
1000
)
/
R
;
...
@@ -297,39 +269,27 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -297,39 +269,27 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed
=
this
.
_computeVerticalSpeed
(
verticalSpeed
=
this
.
_computeVerticalSpeed
(
altitudeDiff
,
altitudeDiff
,
this
.
getMaxClimbRate
(),
this
.
getMaxClimbRate
(),
drone
.
get
Air
Speed
(),
drone
.
get
3D
Speed
(),
this
.
getMaxPitchAngle
()
this
.
getMaxPitchAngle
()
);
);
}
else
{
}
else
{
verticalSpeed
=
-
this
.
_computeVerticalSpeed
(
verticalSpeed
=
-
this
.
_computeVerticalSpeed
(
Math
.
abs
(
altitudeDiff
),
Math
.
abs
(
altitudeDiff
),
this
.
getMaxSinkRate
(),
this
.
getMaxSinkRate
(),
drone
.
get
Air
Speed
(),
drone
.
get
3D
Speed
(),
-
this
.
getMinPitchAngle
()
-
this
.
getMinPitchAngle
()
);
);
}
}
return
verticalSpeed
;
return
verticalSpeed
;
};
};
FixedWingDroneAPI
.
prototype
.
setRotation
=
function
(
drone
,
x
,
y
,
z
)
{
//TODO rotation
drone
.
_rotationTarget
=
new
BABYLON
.
Vector3
(
x
,
z
,
y
);
};
FixedWingDroneAPI
.
prototype
.
setRotationBy
=
function
(
drone
,
x
,
y
,
z
)
{
//TODO rotation
drone
.
_rotationTarget
=
new
BABYLON
.
Vector3
(
drone
.
rotation
.
x
+
x
,
drone
.
rotation
.
y
+
z
,
drone
.
rotation
.
z
+
y
);
};
FixedWingDroneAPI
.
prototype
.
setSpeed
=
function
(
drone
,
speed
)
{
FixedWingDroneAPI
.
prototype
.
setSpeed
=
function
(
drone
,
speed
)
{
this
.
_targetSpeed
=
Math
.
max
(
this
.
_targetSpeed
=
Math
.
max
(
Math
.
min
(
speed
,
this
.
getMaxSpeed
()),
Math
.
min
(
speed
,
this
.
getMaxSpeed
()),
this
.
getMinSpeed
()
this
.
getMinSpeed
()
);
);
drone
.
_acceleration
=
(
this
.
_targetSpeed
>
drone
.
get
Air
Speed
())
drone
.
_acceleration
=
(
this
.
_targetSpeed
>
drone
.
get
3D
Speed
())
?
this
.
getMaxAcceleration
()
:
-
this
.
getMaxDeceleration
();
?
this
.
getMaxAcceleration
()
:
-
this
.
getMaxDeceleration
();
};
};
...
@@ -448,14 +408,10 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -448,14 +408,10 @@ var FixedWingDroneAPI = /** @class */ (function () {
FixedWingDroneAPI
.
prototype
.
getMaxClimbRate
=
function
()
{
FixedWingDroneAPI
.
prototype
.
getMaxClimbRate
=
function
()
{
return
this
.
_flight_parameters
.
drone
.
maxClimbRate
;
return
this
.
_flight_parameters
.
drone
.
maxClimbRate
;
};
};
FixedWingDroneAPI
.
prototype
.
getMaxOrientation
=
function
()
{
//TODO should be a game parameter (but how to force value to PI quarters?)
return
Math
.
PI
/
4
;
};
FixedWingDroneAPI
.
prototype
.
getYawVelocity
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
getYawVelocity
=
function
(
drone
)
{
return
360
*
EARTH_GRAVITY
return
360
*
EARTH_GRAVITY
*
Math
.
tan
(
this
.
_toRad
(
this
.
getMaxRollAngle
()))
*
Math
.
tan
(
this
.
_toRad
(
this
.
getMaxRollAngle
()))
/
(
2
*
Math
.
PI
*
drone
.
get
Air
Speed
());
/
(
2
*
Math
.
PI
*
drone
.
get
3D
Speed
());
};
};
FixedWingDroneAPI
.
prototype
.
getYaw
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
getYaw
=
function
(
drone
)
{
var
direction
=
drone
.
worldDirection
;
var
direction
=
drone
.
worldDirection
;
...
@@ -492,30 +448,34 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -492,30 +448,34 @@ var FixedWingDroneAPI = /** @class */ (function () {
return
angle
*
180
/
Math
.
PI
;
return
angle
*
180
/
Math
.
PI
;
};
};
FixedWingDroneAPI
.
prototype
.
getClimbRate
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
getClimbRate
=
function
(
drone
)
{
return
drone
.
worldDirection
.
y
*
drone
.
get
Air
Speed
();
return
drone
.
worldDirection
.
y
*
drone
.
get
3D
Speed
();
};
};
FixedWingDroneAPI
.
prototype
.
get
Ground
Speed
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
getSpeed
=
function
(
drone
)
{
var
direction
=
drone
.
worldDirection
;
var
direction
=
drone
.
worldDirection
;
return
Math
.
sqrt
(
return
Math
.
sqrt
(
Math
.
pow
(
direction
.
x
*
drone
.
get
Air
Speed
(),
2
)
Math
.
pow
(
direction
.
x
*
drone
.
get
3D
Speed
(),
2
)
+
Math
.
pow
(
direction
.
z
*
drone
.
get
Air
Speed
(),
2
)
+
Math
.
pow
(
direction
.
z
*
drone
.
get
3D
Speed
(),
2
)
);
);
};
};
FixedWingDroneAPI
.
prototype
.
triggerParachute
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
takeOff
=
function
()
{
return
console
.
log
(
"
Fixed-wing drones can only be taken off manually.
"
);
};
FixedWingDroneAPI
.
prototype
.
land
=
function
(
drone
)
{
var
drone_pos
=
drone
.
getCurrentPosition
();
var
drone_pos
=
drone
.
getCurrentPosition
();
drone
.
setTargetCoordinates
(
drone
.
setTargetCoordinates
(
drone_pos
.
latitude
,
drone_pos
.
latitude
,
drone_pos
.
longitude
,
drone_pos
.
longitude
,
5
,
0
,
drone
.
get
Air
Speed
()
drone
.
get
3D
Speed
()
);
);
this
.
_is_ready_to_fly
=
false
;
this
.
_is_landing
=
true
;
};
};
FixedWingDroneAPI
.
prototype
.
landed
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
isReadyToFly
=
function
()
{
var
drone_pos
=
drone
.
getCurrentPosition
();
return
this
.
_is_ready_to_fly
;
return
Math
.
floor
(
drone_pos
.
altitude
)
<
10
;
};
};
FixedWingDroneAPI
.
prototype
.
exit
=
function
()
{
FixedWingDroneAPI
.
prototype
.
isLanding
=
function
()
{
return
;
return
this
.
_is_landing
;
};
};
FixedWingDroneAPI
.
prototype
.
getInitialAltitude
=
function
()
{
FixedWingDroneAPI
.
prototype
.
getInitialAltitude
=
function
()
{
return
this
.
_map_dict
.
start_AMSL
;
return
this
.
_map_dict
.
start_AMSL
;
...
...
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_fixedwingdrone_js.xml
View file @
d63ec839
...
@@ -240,7 +240,7 @@
...
@@ -240,7 +240,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1014.1
1751.44914.51968
</string>
</value>
<value>
<string>
1014.1
2067.27492.45397
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -260,7 +260,7 @@
...
@@ -260,7 +260,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
17065
23358.41
</float>
<float>
17065
42739.07
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_logic_js.js
View file @
d63ec839
...
@@ -25,11 +25,9 @@ var DroneManager = /** @class */ (function () {
...
@@ -25,11 +25,9 @@ var DroneManager = /** @class */ (function () {
this
.
_maxRollAngle
=
0
;
this
.
_maxRollAngle
=
0
;
this
.
_maxSinkRate
=
0
;
this
.
_maxSinkRate
=
0
;
this
.
_maxClimbRate
=
0
;
this
.
_maxClimbRate
=
0
;
this
.
_maxOrientation
=
0
;
this
.
_speed
=
0
;
this
.
_speed
=
0
;
this
.
_acceleration
=
0
;
this
.
_acceleration
=
0
;
this
.
_direction
=
new
BABYLON
.
Vector3
(
0
,
0
,
1
);
// North
this
.
_direction
=
new
BABYLON
.
Vector3
(
0
,
0
,
1
);
// North
this
.
_rotationSpeed
=
0.4
;
this
.
_scene
=
scene
;
this
.
_scene
=
scene
;
this
.
_canUpdate
=
true
;
this
.
_canUpdate
=
true
;
this
.
_id
=
id
;
this
.
_id
=
id
;
...
@@ -141,7 +139,7 @@ var DroneManager = /** @class */ (function () {
...
@@ -141,7 +139,7 @@ var DroneManager = /** @class */ (function () {
};
};
DroneManager
.
prototype
.
_internal_setTargetCoordinates
=
DroneManager
.
prototype
.
_internal_setTargetCoordinates
=
function
(
latitude
,
longitude
,
altitude
,
speed
,
radius
)
{
function
(
latitude
,
longitude
,
altitude
,
speed
,
radius
)
{
if
(
!
this
.
_canPlay
)
{
if
(
!
this
.
_canPlay
||
!
this
.
isReadyToFly
()
)
{
return
;
return
;
}
}
//convert real geo-coordinates to virtual x-y coordinates
//convert real geo-coordinates to virtual x-y coordinates
...
@@ -209,20 +207,6 @@ var DroneManager = /** @class */ (function () {
...
@@ -209,20 +207,6 @@ var DroneManager = /** @class */ (function () {
this
.
_direction
=
new
BABYLON
.
Vector3
(
x
,
z
,
y
).
normalize
();
this
.
_direction
=
new
BABYLON
.
Vector3
(
x
,
z
,
y
).
normalize
();
};
};
//TODO rotation
DroneManager
.
prototype
.
setRotation
=
function
(
x
,
y
,
z
)
{
if
(
!
this
.
_canPlay
)
{
return
;
}
return
this
.
_API
.
setRotation
(
this
,
x
,
y
,
z
);
};
DroneManager
.
prototype
.
setRotationBy
=
function
(
x
,
y
,
z
)
{
if
(
!
this
.
_canPlay
)
{
return
;
}
return
this
.
_API
.
setRotation
(
this
,
x
,
y
,
z
);
};
/**
/**
* Send a message to drones
* Send a message to drones
* @param msg The message to send
* @param msg The message to send
...
@@ -309,27 +293,29 @@ var DroneManager = /** @class */ (function () {
...
@@ -309,27 +293,29 @@ var DroneManager = /** @class */ (function () {
DroneManager
.
prototype
.
getYaw
=
function
()
{
DroneManager
.
prototype
.
getYaw
=
function
()
{
return
this
.
_API
.
getYaw
(
this
);
return
this
.
_API
.
getYaw
(
this
);
};
};
DroneManager
.
prototype
.
get
Air
Speed
=
function
()
{
DroneManager
.
prototype
.
get
3D
Speed
=
function
()
{
return
this
.
_speed
;
return
this
.
_speed
;
};
};
DroneManager
.
prototype
.
get
Ground
Speed
=
function
()
{
DroneManager
.
prototype
.
getSpeed
=
function
()
{
return
this
.
_API
.
get
Ground
Speed
(
this
);
return
this
.
_API
.
getSpeed
(
this
);
};
};
DroneManager
.
prototype
.
getClimbRate
=
function
()
{
DroneManager
.
prototype
.
getClimbRate
=
function
()
{
return
this
.
_API
.
getClimbRate
(
this
);
return
this
.
_API
.
getClimbRate
(
this
);
};
};
DroneManager
.
prototype
.
getSinkRate
=
function
()
{
DroneManager
.
prototype
.
takeOff
=
function
()
{
return
this
.
_API
.
getSinkRate
();
return
this
.
_API
.
takeOff
();
};
};
DroneManager
.
prototype
.
triggerParachute
=
function
()
{
DroneManager
.
prototype
.
land
=
function
()
{
return
this
.
_API
.
triggerParachute
(
this
);
return
this
.
_API
.
land
(
this
);
};
};
DroneManager
.
prototype
.
exit
=
function
()
{
DroneManager
.
prototype
.
exit
=
function
()
{
this
.
_internal_crash
();
return
this
.
_internal_crash
();
return
this
.
_API
.
exit
();
};
};
DroneManager
.
prototype
.
landed
=
function
()
{
DroneManager
.
prototype
.
isReadyToFly
=
function
()
{
return
this
.
_API
.
landed
(
this
);
return
this
.
_API
.
isReadyToFly
();
};
DroneManager
.
prototype
.
isLanding
=
function
()
{
return
this
.
_API
.
isLanding
();
};
};
/**
/**
* Set the drone last checkpoint reached
* Set the drone last checkpoint reached
...
@@ -347,7 +333,7 @@ var DroneManager = /** @class */ (function () {
...
@@ -347,7 +333,7 @@ var DroneManager = /** @class */ (function () {
* Function called on game update
* Function called on game update
* @param timestamp The tic value
* @param timestamp The tic value
*/
*/
DroneManager
.
prototype
.
onUpdate
=
function
()
{
return
;
};
DroneManager
.
prototype
.
onUpdate
=
function
(
timestamp
)
{
return
;
};
/**
/**
* Function called when drone crashes
* Function called when drone crashes
*/
*/
...
@@ -668,8 +654,12 @@ var GameManager = /** @class */ (function () {
...
@@ -668,8 +654,12 @@ var GameManager = /** @class */ (function () {
drone
.
_tick
+=
1
;
drone
.
_tick
+=
1
;
if
(
drone
.
_API
.
isCollidable
&&
drone
.
can_play
)
{
if
(
drone
.
_API
.
isCollidable
&&
drone
.
can_play
)
{
if
(
drone
.
getCurrentPosition
().
altitude
<=
0
)
{
if
(
drone
.
getCurrentPosition
().
altitude
<=
0
)
{
if
(
!
drone
.
isLanding
())
{
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
'
touched the floor.
'
));
'
touched the floor.
'
));
}
else
{
drone
.
_internal_crash
();
}
}
else
{
}
else
{
_this
.
_droneList
.
forEach
(
function
(
other
)
{
_this
.
_droneList
.
forEach
(
function
(
other
)
{
if
(
other
.
can_play
&&
drone
.
id
!==
other
.
id
)
{
if
(
other
.
can_play
&&
drone
.
id
!==
other
.
id
)
{
...
@@ -722,7 +712,7 @@ var GameManager = /** @class */ (function () {
...
@@ -722,7 +712,7 @@ var GameManager = /** @class */ (function () {
game_manager
.
_game_duration
,
geo_coordinates
.
latitude
,
game_manager
.
_game_duration
,
geo_coordinates
.
latitude
,
geo_coordinates
.
longitude
,
geo_coordinates
.
longitude
,
map_info
.
start_AMSL
+
drone_position
.
z
,
map_info
.
start_AMSL
+
drone_position
.
z
,
drone_position
.
z
,
drone
.
getYaw
(),
drone
.
get
Ground
Speed
(),
drone_position
.
z
,
drone
.
getYaw
(),
drone
.
getSpeed
(),
drone
.
getClimbRate
()
drone
.
getClimbRate
()
]);
]);
}
}
...
...
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/drone_simulator_logic_js.xml
View file @
d63ec839
...
@@ -240,7 +240,7 @@
...
@@ -240,7 +240,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1014.1
1746.34243.61149
</string>
</value>
<value>
<string>
1014.1
2072.47950.5358
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -260,7 +260,7 @@
...
@@ -260,7 +260,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
17065
23386.8
</float>
<float>
17065
42965.82
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_simulator/PathTemplateItem/web_page_module/ojs_drone_simulator_script_page_js.xml
View file @
d63ec839
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1014.
54902.15254.29337
</string>
</value>
<value>
<string>
1014.
11755.64575.41864
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
170
9130323.68
</float>
<float>
170
6525997.75
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_simulator_test/PathTemplateItem/web_page_module/test_drone_simulator_flight_js.js
View file @
d63ec839
...
@@ -57,7 +57,7 @@
...
@@ -57,7 +57,7 @@
'
}
\n
'
+
'
}
\n
'
+
'
\n
'
+
'
\n
'
+
'
me.onStart = function () {
\n
'
+
'
me.onStart = function () {
\n
'
+
'
assert(me.get
Air
Speed(),
'
+
DEFAULT_SPEED
+
'
, "Initial speed");
\n
'
+
'
assert(me.getSpeed(),
'
+
DEFAULT_SPEED
+
'
, "Initial speed");
\n
'
+
'
assert(me.getYaw(), 0, "Yaw angle")
\n
'
+
'
assert(me.getYaw(), 0, "Yaw angle")
\n
'
+
'
me.initialPosition = me.getCurrentPosition();
\n
'
+
'
me.initialPosition = me.getCurrentPosition();
\n
'
+
'
me.setTargetCoordinates(
\n
'
+
'
me.setTargetCoordinates(
\n
'
+
...
@@ -76,7 +76,7 @@
...
@@ -76,7 +76,7 @@
'
me.getCurrentPosition().latitude,
\n
'
+
'
me.getCurrentPosition().latitude,
\n
'
+
'
me.getCurrentPosition().longitude
\n
'
+
'
me.getCurrentPosition().longitude
\n
'
+
'
).toFixed(8),
\n
'
+
'
).toFixed(8),
\n
'
+
'
expectedDistance = (me.get
Air
Speed() * timestamp / 1000).toFixed(8);
\n
'
+
'
expectedDistance = (me.getSpeed() * timestamp / 1000).toFixed(8);
\n
'
+
'
assert(timestamp, 1000 / 60, "Timestamp");
\n
'
+
'
assert(timestamp, 1000 / 60, "Timestamp");
\n
'
+
'
assert(realDistance, expectedDistance, "Distance");
\n
'
+
'
assert(realDistance, expectedDistance, "Distance");
\n
'
+
'
current_position.latitude = current_position.latitude.toFixed(7);
\n
'
+
'
current_position.latitude = current_position.latitude.toFixed(7);
\n
'
+
...
@@ -85,7 +85,7 @@
...
@@ -85,7 +85,7 @@
'
longitude: me.initialPosition.longitude,
\n
'
+
'
longitude: me.initialPosition.longitude,
\n
'
+
'
altitude: me.initialPosition.altitude
\n
'
+
'
altitude: me.initialPosition.altitude
\n
'
+
'
});
\n
'
+
'
});
\n
'
+
'
me.exit(me.
triggerParachute
());
\n
'
+
'
me.exit(me.
land
());
\n
'
+
'
};
'
,
'
};
'
,
DRAW
=
true
,
DRAW
=
true
,
LOG
=
true
,
LOG
=
true
,
...
...
bt5/erp5_officejs_drone_simulator_test/PathTemplateItem/web_page_module/test_drone_simulator_flight_js.xml
View file @
d63ec839
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1014.552
02.15664.53026
</string>
</value>
<value>
<string>
1014.552
87.25371.8430
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
170913
0383.65
</float>
<float>
170913
6309.62
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment