[nav] exceeding_time on segment

Add an 'exceeding_time' attribute to 'go' and 'path' blocks that tells how
many seconds the plane should fly after the end of the segment before
completing it.
It is equivalent to giving a negative 'approaching_time' (and these two
attributes are of course not compatible with each other).
In addition some math functions in nav are forced to float.
This commit is contained in:
Gautier Hattenberger
2014-04-01 17:55:29 +02:00
parent 7d917974a4
commit 524205cbf8
3 changed files with 53 additions and 30 deletions
+2
View File
@@ -141,6 +141,7 @@ pitch CDATA #IMPLIED
alt CDATA #IMPLIED alt CDATA #IMPLIED
height CDATA #IMPLIED height CDATA #IMPLIED
approaching_time CDATA #IMPLIED approaching_time CDATA #IMPLIED
exceeding_time CDATA #IMPLIED
throttle CDATA #IMPLIED throttle CDATA #IMPLIED
climb CDATA #IMPLIED climb CDATA #IMPLIED
until CDATA #IMPLIED> until CDATA #IMPLIED>
@@ -151,6 +152,7 @@ vmode CDATA #IMPLIED
pitch CDATA #IMPLIED pitch CDATA #IMPLIED
alt CDATA #IMPLIED alt CDATA #IMPLIED
approaching_time CDATA #IMPLIED approaching_time CDATA #IMPLIED
exceeding_time CDATA #IMPLIED
throttle CDATA #IMPLIED throttle CDATA #IMPLIED
climb CDATA #IMPLIED> climb CDATA #IMPLIED>
+43 -29
View File
@@ -109,7 +109,7 @@ void nav_init_stage( void ) {
void nav_circle_XY(float x, float y, float radius) { void nav_circle_XY(float x, float y, float radius) {
struct EnuCoor_f* pos = stateGetPositionEnu_f(); struct EnuCoor_f* pos = stateGetPositionEnu_f();
float last_trigo_qdr = nav_circle_trigo_qdr; float last_trigo_qdr = nav_circle_trigo_qdr;
nav_circle_trigo_qdr = atan2(pos->y - y, pos->x - x); nav_circle_trigo_qdr = atan2f(pos->y - y, pos->x - x);
float sign_radius = radius > 0 ? 1 : -1; float sign_radius = radius > 0 ? 1 : -1;
if (nav_in_circle) { if (nav_in_circle) {
@@ -133,7 +133,7 @@ void nav_circle_XY(float x, float y, float radius) {
(dist2_center > Square(abs_radius + dist_carrot) (dist2_center > Square(abs_radius + dist_carrot)
|| dist2_center < Square(abs_radius - dist_carrot)) ? || dist2_center < Square(abs_radius - dist_carrot)) ?
0 : 0 :
atan((*stateGetHorizontalSpeedNorm_f())*(*stateGetHorizontalSpeedNorm_f()) / (NAV_GRAVITY*radius)); atanf((*stateGetHorizontalSpeedNorm_f())*(*stateGetHorizontalSpeedNorm_f()) / (NAV_GRAVITY*radius));
float carrot_angle = dist_carrot / abs_radius; float carrot_angle = dist_carrot / abs_radius;
carrot_angle = Min(carrot_angle, M_PI/4); carrot_angle = Min(carrot_angle, M_PI/4);
@@ -142,10 +142,10 @@ void nav_circle_XY(float x, float y, float radius) {
horizontal_mode = HORIZONTAL_MODE_CIRCLE; horizontal_mode = HORIZONTAL_MODE_CIRCLE;
float radius_carrot = abs_radius; float radius_carrot = abs_radius;
if (nav_mode == NAV_MODE_COURSE) { if (nav_mode == NAV_MODE_COURSE) {
radius_carrot += (abs_radius / cos(carrot_angle) - abs_radius); radius_carrot += (abs_radius / cosf(carrot_angle) - abs_radius);
} }
fly_to_xy(x+cos(alpha_carrot)*radius_carrot, fly_to_xy(x+cosf(alpha_carrot)*radius_carrot,
y+sin(alpha_carrot)*radius_carrot); y+sinf(alpha_carrot)*radius_carrot);
nav_in_circle = TRUE; nav_in_circle = TRUE;
nav_circle_x = x; nav_circle_x = x;
nav_circle_y = y; nav_circle_y = y;
@@ -226,14 +226,14 @@ static inline bool_t nav_compute_baseleg(uint8_t wp_af, uint8_t wp_td, uint8_t w
float y_0 = waypoints[wp_td].y - waypoints[wp_af].y; float y_0 = waypoints[wp_td].y - waypoints[wp_af].y;
/* Unit vector from AF to TD */ /* Unit vector from AF to TD */
float d = sqrt(x_0*x_0+y_0*y_0); float d = sqrtf(x_0*x_0+y_0*y_0);
float x_1 = x_0 / d; float x_1 = x_0 / d;
float y_1 = y_0 / d; float y_1 = y_0 / d;
waypoints[wp_baseleg].x = waypoints[wp_af].x + y_1 * nav_radius; waypoints[wp_baseleg].x = waypoints[wp_af].x + y_1 * nav_radius;
waypoints[wp_baseleg].y = waypoints[wp_af].y - x_1 * nav_radius; waypoints[wp_baseleg].y = waypoints[wp_af].y - x_1 * nav_radius;
waypoints[wp_baseleg].a = waypoints[wp_af].a; waypoints[wp_baseleg].a = waypoints[wp_af].a;
baseleg_out_qdr = M_PI - atan2(-y_1, -x_1); baseleg_out_qdr = M_PI - atan2f(-y_1, -x_1);
if (nav_radius < 0) if (nav_radius < 0)
baseleg_out_qdr += M_PI; baseleg_out_qdr += M_PI;
@@ -247,7 +247,7 @@ static inline bool_t nav_compute_final_from_glide(uint8_t wp_af, uint8_t wp_td,
float h_0 = waypoints[wp_td].a - waypoints[wp_af].a; float h_0 = waypoints[wp_td].a - waypoints[wp_af].a;
/* Unit vector from AF to TD */ /* Unit vector from AF to TD */
float d = sqrt(x_0*x_0+y_0*y_0); float d = sqrtf(x_0*x_0+y_0*y_0);
float x_1 = x_0 / d; float x_1 = x_0 / d;
float y_1 = y_0 / d; float y_1 = y_0 / d;
@@ -266,8 +266,8 @@ static inline bool_t compute_TOD(uint8_t _af, uint8_t _td, uint8_t _tod, float g
struct FloatVect2* wind = stateGetHorizontalWindspeed_f(); struct FloatVect2* wind = stateGetHorizontalWindspeed_f();
float td_af_x = WaypointX(_af) - WaypointX(_td); float td_af_x = WaypointX(_af) - WaypointX(_td);
float td_af_y = WaypointY(_af) - WaypointY(_td); float td_af_y = WaypointY(_af) - WaypointY(_td);
float td_af = sqrt( td_af_x*td_af_x + td_af_y*td_af_y); float td_af = sqrtf( td_af_x*td_af_x + td_af_y*td_af_y);
float td_tod = (WaypointAlt(_af) - WaypointAlt(_td)) / glide_vspeed * (glide_airspeed - sqrt(wind->x*wind->x + wind->y*wind->y)); float td_tod = (WaypointAlt(_af) - WaypointAlt(_td)) / glide_vspeed * (glide_airspeed - sqrtf(wind->x*wind->x + wind->y*wind->y));
WaypointX(_tod) = WaypointX(_td) + td_af_x / td_af * td_tod; WaypointX(_tod) = WaypointX(_td) + td_af_x / td_af * td_tod;
WaypointY(_tod) = WaypointY(_td) + td_af_y / td_af * td_tod; WaypointY(_tod) = WaypointY(_td) + td_af_y / td_af * td_tod;
WaypointAlt(_tod) = WaypointAlt(_af); WaypointAlt(_tod) = WaypointAlt(_af);
@@ -292,7 +292,7 @@ static inline void nav_follow(uint8_t _ac_id, float _distance, float _height) {
NavVerticalAutoThrottleMode(0.); NavVerticalAutoThrottleMode(0.);
NavVerticalAltitudeMode(Max(ac->alt + _height, ground_alt+SECURITY_HEIGHT), 0.); NavVerticalAltitudeMode(Max(ac->alt + _height, ground_alt+SECURITY_HEIGHT), 0.);
float alpha = M_PI/2 - ac->course; float alpha = M_PI/2 - ac->course;
float ca = cos(alpha), sa = sin(alpha); float ca = cosf(alpha), sa = sinf(alpha);
float x = ac->east - _distance*ca; float x = ac->east - _distance*ca;
float y = ac->north - _distance*sa; float y = ac->north - _distance*sa;
fly_to_xy(x, y); fly_to_xy(x, y);
@@ -314,7 +314,10 @@ float fp_pitch; /* deg */
* Computes \a dist2_to_wp and compare it to square \a carrot. * Computes \a dist2_to_wp and compare it to square \a carrot.
* Return true if it is smaller. Else computes by scalar products if * Return true if it is smaller. Else computes by scalar products if
* uav has not gone past waypoint. * uav has not gone past waypoint.
* Return true if it is the case. * \a approaching_time can be negative and in this case, the UAV will
* fly after the waypoint for the given number of seconds.
*
* @return true if the position (x, y) is reached
*/ */
bool_t nav_approaching_xy(float x, float y, float from_x, float from_y, float approaching_time) { bool_t nav_approaching_xy(float x, float y, float from_x, float from_y, float approaching_time) {
/** distance to waypoint in x */ /** distance to waypoint in x */
@@ -322,14 +325,25 @@ bool_t nav_approaching_xy(float x, float y, float from_x, float from_y, float ap
/** distance to waypoint in y */ /** distance to waypoint in y */
float pw_y = y - stateGetPositionEnu_f()->y; float pw_y = y - stateGetPositionEnu_f()->y;
dist2_to_wp = pw_x*pw_x + pw_y *pw_y; if (approaching_time < 0.) {
float min_dist = approaching_time * (*stateGetHorizontalSpeedNorm_f()); // fly after the destination waypoint
if (dist2_to_wp < min_dist*min_dist) float leg_x = x - from_x;
return TRUE; float leg_y = y - from_y;
float leg = sqrtf(Max(leg_x * leg_x + leg_y * leg_y, 1.));
float scal_prod = (x - from_x) * pw_x + (y - from_y) * pw_y; float exceed_dist = approaching_time * (*stateGetHorizontalSpeedNorm_f()); // negative value
float scal_prod = (leg_x * pw_x + leg_y * pw_y) / leg;
return (scal_prod < 0.); return (scal_prod < exceed_dist);
}
else {
// fly close enough of the waypoint or cross it
dist2_to_wp = pw_x*pw_x + pw_y *pw_y;
float min_dist = approaching_time * (*stateGetHorizontalSpeedNorm_f());
if (dist2_to_wp < min_dist*min_dist) {
return TRUE;
}
float scal_prod = (x - from_x) * pw_x + (y - from_y) * pw_y;
return (scal_prod < 0.);
}
} }
@@ -342,17 +356,17 @@ void fly_to_xy(float x, float y) {
desired_x = x; desired_x = x;
desired_y = y; desired_y = y;
if (nav_mode == NAV_MODE_COURSE) { if (nav_mode == NAV_MODE_COURSE) {
h_ctl_course_setpoint = atan2(x - pos->x, y - pos->y); h_ctl_course_setpoint = atan2f(x - pos->x, y - pos->y);
if (h_ctl_course_setpoint < 0.) if (h_ctl_course_setpoint < 0.)
h_ctl_course_setpoint += 2 * M_PI; h_ctl_course_setpoint += 2 * M_PI;
lateral_mode = LATERAL_MODE_COURSE; lateral_mode = LATERAL_MODE_COURSE;
} else { } else {
float diff = atan2(x - pos->x, y - pos->y) - (*stateGetHorizontalSpeedDir_f()); float diff = atan2f(x - pos->x, y - pos->y) - (*stateGetHorizontalSpeedDir_f());
NormRadAngle(diff); NormRadAngle(diff);
BoundAbs(diff,M_PI/2.); BoundAbs(diff,M_PI/2.);
float s = sin(diff); float s = sinf(diff);
float speed = *stateGetHorizontalSpeedNorm_f(); float speed = *stateGetHorizontalSpeedNorm_f();
h_ctl_roll_setpoint = atan(2 * speed * speed * s * h_ctl_course_pgain / (CARROT * NOMINAL_AIRSPEED * 9.81) ); h_ctl_roll_setpoint = atanf(2 * speed * speed * s * h_ctl_course_pgain / (CARROT * NOMINAL_AIRSPEED * 9.81) );
BoundAbs(h_ctl_roll_setpoint, h_ctl_roll_max_setpoint); BoundAbs(h_ctl_roll_setpoint, h_ctl_roll_max_setpoint);
lateral_mode = LATERAL_MODE_ROLL; lateral_mode = LATERAL_MODE_ROLL;
} }
@@ -366,7 +380,7 @@ void nav_route_xy(float last_wp_x, float last_wp_y, float wp_x, float wp_y) {
float leg_y = wp_y - last_wp_y; float leg_y = wp_y - last_wp_y;
float leg2 = Max(leg_x * leg_x + leg_y * leg_y, 1.); float leg2 = Max(leg_x * leg_x + leg_y * leg_y, 1.);
nav_leg_progress = ((stateGetPositionEnu_f()->x - last_wp_x) * leg_x + (stateGetPositionEnu_f()->y - last_wp_y) * leg_y) / leg2; nav_leg_progress = ((stateGetPositionEnu_f()->x - last_wp_x) * leg_x + (stateGetPositionEnu_f()->y - last_wp_y) * leg_y) / leg2;
nav_leg_length = sqrt(leg2); nav_leg_length = sqrtf(leg2);
/** distance of carrot (in meter) */ /** distance of carrot (in meter) */
float carrot = CARROT * NOMINAL_AIRSPEED; float carrot = CARROT * NOMINAL_AIRSPEED;
@@ -548,7 +562,7 @@ void nav_eight(uint8_t target, uint8_t c1, float radius) {
float target_c1_x = waypoints[c1].x - waypoints[target].x; float target_c1_x = waypoints[c1].x - waypoints[target].x;
float target_c1_y = waypoints[c1].y - waypoints[target].y; float target_c1_y = waypoints[c1].y - waypoints[target].y;
float d = sqrt(target_c1_x*target_c1_x+target_c1_y*target_c1_y); float d = sqrtf(target_c1_x*target_c1_x+target_c1_y*target_c1_y);
d = Max(d, 1.); /* To prevent a division by zero */ d = Max(d, 1.); /* To prevent a division by zero */
/* Unit vector from target to c1 */ /* Unit vector from target to c1 */
@@ -586,7 +600,7 @@ void nav_eight(uint8_t target, uint8_t c1, float radius) {
c2.y - radius * u_x, c2.y - radius * u_x,
alt }; alt };
float qdr_out = M_PI - atan2(u_y, u_x); float qdr_out = M_PI - atan2f(u_y, u_x);
if (radius < 0) if (radius < 0)
qdr_out += M_PI; qdr_out += M_PI;
@@ -670,7 +684,7 @@ void nav_oval(uint8_t p1, uint8_t p2, float radius) {
float p2_p1_x = waypoints[p1].x - waypoints[p2].x; float p2_p1_x = waypoints[p1].x - waypoints[p2].x;
float p2_p1_y = waypoints[p1].y - waypoints[p2].y; float p2_p1_y = waypoints[p1].y - waypoints[p2].y;
float d = sqrt(p2_p1_x*p2_p1_x+p2_p1_y*p2_p1_y); float d = sqrtf(p2_p1_x*p2_p1_x+p2_p1_y*p2_p1_y);
/* Unit vector from p1 to p2 */ /* Unit vector from p1 to p2 */
float u_x = p2_p1_x / d; float u_x = p2_p1_x / d;
@@ -691,7 +705,7 @@ void nav_oval(uint8_t p1, uint8_t p2, float radius) {
waypoints[p2].y + radius * u_x, waypoints[p2].y + radius * u_x,
alt }; alt };
float qdr_out_2 = M_PI - atan2(u_y, u_x); float qdr_out_2 = M_PI - atan2f(u_y, u_x);
float qdr_out_1 = qdr_out_2 + M_PI; float qdr_out_1 = qdr_out_2 + M_PI;
if (radius < 0) { if (radius < 0) {
qdr_out_2 += M_PI; qdr_out_2 += M_PI;
+8 -1
View File
@@ -363,7 +363,14 @@ let rec print_stage = fun index_of_waypoints x ->
lprintf "waypoints[0].y = %s;\n" (parsed_attrib x "y"); lprintf "waypoints[0].y = %s;\n" (parsed_attrib x "y");
"0" "0"
in in
let at = try ExtXml.attrib x "approaching_time" with _ -> "CARROT" in let at = try Some (ExtXml.attrib x "approaching_time") with _ -> None in
let et = try Some (ExtXml.attrib x "exceeding_time") with _ -> None in
let at = match at, et with
| Some a, None -> a
| None, Some e -> "-"^e
| None, None -> "CARROT"
| _, _ -> failwith "Error: 'approaching_time' and 'exceeding_time' attributes are not compatible"
in
let last_wp = let last_wp =
try try
get_index_waypoint (ExtXml.attrib x "from") index_of_waypoints get_index_waypoint (ExtXml.attrib x "from") index_of_waypoints