diff --git a/conf/flight_plans/fixedwing_demo_takeoff_land.xml b/conf/flight_plans/fixedwing_demo_takeoff_land.xml index 73809db45b..7975f460a0 100644 --- a/conf/flight_plans/fixedwing_demo_takeoff_land.xml +++ b/conf/flight_plans/fixedwing_demo_takeoff_land.xml @@ -36,7 +36,7 @@ - + diff --git a/conf/flight_plans/rotorcraft_demo_takeoff_land.xml b/conf/flight_plans/rotorcraft_demo_takeoff_land.xml index 88c9b30764..b9214b35dc 100644 --- a/conf/flight_plans/rotorcraft_demo_takeoff_land.xml +++ b/conf/flight_plans/rotorcraft_demo_takeoff_land.xml @@ -35,7 +35,7 @@ - + diff --git a/sw/airborne/modules/nav/nav_takeoff_and_landing.h b/sw/airborne/modules/nav/nav_takeoff_and_landing.h index eeb2069731..8e6249054b 100644 --- a/sw/airborne/modules/nav/nav_takeoff_and_landing.h +++ b/sw/airborne/modules/nav/nav_takeoff_and_landing.h @@ -86,9 +86,10 @@ extern void nav_takeoff_and_landing_periodic(void); * - rotorcraft: set the wp at current location and climb verticaly * * @param[in] wp_id waypoint ID + * @param[in] height height in meters for ending takeoff procedure (<0 to use default value) * @return true until procedure is completed */ -extern bool nav_takeoff_from_wp(uint8_t wp_id); +extern bool nav_takeoff_from_wp(uint8_t wp_id, float height); /** Takeoff from lat long location * @@ -97,18 +98,20 @@ extern bool nav_takeoff_from_wp(uint8_t wp_id); * * @param[in] lat takeoff latitude (deg) * @param[in] lon takeoff longitude (deg) + * @param[in] height height in meters for ending takeoff procedure (<0 to use default value) * @return true until procedure is completed */ -extern bool nav_takeoff_from_loc(float lat, float lon); +extern bool nav_takeoff_from_loc(float lat, float lon, float height); /** Takeoff from current location * * - fixedwing: climb direction is specified with setting * - rotorcraft: start from current location and climb verticaly * + * @param[in] height height in meters for ending takeoff procedure (<0 to use default value) * @return true until procedure is completed */ -extern bool nav_takeoff_from_here(void); +extern bool nav_takeoff_from_here(float height); /** Land at waypoint location * diff --git a/sw/airborne/modules/nav/nav_takeoff_and_landing_fw.c b/sw/airborne/modules/nav/nav_takeoff_and_landing_fw.c index 4f95a784be..02697df4e7 100644 --- a/sw/airborne/modules/nav/nav_takeoff_and_landing_fw.c +++ b/sw/airborne/modules/nav/nav_takeoff_and_landing_fw.c @@ -76,9 +76,10 @@ float nav_takeoff_direction; static bool nav_takeoff_mission(uint8_t nb UNUSED, float *params UNUSED, enum MissionRunFlag flag) { - if (flag == MissionInit) { + if (flag == MissionInit && nb == 1) { + float height = params[0]; takeoff.status = NAV_TAKEOFF_INIT; - return nav_takeoff_from_here(); + return nav_takeoff_from_here(height); } else if (flag == MissionRun) { return nav_takeoff_run(); @@ -175,7 +176,7 @@ static bool nav_takeoff_run(void) { NavVerticalAutoThrottleMode(RadOfDeg(NAV_TAKEOFF_PITCH)); NavVerticalThrottleMode(TRIM_UPPRZ(MAX_PPRZ*NAV_TAKEOFF_THROTTLE)); if (nav_approaching_xy(takeoff.climb_pos.x, takeoff.climb_pos.y, takeoff.start_pos.x, takeoff.start_pos.y, CARROT) - || (stateGetPositionEnu_f()->z > takeoff.start_pos.z + NAV_TAKEOFF_HEIGHT)) { + || (stateGetPositionEnu_f()->z - takeoff.start_pos.z > takeoff.climb_pos.z)) { // end when climb point or target alt is reached takeoff.status = NAV_TAKEOFF_DONE; } @@ -188,39 +189,53 @@ static bool nav_takeoff_run(void) { return true; } -bool nav_takeoff_from_wp(uint8_t wp_id) +bool nav_takeoff_from_wp(uint8_t wp_id, float height) { if (takeoff.status == NAV_TAKEOFF_INIT) { + takeoff.start_pos = *stateGetPositionEnu_f(); takeoff.climb_id = wp_id; takeoff.climb_pos.x = WaypointX(wp_id); takeoff.climb_pos.y = WaypointY(wp_id); - takeoff.climb_pos.z = WaypointAlt(wp_id) - GetAltRef(); - takeoff.start_pos = *stateGetPositionEnu_f(); + if (height < 0.f) { + takeoff.climb_pos.z = takeoff.start_pos.z + NAV_TAKEOFF_HEIGHT; + } else { + takeoff.climb_pos.z = takeoff.start_pos.z + height; + } } return nav_takeoff_run(); } -bool nav_takeoff_from_loc(float lat, float lon) +bool nav_takeoff_from_loc(float lat, float lon, float height) { if (takeoff.status == NAV_TAKEOFF_INIT) { - struct LlaCoor_f lla = { RadOfDeg(lat), RadOfDeg(lon), stateGetPositionLla_f()->alt + NAV_TAKEOFF_HEIGHT }; + takeoff.start_pos = *stateGetPositionEnu_f(); + float alt = stateGetPositionLla_f()->alt; + if (height < 0.f) { + alt += NAV_TAKEOFF_HEIGHT; + } else { + alt += height; + } + struct LlaCoor_f lla = { RadOfDeg(lat), RadOfDeg(lon), alt }; struct UtmCoor_f utm; utm_of_lla_f(&utm, &lla); ENU_OF_UTM_DIFF(takeoff.climb_pos, utm, *stateGetUtmOrigin_f()); } - return nav_takeoff_from_here(); + return nav_takeoff_run(); } -bool nav_takeoff_from_here(void) +bool nav_takeoff_from_here(float height) { if (takeoff.status == NAV_TAKEOFF_INIT) { takeoff.climb_id = 0; takeoff.start_pos = *stateGetPositionEnu_f(); - takeoff.climb_pos = takeoff.start_pos; takeoff.climb_pos.x = takeoff.start_pos.x + NAV_TAKEOFF_DIST * sinf(RadOfDeg(nav_takeoff_direction)); takeoff.climb_pos.y = takeoff.start_pos.y + NAV_TAKEOFF_DIST * cosf(RadOfDeg(nav_takeoff_direction)); - takeoff.climb_pos.z = takeoff.start_pos.z + NAV_TAKEOFF_HEIGHT; + if (height < 0.f) { + takeoff.climb_pos.z = takeoff.start_pos.z + NAV_TAKEOFF_HEIGHT; + } else { + takeoff.climb_pos.z = takeoff.start_pos.z + height; + } } return nav_takeoff_run(); diff --git a/sw/airborne/modules/nav/nav_takeoff_and_landing_rotorcraft.c b/sw/airborne/modules/nav/nav_takeoff_and_landing_rotorcraft.c index 6376088f22..292a6f865e 100644 --- a/sw/airborne/modules/nav/nav_takeoff_and_landing_rotorcraft.c +++ b/sw/airborne/modules/nav/nav_takeoff_and_landing_rotorcraft.c @@ -64,9 +64,10 @@ float nav_takeoff_direction; static bool nav_takeoff_mission(uint8_t nb UNUSED, float *params UNUSED, enum MissionRunFlag flag) { - if (flag == MissionInit) { + if (flag == MissionInit && nb == 1) { + float height = params[0]; takeoff.status = NAV_TAKEOFF_INIT; - return nav_takeoff_from_here(); + return nav_takeoff_from_here(height); } else if (flag == MissionRun) { return nav_takeoff_run(); @@ -157,7 +158,7 @@ static bool nav_takeoff_run(void) { autopilot_set_in_flight(true); NavGotoWaypoint(takeoff.climb_id); NavVerticalClimbMode(NAV_TAKEOFF_CLIMB_SPEED); - if (stateGetPositionEnu_f()->z - takeoff.start_pos.z > NAV_TAKEOFF_HEIGHT) { + if (stateGetPositionEnu_f()->z - takeoff.start_pos.z > takeoff.climb_pos.z) { // end when takeoff height is reached takeoff.status = NAV_TAKEOFF_DONE; } @@ -171,29 +172,39 @@ static bool nav_takeoff_run(void) { return true; } -bool nav_takeoff_from_wp(uint8_t wp_id) +bool nav_takeoff_from_wp(uint8_t wp_id, float height) { if (takeoff.status == NAV_TAKEOFF_INIT) { takeoff.climb_id = wp_id; waypoint_set_here_2d(wp_id); takeoff.climb_pos = *waypoint_get_enu_f(wp_id); takeoff.start_pos = *stateGetPositionEnu_f(); + if (height < 0.f) { + takeoff.climb_pos.z = takeoff.start_pos.z + NAV_TAKEOFF_HEIGHT; // default value + } else { + takeoff.climb_pos.z = takeoff.start_pos.z + height; + } } return nav_takeoff_run(); } -bool nav_takeoff_from_loc(float lat UNUSED, float lon UNUSED) +bool nav_takeoff_from_loc(float lat UNUSED, float lon UNUSED, float height) { - return nav_takeoff_from_here(); + return nav_takeoff_from_here(height); } -bool nav_takeoff_from_here(void) +bool nav_takeoff_from_here(float height) { if (takeoff.status == NAV_TAKEOFF_INIT) { takeoff.climb_id = 0; // use dummy hidden WP takeoff.start_pos = *stateGetPositionEnu_f(); takeoff.climb_pos = takeoff.start_pos; + if (height < 0.f) { + takeoff.climb_pos.z += NAV_TAKEOFF_HEIGHT; // default value + } else { + takeoff.climb_pos.z += height; + } waypoint_set_enu(0, &takeoff.climb_pos); }