2019-01-15 13:46:13 -04:00
|
|
|
#include "mode.h"
|
|
|
|
#include "Plane.h"
|
|
|
|
|
|
|
|
bool ModeCruise::_enter()
|
|
|
|
{
|
2020-08-03 15:22:00 -03:00
|
|
|
locked_heading = false;
|
|
|
|
lock_timer_ms = 0;
|
2019-01-15 13:46:13 -04:00
|
|
|
|
2020-09-23 05:16:45 -03:00
|
|
|
#if HAL_SOARING_ENABLED
|
2019-01-15 13:46:13 -04:00
|
|
|
// for ArduSoar soaring_controller
|
|
|
|
plane.g2.soaring_controller.init_cruising();
|
2019-04-07 18:56:08 -03:00
|
|
|
#endif
|
2019-01-15 13:46:13 -04:00
|
|
|
|
|
|
|
plane.set_target_altitude_current();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ModeCruise::update()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
in CRUISE mode we use the navigation code to control
|
|
|
|
roll when heading is locked. Heading becomes unlocked on
|
|
|
|
any aileron or rudder input
|
|
|
|
*/
|
|
|
|
if (plane.channel_roll->get_control_in() != 0 || plane.channel_rudder->get_control_in() != 0) {
|
2020-08-03 15:22:00 -03:00
|
|
|
locked_heading = false;
|
|
|
|
lock_timer_ms = 0;
|
2019-01-15 13:46:13 -04:00
|
|
|
}
|
|
|
|
|
2022-10-25 05:21:14 -03:00
|
|
|
#if AP_SCRIPTING_ENABLED
|
2022-10-26 19:50:10 -03:00
|
|
|
if (plane.nav_scripting_active()) {
|
2022-10-25 05:21:14 -03:00
|
|
|
// while a trick is running unlock heading and zero altitude offset
|
|
|
|
locked_heading = false;
|
|
|
|
lock_timer_ms = 0;
|
|
|
|
plane.set_target_altitude_current();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-08-03 15:22:00 -03:00
|
|
|
if (!locked_heading) {
|
2019-01-15 13:46:13 -04:00
|
|
|
plane.nav_roll_cd = plane.channel_roll->norm_input() * plane.roll_limit_cd;
|
|
|
|
plane.update_load_factor();
|
|
|
|
} else {
|
|
|
|
plane.calc_nav_roll();
|
|
|
|
}
|
|
|
|
plane.update_fbwb_speed_height();
|
|
|
|
}
|
|
|
|
|
2020-07-29 12:01:34 -03:00
|
|
|
/*
|
|
|
|
handle CRUISE mode, locking heading to GPS course when we have
|
|
|
|
sufficient ground speed, and no aileron or rudder input
|
|
|
|
*/
|
2020-08-19 04:51:00 -03:00
|
|
|
void ModeCruise::navigate()
|
2020-07-29 12:01:34 -03:00
|
|
|
{
|
2022-10-25 05:21:14 -03:00
|
|
|
#if AP_SCRIPTING_ENABLED
|
2022-10-26 19:50:10 -03:00
|
|
|
if (plane.nav_scripting_active()) {
|
2022-10-25 05:21:14 -03:00
|
|
|
// don't try to navigate while running trick
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
2020-08-03 15:22:00 -03:00
|
|
|
if (!locked_heading &&
|
2020-07-29 12:01:34 -03:00
|
|
|
plane.channel_roll->get_control_in() == 0 &&
|
|
|
|
plane.rudder_input() == 0 &&
|
|
|
|
plane.gps.status() >= AP_GPS::GPS_OK_FIX_2D &&
|
|
|
|
plane.gps.ground_speed() >= 3 &&
|
2020-08-03 15:22:00 -03:00
|
|
|
lock_timer_ms == 0) {
|
2020-07-29 12:01:34 -03:00
|
|
|
// user wants to lock the heading - start the timer
|
2020-08-03 15:22:00 -03:00
|
|
|
lock_timer_ms = millis();
|
2020-07-29 12:01:34 -03:00
|
|
|
}
|
2020-08-03 15:22:00 -03:00
|
|
|
if (lock_timer_ms != 0 &&
|
|
|
|
(millis() - lock_timer_ms) > 500) {
|
2020-07-29 12:01:34 -03:00
|
|
|
// lock the heading after 0.5 seconds of zero heading input
|
|
|
|
// from user
|
2020-08-03 15:22:00 -03:00
|
|
|
locked_heading = true;
|
|
|
|
lock_timer_ms = 0;
|
|
|
|
locked_heading_cd = plane.gps.ground_course_cd();
|
2020-07-29 12:01:34 -03:00
|
|
|
plane.prev_WP_loc = plane.current_loc;
|
|
|
|
}
|
2020-08-03 15:22:00 -03:00
|
|
|
if (locked_heading) {
|
2020-07-29 12:01:34 -03:00
|
|
|
plane.next_WP_loc = plane.prev_WP_loc;
|
|
|
|
// always look 1km ahead
|
2020-08-03 15:22:00 -03:00
|
|
|
plane.next_WP_loc.offset_bearing(locked_heading_cd*0.01f, plane.prev_WP_loc.get_distance(plane.current_loc) + 1000);
|
2020-07-29 12:01:34 -03:00
|
|
|
plane.nav_controller->update_waypoint(plane.prev_WP_loc, plane.next_WP_loc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-01 12:26:22 -04:00
|
|
|
bool ModeCruise::get_target_heading_cd(int32_t &target_heading) const
|
2020-08-03 15:22:00 -03:00
|
|
|
{
|
|
|
|
target_heading = locked_heading_cd;
|
|
|
|
return locked_heading;
|
|
|
|
}
|