forked from ArduPilot/ardupilot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mode_smart_rtl.cpp
91 lines (81 loc) · 3.17 KB
/
mode_smart_rtl.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "mode.h"
#include "Rover.h"
bool ModeSmartRTL::_enter()
{
// SmartRTL requires EKF (not DCM)
Location ekf_origin;
if (!ahrs.get_origin(ekf_origin)) {
return false;
}
// refuse to enter SmartRTL if smart RTL's home has not been set
if (!g2.smart_rtl.is_active()) {
return false;
}
// initialise waypoint speed
set_desired_speed_to_default(true);
// init location target
set_desired_location(rover.current_loc);
// init state
smart_rtl_state = SmartRTL_WaitForPathCleanup;
_reached_destination = false;
return true;
}
void ModeSmartRTL::update()
{
switch (smart_rtl_state) {
case SmartRTL_WaitForPathCleanup:
// check if return path is computed and if yes, begin journey home
if (g2.smart_rtl.request_thorough_cleanup()) {
smart_rtl_state = SmartRTL_PathFollow;
_load_point = true;
}
// Note: this may lead to an unnecessary 20ms slow down of the vehicle (but it is unlikely)
stop_vehicle();
break;
case SmartRTL_PathFollow:
// load point if required
if (_load_point) {
Vector3f next_point;
if (!g2.smart_rtl.pop_point(next_point)) {
// if not more points, we have reached home
gcs().send_text(MAV_SEVERITY_INFO, "Reached destination");
smart_rtl_state = SmartRTL_StopAtHome;
break;
}
_load_point = false;
// set target destination to new point
if (!set_desired_location_NED(next_point)) {
// this failure should never happen but we add it just in case
gcs().send_text(MAV_SEVERITY_INFO, "SmartRTL: failed to set destination");
smart_rtl_state = SmartRTL_Failure;
}
}
// check if we've reached the next point
_distance_to_destination = get_distance(rover.current_loc, _destination);
if (_distance_to_destination <= rover.g.waypoint_radius || location_passed_point(rover.current_loc, _origin, _destination)) {
_load_point = true;
}
// continue driving towards destination
calc_steering_to_waypoint(_origin, _destination);
calc_throttle(calc_reduced_speed_for_turn_or_distance(_desired_speed), true, false);
break;
case SmartRTL_StopAtHome:
case SmartRTL_Failure:
_reached_destination = true;
if (rover.is_boat()) {
// boats attempt to hold position at home
calc_steering_to_waypoint(rover.current_loc, _destination);
calc_throttle(calc_reduced_speed_for_turn_or_distance(_desired_speed), true, false);
} else {
// rovers stop
stop_vehicle();
}
break;
}
}
// save current position for use by the smart_rtl flight mode
void ModeSmartRTL::save_position()
{
const bool save_pos = (rover.control_mode != &rover.mode_smartrtl);
g2.smart_rtl.update(true, save_pos);
}