diff --git a/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum.xml b/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum.xml index 89834b91ce..a8d5013f4f 100644 --- a/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum.xml +++ b/conf/airframes/examples/quadrotor_lisa_m_2_pwm_spektrum.xml @@ -196,6 +196,10 @@ +
+ +
+
diff --git a/sw/airborne/firmwares/rotorcraft/navigation.c b/sw/airborne/firmwares/rotorcraft/navigation.c index c9e0fc7539..ae345c8005 100644 --- a/sw/airborne/firmwares/rotorcraft/navigation.c +++ b/sw/airborne/firmwares/rotorcraft/navigation.c @@ -96,9 +96,13 @@ float flight_altitude; static inline void nav_set_altitude( void ); #define CLOSE_TO_WAYPOINT (15 << 8) -#define ARRIVED_AT_WAYPOINT (3 << 8) #define CARROT_DIST (12 << 8) +/** minimum horizontal distance to waypoint to mark as arrived */ +#ifndef ARRIVED_AT_WAYPOINT +#define ARRIVED_AT_WAYPOINT 3.0 +#endif + #if PERIODIC_TELEMETRY #include "subsystems/datalink/telemetry.h" @@ -295,36 +299,39 @@ bool_t nav_approaching_from(uint8_t wp_idx, uint8_t from_idx, int16_t approachin struct Int32Vect2 diff; struct EnuCoor_i* pos = stateGetPositionEnu_i(); - VECT2_DIFF(diff, waypoints[wp_idx], *pos); - INT32_VECT2_RSHIFT(diff, diff, INT32_POS_FRAC); - INT32_VECT2_NORM(dist_to_point, diff); - //printf("dist %d | %d %d\n", dist_to_point,diff.x,diff.y); - //fflush(stdout); - //if (dist_to_point < (ARRIVED_AT_WAYPOINT >> INT32_POS_FRAC)) return TRUE; - if (dist_to_point < (ARRIVED_AT_WAYPOINT >> INT32_POS_FRAC)) return TRUE; - - if (approaching_time >= 0) { + /* if an approaching_time is given, estimate diff after approching_time secs */ + if (approaching_time > 0) { struct Int32Vect2 estimated_pos; struct Int32Vect2 estimated_progress; - struct Int32Vect2 estimated_diff; - int32_t estimated_dist; struct EnuCoor_i* speed = stateGetSpeedEnu_i(); VECT2_SMUL(estimated_progress, *speed, approaching_time); INT32_VECT2_RSHIFT(estimated_progress, estimated_progress, (INT32_SPEED_FRAC - INT32_POS_FRAC)); VECT2_SUM(estimated_pos, *pos, estimated_progress); - VECT2_DIFF(estimated_diff, waypoints[wp_idx], estimated_pos); - - INT32_VECT2_RSHIFT(estimated_diff, estimated_diff, INT32_POS_FRAC); - INT32_VECT2_NORM(estimated_dist, estimated_diff); - if (estimated_dist < (ARRIVED_AT_WAYPOINT >> INT32_POS_FRAC)) return TRUE; - - if (from_idx > 0 && from_idx < NB_WAYPOINT) { - struct Int32Vect2 from_diff; - VECT2_DIFF(from_diff, waypoints[wp_idx], waypoints[from_idx]); - INT32_VECT2_RSHIFT(from_diff, from_diff, INT32_POS_FRAC); - return (estimated_diff.x * from_diff.x + estimated_diff.y * from_diff.y < 0); - } + VECT2_DIFF(diff, waypoints[wp_idx], estimated_pos); } + /* else use current position */ + else { + VECT2_DIFF(diff, waypoints[wp_idx], *pos); + } + /* compute distance of estimated/current pos to target wp + * distance with half metric precision (6.25 cm) + */ + INT32_VECT2_RSHIFT(diff, diff, INT32_POS_FRAC/2); + INT32_VECT2_NORM(dist_to_point, diff); + + /* return TRUE if we have arrived */ + if (dist_to_point < BFP_OF_REAL(ARRIVED_AT_WAYPOINT, INT32_POS_FRAC/2)) + return TRUE; + + /* if coming from a valid waypoint */ + if (from_idx > 0 && from_idx < NB_WAYPOINT) { + /* return TRUE if normal line at the end of the segment is crossed */ + struct Int32Vect2 from_diff; + VECT2_DIFF(from_diff, waypoints[wp_idx], waypoints[from_idx]); + INT32_VECT2_RSHIFT(from_diff, from_diff, INT32_POS_FRAC/2); + return (diff.x * from_diff.x + diff.y * from_diff.y < 0); + } + return FALSE; } @@ -336,15 +343,15 @@ bool_t nav_check_wp_time(uint8_t wp_idx, uint16_t stay_time) { static uint8_t wp_idx_last = 0; struct Int32Vect2 diff; - if(wp_idx_last != wp_idx) { + if (wp_idx_last != wp_idx) { wp_reached = FALSE; wp_idx_last = wp_idx; } VECT2_DIFF(diff, waypoints[wp_idx], *stateGetPositionEnu_i()); - INT32_VECT2_RSHIFT(diff, diff, INT32_POS_FRAC); + INT32_VECT2_RSHIFT(diff, diff, INT32_POS_FRAC/2); INT32_VECT2_NORM(dist_to_point, diff); - if (dist_to_point < (ARRIVED_AT_WAYPOINT >> INT32_POS_FRAC)){ - if(!wp_reached) { + if (dist_to_point < BFP_OF_REAL(ARRIVED_AT_WAYPOINT, INT32_POS_FRAC/2)){ + if (!wp_reached) { wp_reached = TRUE; wp_entry_time = autopilot_flight_time; time_at_wp = 0;