/// advance_current_nav_cmd - moves current nav command forward /// do command will also be loaded /// accounts for do-jump commands // returns true if command is advanced, false if failed (i.e. mission completed) bool AP_Mission::advance_current_nav_cmd() { Mission_Command cmd; uint16_t cmd_index; // exit immediately if we're not running if (_flags.state != MISSION_RUNNING) { return false; } // exit immediately if current nav command has not completed if (_flags.nav_cmd_loaded) { return false; } // stop the current running do command _do_cmd.index = AP_MISSION_CMD_INDEX_NONE; _flags.do_cmd_loaded = false; _flags.do_cmd_all_done = false; // get starting point for search cmd_index = _nav_cmd.index; if (cmd_index == AP_MISSION_CMD_INDEX_NONE) { // start from beginning of the mission command list cmd_index = AP_MISSION_FIRST_REAL_COMMAND; }else{ // start from one position past the current nav command cmd_index++; } // search until we find next nav command or reach end of command list while (!_flags.nav_cmd_loaded) { // get next command if (!get_next_cmd(cmd_index, cmd, true)) { return false; } // check if navigation or "do" command if (is_nav_cmd(cmd)) { // save previous nav command index _prev_nav_cmd_index = _nav_cmd.index; // set current navigation command and start it _nav_cmd = cmd; _flags.nav_cmd_loaded = true; _cmd_start_fn(_nav_cmd); }else{ // set current do command and start it (if not already set) if (!_flags.do_cmd_loaded) { _do_cmd = cmd; _flags.do_cmd_loaded = true; _cmd_start_fn(_do_cmd); } } // move onto next command cmd_index = cmd.index+1; } // if we got this far we must have successfully advanced the nav command return true; }
/// get_next_nav_cmd - gets next "navigation" command found at or after start_index /// returns true if found, false if not found (i.e. reached end of mission command list) /// accounts for do_jump commands but never increments the jump's num_times_run (advance_current_nav_cmd is responsible for this) bool AP_Mission::get_next_nav_cmd(uint16_t start_index, Mission_Command& cmd) { uint16_t cmd_index = start_index; Mission_Command temp_cmd; // search until the end of the mission command list while(cmd_index < (unsigned)_cmd_total) { // get next command if (!get_next_cmd(cmd_index, temp_cmd, false)) { // no more commands so return failure return false; }else{ // if found a "navigation" command then return it if (is_nav_cmd(temp_cmd)) { cmd = temp_cmd; return true; }else{ // move on in list cmd_index++; } } } // if we got this far we did not find a navigation command return false; }
/// get_next_do_cmd - gets next "do" or "conditional" command after start_index /// returns true if found, false if not found /// stops and returns false if it hits another navigation command before it finds the first do or conditional command /// accounts for do_jump commands but never increments the jump's num_times_run (advance_current_nav_cmd is responsible for this) bool AP_Mission::get_next_do_cmd(uint16_t start_index, Mission_Command& cmd) { Mission_Command temp_cmd; // check we have not passed the end of the mission list if (start_index >= (unsigned)_cmd_total) { return false; } // get next command if (!get_next_cmd(start_index, temp_cmd, false)) { // no more commands so return failure return false; }else if (is_nav_cmd(temp_cmd)) { // if it's a "navigation" command then return false because we do not progress past nav commands return false; }else{ // this must be a "do" or "conditional" and is not a do-jump command so return it cmd = temp_cmd; return true; } }
// set_current_cmd - jumps to command specified by index bool AP_Mission::set_current_cmd(uint16_t index) { Mission_Command cmd; // sanity check index and that we have a mission if (index >= (unsigned)_cmd_total || _cmd_total == 1) { return false; } // stop the current running do command _do_cmd.index = AP_MISSION_CMD_INDEX_NONE; _flags.do_cmd_loaded = false; _flags.do_cmd_all_done = false; // stop current nav cmd _flags.nav_cmd_loaded = false; // if index is zero then the user wants to completely restart the mission if (index == 0 || _flags.state == MISSION_COMPLETE) { _prev_nav_cmd_index = AP_MISSION_CMD_INDEX_NONE; // reset the jump tracking to zero init_jump_tracking(); if (index == 0) { index = 1; } } // if the mission is stopped or completed move the nav_cmd index to the specified point and set the state to stopped // so that if the user resumes the mission it will begin at the specified index if (_flags.state != MISSION_RUNNING) { // search until we find next nav command or reach end of command list while (!_flags.nav_cmd_loaded) { // get next command if (!get_next_cmd(index, cmd, true)) { _nav_cmd.index = AP_MISSION_CMD_INDEX_NONE; return false; } // check if navigation or "do" command if (is_nav_cmd(cmd)) { // set current navigation command _nav_cmd = cmd; _flags.nav_cmd_loaded = true; }else{ // set current do command if (!_flags.do_cmd_loaded) { _do_cmd = cmd; _flags.do_cmd_loaded = true; } } // move onto next command index = cmd.index+1; } // if we got this far then the mission can safely be "resumed" from the specified index so we set the state to "stopped" _flags.state = MISSION_STOPPED; return true; } // the state must be MISSION_RUNNING // search until we find next nav command or reach end of command list while (!_flags.nav_cmd_loaded) { // get next command if (!get_next_cmd(index, cmd, true)) { // if we run out of nav commands mark mission as complete complete(); // return true because we did what was requested // which was apparently to jump to a command at the end of the mission return true; } // check if navigation or "do" command if (is_nav_cmd(cmd)) { // save previous nav command index _prev_nav_cmd_index = _nav_cmd.index; // set current navigation command and start it _nav_cmd = cmd; _flags.nav_cmd_loaded = true; _cmd_start_fn(_nav_cmd); }else{ // set current do command and start it (if not already set) if (!_flags.do_cmd_loaded) { _do_cmd = cmd; _flags.do_cmd_loaded = true; _cmd_start_fn(_do_cmd); } } // move onto next command index = cmd.index+1; } // if we got this far we must have successfully advanced the nav command return true; }