// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- /* * logic for dealing with the current command in the mission and home location */ static int32_t read_alt_to_hold() { if (g.RTL_altitude_cm < 0) { return current_loc.alt; } return g.RTL_altitude_cm + home.alt; } /* * This function stores waypoint commands * It looks to see what the next command type is and finds the last command. */ static void set_next_WP(const AP_Mission::Mission_Command& cmd) { // copy the current WP into the OldWP slot // --------------------------------------- prev_WP = next_WP; // Load the next_WP slot // --------------------- next_WP = cmd; // if lat and lon is zero, then use current lat/lon // this allows a mission to contain a "loiter on the spot" // command if (next_WP.content.location.lat == 0 && next_WP.content.location.lng == 0) { next_WP.content.location.lat = current_loc.lat; next_WP.content.location.lng = current_loc.lng; // additionally treat zero altitude as current altitude if (next_WP.content.location.alt == 0) { next_WP.content.location.alt = current_loc.alt; next_WP.content.location.flags.relative_alt = false; } } // convert relative alt to absolute alt if (next_WP.content.location.flags.relative_alt) { next_WP.content.location.flags.relative_alt = false; next_WP.content.location.alt += home.alt; } // are we already past the waypoint? This happens when we jump // waypoints, and it can cause us to skip a waypoint. If we are // past the waypoint when we start on a leg, then use the current // location as the previous waypoint, to prevent immediately // considering the waypoint complete if (location_passed_point(current_loc, prev_WP.content.location, next_WP.content.location)) { gcs_send_text_P(SEVERITY_LOW, PSTR("Resetting prev_WP")); prev_WP.content.location = current_loc; } // used to control FBW and limit the rate of climb // ----------------------------------------------- target_altitude_cm = current_loc.alt; // zero out our loiter vals to watch for missed waypoints loiter_angle_reset(); setup_glide_slope(); loiter_angle_reset(); } static void set_guided_WP(void) { if (g.loiter_radius < 0) { loiter.direction = -1; } else { loiter.direction = 1; } // copy the current location into the OldWP slot // --------------------------------------- prev_WP.content.location = current_loc; // Load the next_WP slot // --------------------- next_WP.content.location = guided_WP; // used to control FBW and limit the rate of climb // ----------------------------------------------- target_altitude_cm = current_loc.alt; setup_glide_slope(); loiter_angle_reset(); } // run this at setup on the ground // ------------------------------- static void init_home() { gcs_send_text_P(SEVERITY_LOW, PSTR("init home")); // block until we get a good fix // ----------------------------- while (!g_gps->new_data || !g_gps->fix) { g_gps->update(); #if HIL_MODE != HIL_MODE_DISABLED // update hil gps so we have new_data gcs_update(); #endif } ahrs.set_home(g_gps->latitude, g_gps->longitude, g_gps->altitude_cm); home_is_set = true; gcs_send_text_fmt(PSTR("gps alt: %lu"), (unsigned long)home.alt); // Save Home to EEPROM mission.write_home_to_storage(); // Save prev loc // ------------- next_WP.content.location = prev_WP.content.location = home; // Load home for a default guided_WP // ------------- guided_WP = home; guided_WP.alt += g.RTL_altitude_cm; } /* update home location from GPS this is called as long as we have 3D lock and the arming switch is not pushed */ static void update_home() { ahrs.set_home(g_gps->latitude, g_gps->longitude, g_gps->altitude_cm); barometer.update_calibration(); }