#include "Rover.h"
#if MODE_FOLLOW_ENABLED
bool ModeFollow::_enter()
{
if (!g2.follow.enabled()) {
return false;
}
_desired_speed = g2.wp_nav.get_default_speed();
return true;
}
void ModeFollow::_exit()
{
g2.follow.clear_offsets_if_required();
}
void ModeFollow::update()
{
float speed;
if (!attitude_control.get_forward_speed(speed)) {
g2.motors.set_throttle(0.0f);
g2.motors.set_steering(0.0f);
return;
}
Vector3f dist_vec;
Vector3f dist_vec_offs;
Vector3f vel_of_target;
if (!g2.follow.get_target_dist_and_vel_NED_m(dist_vec, dist_vec_offs, vel_of_target)) {
_reached_destination = true;
stop_vehicle();
return;
}
Vector2f desired_velocity_ne;
const float kp = g2.follow.get_pos_p().kP();
desired_velocity_ne.x = vel_of_target.x + (dist_vec_offs.x * kp);
desired_velocity_ne.y = vel_of_target.y + (dist_vec_offs.y * kp);
if (desired_velocity_ne.length() < 0.03f) {
_reached_destination = true;
stop_vehicle();
return;
}
if (vel_of_target.length() < 0.03f && dist_vec_offs.length() < g2.turn_radius) {
_reached_destination = true;
stop_vehicle();
return;
}
_reached_destination = false;
float desired_speed = safe_sqrt(sq(desired_velocity_ne.x) + sq(desired_velocity_ne.y));
if (!is_zero(desired_speed) && (desired_speed > _desired_speed)) {
const float scalar_xy = _desired_speed / desired_speed;
desired_velocity_ne *= scalar_xy;
desired_speed = _desired_speed;
}
const float desired_yaw_cd = wrap_180_cd(rad_to_cd(atan2f(desired_velocity_ne.y, desired_velocity_ne.x)));
calc_steering_to_heading(desired_yaw_cd);
calc_throttle(desired_speed, true);
}
float ModeFollow::wp_bearing() const
{
return g2.follow.get_bearing_to_target_deg();
}
float ModeFollow::get_distance_to_destination() const
{
return g2.follow.get_distance_to_target_m();
}
bool ModeFollow::set_desired_speed(float speed)
{
if (is_negative(speed)) {
return false;
}
_desired_speed = speed;
return true;
}
#endif