/* handle a MISSION_REQUEST mavlink packet */ void GCS_MAVLINK::handle_mission_request(AP_Mission &mission, mavlink_message_t *msg) { AP_Mission::Mission_Command cmd; // decode mavlink_mission_request_t packet; mavlink_msg_mission_request_decode(msg, &packet); // exit immediately if this command is not meant for this vehicle if (mavlink_check_target(packet.target_system, packet.target_component)) { return; } // retrieve mission from eeprom if (!mission.read_cmd_from_storage(packet.seq, cmd)) { goto mission_item_send_failed; } // convert mission command to mavlink mission item packet mavlink_mission_item_t ret_packet; memset(&ret_packet, 0, sizeof(ret_packet)); if (!AP_Mission::mission_cmd_to_mavlink(cmd, ret_packet)) { goto mission_item_send_failed; } // set packet's current field to 1 if this is the command being executed if (cmd.id == (uint16_t)mission.get_current_nav_cmd().index) { ret_packet.current = 1; } else { ret_packet.current = 0; } // set auto continue to 1 ret_packet.autocontinue = 1; // 1 (true), 0 (false) /* avoid the _send() function to save memory on APM2, as it avoids the stack usage of the _send() function by using the already declared ret_packet above */ ret_packet.target_system = msg->sysid; ret_packet.target_component = msg->compid; ret_packet.seq = packet.seq; ret_packet.command = cmd.id; _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_MISSION_ITEM, (const char *)&ret_packet, MAVLINK_MSG_ID_MISSION_ITEM_LEN, MAVLINK_MSG_ID_MISSION_ITEM_CRC); return; mission_item_send_failed: // send failure message mavlink_msg_mission_ack_send(chan, msg->sysid, msg->compid, MAV_MISSION_ERROR); }
void MavlinkMissionManager::handle_mission_request(const mavlink_message_t *msg) { mavlink_mission_request_t wpr; mavlink_msg_mission_request_decode(msg, &wpr); if (CHECK_SYSID_COMPID_MISSION(wpr)) { if (msg->sysid == _transfer_partner_sysid && msg->compid == _transfer_partner_compid) { if (_state == MAVLINK_WPM_STATE_SENDLIST) { _time_last_recv = hrt_absolute_time(); /* _transfer_seq contains sequence of expected request */ if (wpr.seq == _transfer_seq && _transfer_seq < _transfer_count) { if (_verbose) { warnx("WPM: MISSION_ITEM_REQUEST seq %u from ID %u", wpr.seq, msg->sysid); } _transfer_seq++; } else if (wpr.seq == _transfer_seq - 1) { if (_verbose) { warnx("WPM: MISSION_ITEM_REQUEST seq %u from ID %u (again)", wpr.seq, msg->sysid); } } else { if (_transfer_seq > 0 && _transfer_seq < _transfer_count) { if (_verbose) { warnx("WPM: MISSION_ITEM_REQUEST ERROR: seq %u from ID %u unexpected, must be %i or %i", wpr.seq, msg->sysid, _transfer_seq - 1, _transfer_seq); } } else if (_transfer_seq <= 0) { if (_verbose) { warnx("WPM: MISSION_ITEM_REQUEST ERROR: seq %u from ID %u unexpected, must be %i", wpr.seq, msg->sysid, _transfer_seq); } } else { if (_verbose) { warnx("WPM: MISSION_ITEM_REQUEST ERROR: seq %u from ID %u unexpected, must be %i", wpr.seq, msg->sysid, _transfer_seq - 1); } } _state = MAVLINK_WPM_STATE_IDLE; send_mission_ack(_transfer_partner_sysid, _transfer_partner_compid, MAV_MISSION_ERROR); _mavlink->send_statustext_critical("WPM: REJ. CMD: Req. WP was unexpected"); return; } /* double check bounds in case of items count changed */ if (wpr.seq < _count) { send_mission_item(_transfer_partner_sysid, _transfer_partner_compid, wpr.seq); } else { if (_verbose) { warnx("WPM: MISSION_ITEM_REQUEST ERROR: seq %u out of bound [%u, %u]", (unsigned)wpr.seq, (unsigned)wpr.seq, (unsigned)_count - 1); } _state = MAVLINK_WPM_STATE_IDLE; send_mission_ack(_transfer_partner_sysid, _transfer_partner_compid, MAV_MISSION_ERROR); _mavlink->send_statustext_critical("WPM: REJ. CMD: Req. WP was unexpected"); } } else if (_state == MAVLINK_WPM_STATE_IDLE) { if (_verbose) { warnx("WPM: MISSION_ITEM_REQUEST ERROR: no transfer"); } _mavlink->send_statustext_critical("IGN MISSION_ITEM_REQUEST: No active transfer"); } else { if (_verbose) { warnx("WPM: MISSION_ITEM_REQUEST ERROR: busy (state %d).", _state); } _mavlink->send_statustext_critical("WPM: REJ. CMD: Busy"); } } else { _mavlink->send_statustext_critical("WPM: REJ. CMD: partner id mismatch"); if (_verbose) { warnx("WPM: MISSION_ITEM_REQUEST ERROR: rejected, partner ID mismatch"); } } } }
void protDecodeMavlink(void) { uint8_t indx, writeSuccess, commChannel = 1; mavlink_param_set_t set; mavlink_message_t msg; mavlink_status_t status; // uint8_t* dataIn; // fix the data length so if the interrupt adds data // during execution of this block, it will be read // until the next gsRead unsigned int tmpLen = getLength(uartMavlinkInBuffer), i = 0; // if the buffer has more data than the max size, set it to max, // otherwise set it to the length //DatafromGSmavlink[0] = (tmpLen > MAXINLEN) ? MAXINLEN : tmpLen; // read the data //for (i = 1; i <= DatafromGSmavlink[0]; i += 1) { //mavlink_parse_char(commChannel, readFront(uartBufferInMavlink), &msg, &status); //DatafromGSmavlink[i] = readFront(uartMavlinkInBuffer); //} //dataIn = DatafromGSmavlink; // increment the age of heartbeat mlPending.heartbeatAge++; for (i = 0; i <= tmpLen; i++) { // Try to get a new message if (mavlink_parse_char(commChannel, readFront(uartMavlinkInBuffer), &msg, &status)) { // Handle message switch (msg.msgid) { case MAVLINK_MSG_ID_HEARTBEAT: mavlink_msg_heartbeat_decode(&msg, &mlHeartbeat); // Reset the heartbeat mlPending.heartbeatAge = 0; break; //AM DBG case MAVLINK_MSG_ID_MISSION_COUNT: if (!mlPending.wpTransaction && (mlPending.wpProtState == WP_PROT_IDLE)) { mavlink_msg_mission_count_decode(&msg, &mlWpCount); // Start the transaction mlPending.wpTransaction = 1; // change the state mlPending.wpProtState = WP_PROT_GETTING_WP_IDLE; // reset the rest of the state machine mlPending.wpTotalWps = mlWpCount.count; mlPending.wpCurrentWpInTransaction = 0; mlPending.wpTimeOut = 0; } break; case MAVLINK_MSG_ID_MISSION_REQUEST_LIST: // if there is no transaction going on if (!mlPending.wpTransaction && (mlPending.wpProtState == WP_PROT_IDLE)) { // Start the transaction mlPending.wpTransaction = 1; // change the state mlPending.wpProtState = WP_PROT_LIST_REQUESTED; // reset the rest of the state machine mlPending.wpCurrentWpInTransaction = 0; mlPending.wpTimeOut = 0; } break; case MAVLINK_MSG_ID_MISSION_REQUEST: mavlink_msg_mission_request_decode(&msg, &mlWpRequest); if (mlPending.wpTransaction && (mlWpRequest.seq < mlWpValues.wpCount)) { // change the state mlPending.wpProtState = WP_PROT_TX_WP; // reset the rest of the state machine mlPending.wpCurrentWpInTransaction = mlWpRequest.seq; mlPending.wpTimeOut = 0; } else { // TODO: put here a report for a single WP, i.e. not inside a transaction } break; case MAVLINK_MSG_ID_MISSION_ACK: mavlink_msg_mission_ack_decode(&msg, &mlWpAck); if (mlPending.wpTransaction) { // End the transaction mlPending.wpTransaction = 0; // change the state mlPending.wpProtState = WP_PROT_IDLE; // reset the rest of the state machine mlPending.wpCurrentWpInTransaction = 0; mlPending.wpTimeOut = 0; // send current waypoint index mlPending.wpSendCurrent = TRUE; } break; case MAVLINK_MSG_ID_MISSION_ITEM: writeSuccess = SUCCESS; mavlink_msg_mission_item_decode(&msg, &mlSingleWp); if (mlPending.wpTransaction && (mlPending.wpProtState == WP_PROT_RX_WP)) { mlPending.wpProtState = WP_PROT_GETTING_WP_IDLE; } indx = (uint8_t) mlSingleWp.seq; mlWpValues.lat[indx] = mlSingleWp.x; mlWpValues.lon[indx] = mlSingleWp.y; mlWpValues.alt[indx] = mlSingleWp.z; mlWpValues.type[indx] = mlSingleWp.command; mlWpValues.orbit[indx] = (uint16_t) mlSingleWp.param3; /* // Record the data in EEPROM writeSuccess = storeWaypointInEeprom(&mlSingleWp); // Set the flag of Aknowledge for the AKN Message // if the write was not successful if (writeSuccess != SUCCESS) { mlPending.wpAck++; mlWpAck.target_component = MAV_COMP_ID_MISSIONPLANNER; mlWpAck.type = MAV_MISSION_ERROR; } */ break; case MAVLINK_MSG_ID_MISSION_CLEAR_ALL: writeSuccess = SUCCESS; // clear the WP values in memory; memset(&mlWpValues, 0, sizeof (mavlink_mission_item_values_t)); /* writeSuccess = clearWaypointsFrom(0); // Set the flag of Aknowledge fail // if the write was unsuccessful if (writeSuccess != SUCCESS) { mlPending.statustext++; mlStatustext.severity = MAV_SEVERITY_ERROR; strncpy(mlStatustext.text, "Failed to clear waypoints from EEPROM.", 49); } */ // Update the waypoint count mlWpValues.wpCount = 0; // Set the state machine ready to send the WP akn mlPending.wpCurrentWpInTransaction = 0; mlPending.wpTotalWps = 0; mlPending.wpTransaction = 1; mlPending.wpProtState = WP_PROT_GETTING_WP_IDLE; break; case MAVLINK_MSG_ID_SET_GPS_GLOBAL_ORIGIN: writeSuccess = SUCCESS; memset(&mlSingleWp, 0, sizeof (mavlink_mission_item_t)); mavlink_msg_set_gps_global_origin_decode(&msg, &mlGSLocation); mlSingleWp.x = (float) (mlGSLocation.latitude); mlSingleWp.y = (float) (mlGSLocation.longitude); mlSingleWp.z = (float) (mlGSLocation.altitude); indx = (uint8_t) MAX_NUM_WPS - 1; mlWpValues.lat[indx] = mlSingleWp.x; mlWpValues.lon[indx] = mlSingleWp.y; mlWpValues.alt[indx] = mlSingleWp.z; mlWpValues.type[indx] = MAV_CMD_NAV_LAND; mlWpValues.orbit[indx] = 0; // Record the data in EEPROM /* writeSuccess = storeWaypointInEeprom(&mlSingleWp); if (writeSuccess != SUCCESS) { mlPending.statustext++; mlStatustext.severity = MAV_SEVERITY_ERROR; strncpy(mlStatustext.text, "Failed to write origin to EEPROM.", 49); } else { mlPending.statustext++; mlStatustext.severity = MAV_SEVERITY_INFO; strncpy(mlStatustext.text, "Control DSC GPS origin set.", 49); } */ break; //AM DBG case MAVLINK_MSG_ID_PARAM_REQUEST_LIST: mlPending.piTransaction = 1; mlPending.piProtState = PI_SEND_ALL_PARAM; mlPending.piCurrentParamInTransaction = 0; break; case MAVLINK_MSG_ID_PARAM_REQUEST_READ: // If it was in the middle of a list transmission or there is already a param enqueued mlPending.piTransaction = 1; switch (mlPending.piProtState) { case PI_IDLE: mlPending.piBackToList = 0; // no need to go back mlPending.piQIdx = -1; // no Index mlPending.piCurrentParamInTransaction = mavlink_msg_param_request_read_get_param_index(&msg); // assign directly mlPending.piProtState = PI_SEND_ONE_PARAM; break; case PI_SEND_ALL_PARAM: mlPending.piBackToList = 1; // mark to go back mlPending.piQIdx++; // done like this because when empty index = -1 mlPending.piQueue[mlPending.piQIdx] = mavlink_msg_param_request_read_get_param_index(&msg); // put in in queue mlPending.piProtState = PI_SEND_ONE_PARAM; break; case PI_SEND_ONE_PARAM: if (mlPending.piBackToList) { mlPending.piQIdx++; // done like this because when empty index = -1 mlPending.piQueue[mlPending.piQIdx] = mavlink_msg_param_request_read_get_param_index(&msg); // put in in queue } mlPending.piProtState = PI_SEND_ONE_PARAM; break; } break; case MAVLINK_MSG_ID_PARAM_SET: mavlink_msg_param_set_decode(&msg, &set); if ((uint8_t) set.target_system == (uint8_t) SYSTEMID && (uint8_t) set.target_component == (uint8_t) COMPID) { char* key = (char*) set.param_id; uint8_t i, j; uint8_t match; for (i = 0; i < PAR_PARAM_COUNT; i++) { match = 1; for (j = 0; j < PARAM_NAME_LENGTH; j++) { // Compare if (((char) (mlParamInterface.param_name[i][j])) != (char) (key[j])) { match = 0; } // if // End matching if null termination is reached if (((char) mlParamInterface.param_name[i][j]) == '\0') { break; } // if }// for j // Check if matched if (match) { //sw_debug = 1; // Only write and emit changes if there is actually a difference // AND only write if new value is NOT "not-a-number" // AND is NOT infinity if (isFinite(set.param_value)) { mlParamInterface.param[i] = set.param_value; // Report back new value mlPending.piBackToList = 0; // no need to go back mlPending.piQIdx = -1; // no Index mlPending.piCurrentParamInTransaction = i; // assign directly mlPending.piProtState = PI_SEND_ONE_PARAM; mlPending.piTransaction = 1; } // if different and not nan and not inf } // if match }// for i } // if addressed to this break; default: break; } } } }
void mavlink_wpm_message_handler(const mavlink_message_t* msg) { uint64_t now = mavlink_missionlib_get_system_timestamp(); switch(msg->msgid) { case MAVLINK_MSG_ID_ATTITUDE: { if(msg->sysid == mavlink_system.sysid && wpm.current_active_wp_id < wpm.size) { mavlink_mission_item_t *wp = &(wpm.waypoints[wpm.current_active_wp_id]); if(wp->frame == MAV_FRAME_LOCAL_ENU || wp->frame == MAV_FRAME_LOCAL_NED) { mavlink_attitude_t att; mavlink_msg_attitude_decode(msg, &att); float yaw_tolerance = wpm.accept_range_yaw; //compare current yaw if (att.yaw - yaw_tolerance >= 0.0f && att.yaw + yaw_tolerance < 2.f*M_PI) { if (att.yaw - yaw_tolerance <= wp->param4 && att.yaw + yaw_tolerance >= wp->param4) wpm.yaw_reached = true; } else if(att.yaw - yaw_tolerance < 0.0f) { float lowerBound = 360.0f + att.yaw - yaw_tolerance; if (lowerBound < wp->param4 || wp->param4 < att.yaw + yaw_tolerance) wpm.yaw_reached = true; } else { float upperBound = att.yaw + yaw_tolerance - 2.f*M_PI; if (att.yaw - yaw_tolerance < wp->param4 || wp->param4 < upperBound) wpm.yaw_reached = true; } } } break; } case MAVLINK_MSG_ID_LOCAL_POSITION_NED: { if(msg->sysid == mavlink_system.sysid && wpm.current_active_wp_id < wpm.size) { mavlink_mission_item_t *wp = &(wpm.waypoints[wpm.current_active_wp_id]); if(wp->frame == MAV_FRAME_LOCAL_ENU || MAV_FRAME_LOCAL_NED) { mavlink_local_position_ned_t pos; mavlink_msg_local_position_ned_decode(msg, &pos); //// if (debug) // printf("Received new position: x: %f | y: %f | z: %f\n", pos.x, pos.y, pos.z); wpm.pos_reached = false; // compare current position (given in message) with current waypoint float orbit = wp->param1; float dist; // if (wp->param2 == 0) // { // // FIXME segment distance // //dist = mavlink_wpm_distance_to_segment(current_active_wp_id, pos.x, pos.y, pos.z); // } // else // { dist = mavlink_wpm_distance_to_point(wpm.current_active_wp_id, pos.x, pos.y, pos.z); // } if (dist >= 0.f && dist <= orbit && wpm.yaw_reached) { wpm.pos_reached = true; } } } break; } // case MAVLINK_MSG_ID_CMD: // special action from ground station // { // mavlink_cmd_t action; // mavlink_msg_cmd_decode(msg, &action); // if(action.target == mavlink_system.sysid) // { // // if (verbose) std::cerr << "Waypoint: received message with action " << action.action << std::endl; // switch (action.action) // { // // case MAV_ACTION_LAUNCH: // // // if (verbose) std::cerr << "Launch received" << std::endl; // // current_active_wp_id = 0; // // if (wpm.size>0) // // { // // setActive(waypoints[current_active_wp_id]); // // } // // else // // // if (verbose) std::cerr << "No launch, waypointList empty" << std::endl; // // break; // // // case MAV_ACTION_CONTINUE: // // // if (verbose) std::c // // err << "Continue received" << std::endl; // // idle = false; // // setActive(waypoints[current_active_wp_id]); // // break; // // // case MAV_ACTION_HALT: // // // if (verbose) std::cerr << "Halt received" << std::endl; // // idle = true; // // break; // // // default: // // // if (verbose) std::cerr << "Unknown action received with id " << action.action << ", no action taken" << std::endl; // // break; // } // } // break; // } case MAVLINK_MSG_ID_MISSION_ACK: { mavlink_mission_ack_t wpa; mavlink_msg_mission_ack_decode(msg, &wpa); if((msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid) && (wpa.target_system == mavlink_system.sysid /*&& wpa.target_component == mavlink_wpm_comp_id*/)) { wpm.timestamp_lastaction = now; if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST || wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS) { if (wpm.current_wp_id == wpm.size-1) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("Got last WP ACK state -> IDLE"); #else if (MAVLINK_WPM_VERBOSE) printf("Received ACK after having sent last waypoint, going to state MAVLINK_WPM_STATE_IDLE\n"); #endif wpm.current_state = MAVLINK_WPM_STATE_IDLE; wpm.current_wp_id = 0; } } } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: curr partner id mismatch"); #else if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n"); #endif } break; } case MAVLINK_MSG_ID_MISSION_SET_CURRENT: { mavlink_mission_set_current_t wpc; mavlink_msg_mission_set_current_decode(msg, &wpc); if(wpc.target_system == mavlink_system.sysid /*&& wpc.target_component == mavlink_wpm_comp_id*/) { wpm.timestamp_lastaction = now; if (wpm.current_state == MAVLINK_WPM_STATE_IDLE) { if (wpc.seq < wpm.size) { // if (verbose) // printf("Received MAVLINK_MSG_ID_MISSION_ITEM_SET_CURRENT\n"); wpm.current_active_wp_id = wpc.seq; uint32_t i; for(i = 0; i < wpm.size; i++) { if (i == wpm.current_active_wp_id) { wpm.waypoints[i].current = true; } else { wpm.waypoints[i].current = false; } } #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("NEW WP SET"); #else if (MAVLINK_WPM_VERBOSE) printf("New current waypoint %u\n", wpm.current_active_wp_id); #endif wpm.yaw_reached = false; wpm.pos_reached = false; mavlink_wpm_send_waypoint_current(wpm.current_active_wp_id); mavlink_wpm_send_setpoint(wpm.current_active_wp_id); wpm.timestamp_firstinside_orbit = 0; } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("IGN WP CURR CMD: Not in list"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_SET_CURRENT: Index out of bounds\n"); #endif } } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("IGN WP CURR CMD: Busy"); #else if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE NOT IN IDLE STATE\n"); #endif } } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: target id mismatch"); #else if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n"); #endif } break; } case MAVLINK_MSG_ID_MISSION_REQUEST_LIST: { mavlink_mission_request_list_t wprl; mavlink_msg_mission_request_list_decode(msg, &wprl); if(wprl.target_system == mavlink_system.sysid /*&& wprl.target_component == mavlink_wpm_comp_id*/) { wpm.timestamp_lastaction = now; if (wpm.current_state == MAVLINK_WPM_STATE_IDLE || wpm.current_state == MAVLINK_WPM_STATE_SENDLIST) { if (wpm.size > 0) { //if (verbose && wpm.current_state == MAVLINK_WPM_STATE_IDLE) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST from %u changing state to MAVLINK_WPM_STATE_SENDLIST\n", msg->sysid); // if (verbose && wpm.current_state == MAVLINK_WPM_STATE_SENDLIST) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST again from %u staying in state MAVLINK_WPM_STATE_SENDLIST\n", msg->sysid); wpm.current_state = MAVLINK_WPM_STATE_SENDLIST; wpm.current_wp_id = 0; wpm.current_partner_sysid = msg->sysid; wpm.current_partner_compid = msg->compid; } else { // if (verbose) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST from %u but have no waypoints, staying in \n", msg->sysid); } wpm.current_count = wpm.size; mavlink_wpm_send_waypoint_count(msg->sysid,msg->compid, wpm.current_count); } else { // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST because i'm doing something else already (state=%i).\n", wpm.current_state); } } else { // if (verbose) // printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT MISMATCH\n"); } break; } case MAVLINK_MSG_ID_MISSION_REQUEST: { mavlink_mission_request_t wpr; mavlink_msg_mission_request_decode(msg, &wpr); if(msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid && wpr.target_system == mavlink_system.sysid /*&& wpr.target_component == mavlink_wpm_comp_id*/) { wpm.timestamp_lastaction = now; //ensure that we are in the correct state and that the first request has id 0 and the following requests have either the last id (re-send last waypoint) or last_id+1 (next waypoint) if ((wpm.current_state == MAVLINK_WPM_STATE_SENDLIST && wpr.seq == 0) || (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS && (wpr.seq == wpm.current_wp_id || wpr.seq == wpm.current_wp_id + 1) && wpr.seq < wpm.size)) { if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("GOT WP REQ, state -> SEND"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST of waypoint %u from %u changing state to MAVLINK_WPM_STATE_SENDLIST_SENDWPS\n", wpr.seq, msg->sysid); #endif } if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS && wpr.seq == wpm.current_wp_id + 1) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("GOT 2nd WP REQ"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST of waypoint %u from %u staying in state MAVLINK_WPM_STATE_SENDLIST_SENDWPS\n", wpr.seq, msg->sysid); #endif } if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS && wpr.seq == wpm.current_wp_id) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("GOT 2nd WP REQ"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST of waypoint %u (again) from %u staying in state MAVLINK_WPM_STATE_SENDLIST_SENDWPS\n", wpr.seq, msg->sysid); #endif } wpm.current_state = MAVLINK_WPM_STATE_SENDLIST_SENDWPS; wpm.current_wp_id = wpr.seq; mavlink_wpm_send_waypoint(wpm.current_partner_sysid, wpm.current_partner_compid, wpr.seq); } else { // if (verbose) { if (!(wpm.current_state == MAVLINK_WPM_STATE_SENDLIST || wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS)) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because i'm doing something else already (state=%i).\n", wpm.current_state); #endif break; } else if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST) { if (wpr.seq != 0) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: First id != 0"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because the first requested waypoint ID (%u) was not 0.\n", wpr.seq); #endif } } else if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS) { if (wpr.seq != wpm.current_wp_id && wpr.seq != wpm.current_wp_id + 1) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Req. WP was unexpected"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because the requested waypoint ID (%u) was not the expected (%u or %u).\n", wpr.seq, wpm.current_wp_id, wpm.current_wp_id+1); #endif } else if (wpr.seq >= wpm.size) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Req. WP not in list"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because the requested waypoint ID (%u) was out of bounds.\n", wpr.seq); #endif } } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: ?"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST - FIXME: missed error description\n"); #endif } } } } else { //we we're target but already communicating with someone else if((wpr.target_system == mavlink_system.sysid /*&& wpr.target_component == mavlink_wpm_comp_id*/) && !(msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid)) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST from ID %u because i'm already talking to ID %u.\n", msg->sysid, wpm.current_partner_sysid); #endif } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: target id mismatch"); #else if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n"); #endif } } break; } case MAVLINK_MSG_ID_MISSION_COUNT: { mavlink_mission_count_t wpc; mavlink_msg_mission_count_decode(msg, &wpc); if(wpc.target_system == mavlink_system.sysid/* && wpc.target_component == mavlink_wpm_comp_id*/) { wpm.timestamp_lastaction = now; if (wpm.current_state == MAVLINK_WPM_STATE_IDLE || (wpm.current_state == MAVLINK_WPM_STATE_GETLIST && wpm.current_wp_id == 0)) { if (wpc.count > 0) { if (wpm.current_state == MAVLINK_WPM_STATE_IDLE) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("WP CMD OK: state -> GETLIST"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_COUNT (%u) from %u changing state to MAVLINK_WPM_STATE_GETLIST\n", wpc.count, msg->sysid); #endif } if (wpm.current_state == MAVLINK_WPM_STATE_GETLIST) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("WP CMD OK AGAIN"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_COUNT (%u) again from %u\n", wpc.count, msg->sysid); #endif } wpm.current_state = MAVLINK_WPM_STATE_GETLIST; wpm.current_wp_id = 0; wpm.current_partner_sysid = msg->sysid; wpm.current_partner_compid = msg->compid; wpm.current_count = wpc.count; #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("CLR RCV BUF: READY"); #else if (MAVLINK_WPM_VERBOSE) printf("clearing receive buffer and readying for receiving waypoints\n"); #endif wpm.rcv_size = 0; //while(waypoints_receive_buffer->size() > 0) // { // delete waypoints_receive_buffer->back(); // waypoints_receive_buffer->pop_back(); // } mavlink_wpm_send_waypoint_request(wpm.current_partner_sysid, wpm.current_partner_compid, wpm.current_wp_id); } else if (wpc.count == 0) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("COUNT 0"); #else if (MAVLINK_WPM_VERBOSE) printf("got waypoint count of 0, clearing waypoint list and staying in state MAVLINK_WPM_STATE_IDLE\n"); #endif wpm.rcv_size = 0; //while(waypoints_receive_buffer->size() > 0) // { // delete waypoints->back(); // waypoints->pop_back(); // } wpm.current_active_wp_id = -1; wpm.yaw_reached = false; wpm.pos_reached = false; break; } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("IGN WP CMD"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignoring MAVLINK_MSG_ID_MISSION_ITEM_COUNT from %u with count of %u\n", msg->sysid, wpc.count); #endif } } else { if (!(wpm.current_state == MAVLINK_WPM_STATE_IDLE || wpm.current_state == MAVLINK_WPM_STATE_GETLIST)) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_COUNT because i'm doing something else already (state=%i).\n", wpm.current_state); #endif } else if (wpm.current_state == MAVLINK_WPM_STATE_GETLIST && wpm.current_wp_id != 0) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_COUNT because i'm already receiving waypoint %u.\n", wpm.current_wp_id); #endif } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: ?"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_COUNT - FIXME: missed error description\n"); #endif } } } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: target id mismatch"); #else if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n"); #endif } } break; case MAVLINK_MSG_ID_MISSION_ITEM: { mavlink_mission_item_t wp; mavlink_msg_mission_item_decode(msg, &wp); mavlink_missionlib_send_gcs_string("GOT WP"); if((msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid) && (wp.target_system == mavlink_system.sysid /*&& wp.target_component == mavlink_wpm_comp_id*/)) { wpm.timestamp_lastaction = now; //ensure that we are in the correct state and that the first waypoint has id 0 and the following waypoints have the correct ids if ((wpm.current_state == MAVLINK_WPM_STATE_GETLIST && wp.seq == 0) || (wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS && wp.seq == wpm.current_wp_id && wp.seq < wpm.current_count)) { // if (verbose && wpm.current_state == MAVLINK_WPM_STATE_GETLIST) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM %u from %u changing state to MAVLINK_WPM_STATE_GETLIST_GETWPS\n", wp.seq, msg->sysid); // if (verbose && wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS && wp.seq == wpm.current_wp_id) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM %u from %u\n", wp.seq, msg->sysid); // if (verbose && wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS && wp.seq-1 == wpm.current_wp_id) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM %u (again) from %u\n", wp.seq, msg->sysid); // wpm.current_state = MAVLINK_WPM_STATE_GETLIST_GETWPS; mavlink_mission_item_t* newwp = &(wpm.rcv_waypoints[wp.seq]); memcpy(newwp, &wp, sizeof(mavlink_mission_item_t)); wpm.current_wp_id = wp.seq + 1; // if (verbose) // printf ("Added new waypoint to list. X= %f\t Y= %f\t Z= %f\t Yaw= %f\n", newwp->x, newwp->y, newwp->z, newwp->param4); if(wpm.current_wp_id == wpm.current_count && wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS) { mavlink_missionlib_send_gcs_string("GOT ALL WPS"); // if (verbose) // printf("Got all %u waypoints, changing state to MAVLINK_WPM_STATE_IDLE\n", wpm.current_count); mavlink_wpm_send_waypoint_ack(wpm.current_partner_sysid, wpm.current_partner_compid, 0); if (wpm.current_active_wp_id > wpm.rcv_size-1) { wpm.current_active_wp_id = wpm.rcv_size-1; } // switch the waypoints list // FIXME CHECK!!! for (int i = 0; i < wpm.current_count; ++i) { wpm.waypoints[i] = wpm.rcv_waypoints[i]; } wpm.size = wpm.current_count; //get the new current waypoint uint32_t i; for(i = 0; i < wpm.size; i++) { if (wpm.waypoints[i].current == 1) { wpm.current_active_wp_id = i; //// if (verbose) // printf("New current waypoint %u\n", current_active_wp_id); wpm.yaw_reached = false; wpm.pos_reached = false; mavlink_wpm_send_waypoint_current(wpm.current_active_wp_id); mavlink_wpm_send_setpoint(wpm.current_active_wp_id); wpm.timestamp_firstinside_orbit = 0; break; } } if (i == wpm.size) { wpm.current_active_wp_id = -1; wpm.yaw_reached = false; wpm.pos_reached = false; wpm.timestamp_firstinside_orbit = 0; } wpm.current_state = MAVLINK_WPM_STATE_IDLE; } else { mavlink_wpm_send_waypoint_request(wpm.current_partner_sysid, wpm.current_partner_compid, wpm.current_wp_id); } } else { if (wpm.current_state == MAVLINK_WPM_STATE_IDLE) { //we're done receiving waypoints, answer with ack. mavlink_wpm_send_waypoint_ack(wpm.current_partner_sysid, wpm.current_partner_compid, 0); // printf("Received MAVLINK_MSG_ID_MISSION_ITEM while state=MAVLINK_WPM_STATE_IDLE, answered with WAYPOINT_ACK.\n"); } // if (verbose) { if (!(wpm.current_state == MAVLINK_WPM_STATE_GETLIST || wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS)) { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u because i'm doing something else already (state=%i).\n", wp.seq, wpm.current_state); break; } else if (wpm.current_state == MAVLINK_WPM_STATE_GETLIST) { if(!(wp.seq == 0)) { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM because the first waypoint ID (%u) was not 0.\n", wp.seq); } else { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u - FIXME: missed error description\n", wp.seq); } } else if (wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS) { if (!(wp.seq == wpm.current_wp_id)) { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM because the waypoint ID (%u) was not the expected %u.\n", wp.seq, wpm.current_wp_id); } else if (!(wp.seq < wpm.current_count)) { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM because the waypoint ID (%u) was out of bounds.\n", wp.seq); } else { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u - FIXME: missed error description\n", wp.seq); } } else { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u - FIXME: missed error description\n", wp.seq); } } } } else { //we we're target but already communicating with someone else if((wp.target_system == mavlink_system.sysid /*&& wp.target_component == mavlink_wpm_comp_id*/) && !(msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid) && wpm.current_state != MAVLINK_WPM_STATE_IDLE) { // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u from ID %u because i'm already talking to ID %u.\n", wp.seq, msg->sysid, wpm.current_partner_sysid); } else if(wp.target_system == mavlink_system.sysid /* && wp.target_component == mavlink_wpm_comp_id*/) { // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u from ID %u because i have no idea what to do with it\n", wp.seq, msg->sysid); } } break; } case MAVLINK_MSG_ID_MISSION_CLEAR_ALL: { mavlink_mission_clear_all_t wpca; mavlink_msg_mission_clear_all_decode(msg, &wpca); if(wpca.target_system == mavlink_system.sysid /*&& wpca.target_component == mavlink_wpm_comp_id */ && wpm.current_state == MAVLINK_WPM_STATE_IDLE) { wpm.timestamp_lastaction = now; // if (verbose) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_CLEAR_LIST from %u deleting all waypoints\n", msg->sysid); // Delete all waypoints wpm.size = 0; wpm.current_active_wp_id = -1; wpm.yaw_reached = false; wpm.pos_reached = false; } else if (wpca.target_system == mavlink_system.sysid /*&& wpca.target_component == mavlink_wpm_comp_id */ && wpm.current_state != MAVLINK_WPM_STATE_IDLE) { // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_CLEAR_LIST from %u because i'm doing something else already (state=%i).\n", msg->sysid, wpm.current_state); } break; } default: { // if (debug) // printf("Waypoint: received message of unknown type"); break; } } //check if the current waypoint was reached if (wpm.pos_reached /*wpm.yaw_reached &&*/ && !wpm.idle) { if (wpm.current_active_wp_id < wpm.size) { mavlink_mission_item_t *cur_wp = &(wpm.waypoints[wpm.current_active_wp_id]); if (wpm.timestamp_firstinside_orbit == 0) { // Announce that last waypoint was reached // if (verbose) // printf("*** Reached waypoint %u ***\n", cur_wp->seq); mavlink_wpm_send_waypoint_reached(cur_wp->seq); wpm.timestamp_firstinside_orbit = now; } // check if the MAV was long enough inside the waypoint orbit //if (now-timestamp_lastoutside_orbit > (cur_wp->hold_time*1000)) if(now-wpm.timestamp_firstinside_orbit >= cur_wp->param2*1000) { if (cur_wp->autocontinue) { cur_wp->current = 0; if (wpm.current_active_wp_id == wpm.size - 1 && wpm.size > 1) { //the last waypoint was reached, if auto continue is //activated restart the waypoint list from the beginning wpm.current_active_wp_id = 1; } else { if ((uint16_t)(wpm.current_active_wp_id + 1) < wpm.size) wpm.current_active_wp_id++; } // Fly to next waypoint wpm.timestamp_firstinside_orbit = 0; mavlink_wpm_send_waypoint_current(wpm.current_active_wp_id); mavlink_wpm_send_setpoint(wpm.current_active_wp_id); wpm.waypoints[wpm.current_active_wp_id].current = true; wpm.pos_reached = false; wpm.yaw_reached = false; // if (verbose) // printf("Set new waypoint (%u)\n", wpm.current_active_wp_id); } } } } else { wpm.timestamp_lastoutside_orbit = now; } }
void mavlink_connector::handle_missions(mavlink_message_t *msg) { mavlink_message_t resp; switch (msg->msgid) { case MAVLINK_MSG_ID_MISSION_REQUEST_LIST: { mavlink_mission_count_t count; count.count = dji_variable::wp_m.missions[0].size(); count.target_component = msg->compid; count.target_system = msg->sysid; mavlink_msg_mission_count_encode(0, 200, &resp, &count); this->send_msg(&resp); break; } case MAVLINK_MSG_ID_MISSION_REQUEST: { mavlink_mission_request_t req; mavlink_msg_mission_request_decode(msg, &req); // printf("ground is trying to request mission %d \n",req.seq); std::vector<mavlink_mission_item_t> mission_msgs = dji_variable::wp_m.missions[0].to_mission_items(); mavlink_mission_item_t a = mission_msgs[req.seq]; a.target_system = msg->sysid; a.target_component = msg->compid; a.current = (a.seq == dji_variable::wp_m.waypoint_ptr && dji_variable::wp_m.mission_id == 0)? 1:0; mavlink_msg_mission_item_encode(0,200, &resp, &a); this->send_msg(&resp); break; } case MAVLINK_MSG_ID_MISSION_COUNT: { mavlink_mission_count_t mission_count_t; mavlink_msg_mission_count_decode(msg, &mission_count_t); if (MISSION_REC_STATE == MISSION_REC_STANDBY) { printf("Ground is trying to set a waypoint long as %d\n", mission_count_t.count); waypoint_length_size = mission_count_t.count; waypoint_waitfor = 0; dji_variable::wp_m.missions[0].clear(); MISSION_REC_STATE = MISSION_REC_WAIT_FOR; mavlink_mission_request_t request_t; request_t.target_component = msg->compid; request_t.target_system = msg->sysid; request_t.seq = 0; mavlink_msg_mission_request_encode(0,200,&resp,&request_t); this->send_msg(&resp); break; } }; case MAVLINK_MSG_ID_MISSION_ITEM: { if (MISSION_REC_STATE != MISSION_REC_WAIT_FOR) break; mavlink_mission_item_t mission_item_t; mavlink_msg_mission_item_decode(msg,&mission_item_t); printf("seq:%d %f %f cmd: %d\n",mission_item_t.seq,mission_item_t.x,mission_item_t.y,mission_item_t.command); api_pos_custom_data_t wp; wp.lati = mission_item_t.x /180 * M_PI; wp.longti = mission_item_t.y /180 * M_PI; wp.alti = mission_item_t.z; wp.cmd = mission_item_t.command; // wp.uncertain = mission_item_t. wp.uncertain = 10 ; mavlink_mission_request_t request_t; request_t.target_component = msg->compid; request_t.target_system = msg->sysid; if (mission_item_t.seq == waypoint_waitfor) { waypoint_waitfor ++; request_t.seq = waypoint_waitfor; dji_variable::wp_m.missions[0].waypoints.push_back(wp); if (request_t.seq < waypoint_length_size) { mavlink_msg_mission_request_encode(0, 200, &resp, &request_t); this->send_msg(&resp); } else{ std::cout << dji_variable::wp_m.missions[0]; waypoint_waitfor = 0; waypoint_length_size = 0; MISSION_REC_STATE = MISSION_REC_STANDBY; mavlink_mission_ack_t ack_t; ack_t.target_component = msg->compid; ack_t.target_system = msg->sysid; ack_t.type = MAV_MISSION_RESULT::MAV_MISSION_ACCEPTED; mavlink_msg_mission_ack_encode(0,200,&resp,&ack_t); this->send_msg(&resp); } } else{ request_t.seq = waypoint_waitfor; mavlink_msg_mission_request_encode(0, 200, &resp, &request_t); this->send_msg(&resp); } break; }; case MAVLINK_MSG_ID_MISSION_SET_CURRENT: { mavlink_mission_set_current_t set_current_t; mavlink_msg_mission_set_current_decode(msg,&set_current_t); int ptr = set_current_t.seq; printf("say system is trying to set current %d \n",ptr); dji_variable::wp_m.mission_id = 0; dji_variable::wp_m.waypoint_ptr = ptr; dji_variable::wp_m.begin_fly_waypoints(0,ptr); mavlink_mission_ack_t ack_t; ack_t.target_component = msg->compid; ack_t.target_system = msg->sysid; ack_t.type = MAV_MISSION_RESULT::MAV_MISSION_ACCEPTED; mavlink_msg_mission_ack_encode(0,200,&resp,&ack_t); this->send_msg(&resp); }; default: break; } }
void mavlink_wpm_message_handler(const mavlink_message_t *msg, const struct vehicle_global_position_s *global_pos , struct vehicle_local_position_s *local_pos) { uint64_t now = mavlink_missionlib_get_system_timestamp(); switch (msg->msgid) { case MAVLINK_MSG_ID_MISSION_ACK: { mavlink_mission_ack_t wpa; mavlink_msg_mission_ack_decode(msg, &wpa); if ((msg->sysid == wpm->current_partner_sysid && msg->compid == wpm->current_partner_compid) && (wpa.target_system == mavlink_system.sysid /*&& wpa.target_component == mavlink_wpm_comp_id*/)) { wpm->timestamp_lastaction = now; if (wpm->current_state == MAVLINK_WPM_STATE_SENDLIST || wpm->current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS) { if (wpm->current_wp_id == wpm->size - 1) { mavlink_missionlib_send_gcs_string("Got last WP ACK state -> IDLE"); wpm->current_state = MAVLINK_WPM_STATE_IDLE; wpm->current_wp_id = 0; } } } else { mavlink_missionlib_send_gcs_string("REJ. WP CMD: curr partner id mismatch"); } break; } case MAVLINK_MSG_ID_MISSION_SET_CURRENT: { mavlink_mission_set_current_t wpc; mavlink_msg_mission_set_current_decode(msg, &wpc); if (wpc.target_system == mavlink_system.sysid /*&& wpc.target_component == mavlink_wpm_comp_id*/) { wpm->timestamp_lastaction = now; if (wpm->current_state == MAVLINK_WPM_STATE_IDLE) { if (wpc.seq < wpm->size) { // if (verbose) // printf("Received MAVLINK_MSG_ID_MISSION_ITEM_SET_CURRENT\n"); wpm->current_active_wp_id = wpc.seq; uint32_t i; for (i = 0; i < wpm->size; i++) { if (i == wpm->current_active_wp_id) { wpm->waypoints[i].current = true; } else { wpm->waypoints[i].current = false; } } mavlink_missionlib_send_gcs_string("NEW WP SET"); wpm->yaw_reached = false; wpm->pos_reached = false; mavlink_wpm_send_waypoint_current(wpm->current_active_wp_id); mavlink_wpm_send_setpoint(wpm->current_active_wp_id); wpm->timestamp_firstinside_orbit = 0; } else { mavlink_missionlib_send_gcs_string("IGN WP CURR CMD: Not in list"); } } else { mavlink_missionlib_send_gcs_string("IGN WP CURR CMD: Busy"); } } else { mavlink_missionlib_send_gcs_string("REJ. WP CMD: target id mismatch"); } break; } case MAVLINK_MSG_ID_MISSION_REQUEST_LIST: { mavlink_mission_request_list_t wprl; mavlink_msg_mission_request_list_decode(msg, &wprl); if (wprl.target_system == mavlink_system.sysid /*&& wprl.target_component == mavlink_wpm_comp_id*/) { wpm->timestamp_lastaction = now; if (wpm->current_state == MAVLINK_WPM_STATE_IDLE || wpm->current_state == MAVLINK_WPM_STATE_SENDLIST) { if (wpm->size > 0) { //if (verbose && wpm->current_state == MAVLINK_WPM_STATE_IDLE) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST from %u changing state to MAVLINK_WPM_STATE_SENDLIST\n", msg->sysid); // if (verbose && wpm->current_state == MAVLINK_WPM_STATE_SENDLIST) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST again from %u staying in state MAVLINK_WPM_STATE_SENDLIST\n", msg->sysid); wpm->current_state = MAVLINK_WPM_STATE_SENDLIST; wpm->current_wp_id = 0; wpm->current_partner_sysid = msg->sysid; wpm->current_partner_compid = msg->compid; } else { // if (verbose) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST from %u but have no waypoints, staying in \n", msg->sysid); } wpm->current_count = wpm->size; mavlink_wpm_send_waypoint_count(msg->sysid, msg->compid, wpm->current_count); } else { // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST because i'm doing something else already (state=%i).\n", wpm->current_state); } } else { // if (verbose) // printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT MISMATCH\n"); } break; } case MAVLINK_MSG_ID_MISSION_REQUEST: { mavlink_mission_request_t wpr; mavlink_msg_mission_request_decode(msg, &wpr); if (msg->sysid == wpm->current_partner_sysid && msg->compid == wpm->current_partner_compid && wpr.target_system == mavlink_system.sysid /*&& wpr.target_component == mavlink_wpm_comp_id*/) { wpm->timestamp_lastaction = now; //ensure that we are in the correct state and that the first request has id 0 and the following requests have either the last id (re-send last waypoint) or last_id+1 (next waypoint) if ((wpm->current_state == MAVLINK_WPM_STATE_SENDLIST && wpr.seq == 0) || (wpm->current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS && (wpr.seq == wpm->current_wp_id || wpr.seq == wpm->current_wp_id + 1) && wpr.seq < wpm->size)) { if (wpm->current_state == MAVLINK_WPM_STATE_SENDLIST) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("GOT WP REQ, state -> SEND"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST of waypoint %u from %u changing state to MAVLINK_WPM_STATE_SENDLIST_SENDWPS\n", wpr.seq, msg->sysid); #endif } if (wpm->current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS && wpr.seq == wpm->current_wp_id + 1) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("GOT 2nd WP REQ"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST of waypoint %u from %u staying in state MAVLINK_WPM_STATE_SENDLIST_SENDWPS\n", wpr.seq, msg->sysid); #endif } if (wpm->current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS && wpr.seq == wpm->current_wp_id) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("GOT 2nd WP REQ"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST of waypoint %u (again) from %u staying in state MAVLINK_WPM_STATE_SENDLIST_SENDWPS\n", wpr.seq, msg->sysid); #endif } wpm->current_state = MAVLINK_WPM_STATE_SENDLIST_SENDWPS; wpm->current_wp_id = wpr.seq; mavlink_wpm_send_waypoint(wpm->current_partner_sysid, wpm->current_partner_compid, wpr.seq); } else { // if (verbose) { if (!(wpm->current_state == MAVLINK_WPM_STATE_SENDLIST || wpm->current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS)) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because i'm doing something else already (state=%i).\n", wpm->current_state); #endif break; } else if (wpm->current_state == MAVLINK_WPM_STATE_SENDLIST) { if (wpr.seq != 0) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: First id != 0"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because the first requested waypoint ID (%u) was not 0.\n", wpr.seq); #endif } } else if (wpm->current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS) { if (wpr.seq != wpm->current_wp_id && wpr.seq != wpm->current_wp_id + 1) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Req. WP was unexpected"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because the requested waypoint ID (%u) was not the expected (%u or %u).\n", wpr.seq, wpm->current_wp_id, wpm->current_wp_id + 1); #endif } else if (wpr.seq >= wpm->size) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Req. WP not in list"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because the requested waypoint ID (%u) was out of bounds.\n", wpr.seq); #endif } } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: ?"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST - FIXME: missed error description\n"); #endif } } } } else { //we we're target but already communicating with someone else if ((wpr.target_system == mavlink_system.sysid /*&& wpr.target_component == mavlink_wpm_comp_id*/) && !(msg->sysid == wpm->current_partner_sysid && msg->compid == wpm->current_partner_compid)) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST from ID %u because i'm already talking to ID %u.\n", msg->sysid, wpm->current_partner_sysid); #endif } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: target id mismatch"); #else if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n"); #endif } } break; } case MAVLINK_MSG_ID_MISSION_COUNT: { mavlink_mission_count_t wpc; mavlink_msg_mission_count_decode(msg, &wpc); if (wpc.target_system == mavlink_system.sysid/* && wpc.target_component == mavlink_wpm_comp_id*/) { wpm->timestamp_lastaction = now; if (wpm->current_state == MAVLINK_WPM_STATE_IDLE || (wpm->current_state == MAVLINK_WPM_STATE_GETLIST && wpm->current_wp_id == 0)) { // printf("wpc count in: %d\n",wpc.count); // printf("Comp id: %d\n",msg->compid); // printf("Current partner sysid: %d\n",wpm->current_partner_sysid); if (wpc.count > 0) { if (wpm->current_state == MAVLINK_WPM_STATE_IDLE) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("WP CMD OK: state -> GETLIST"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_COUNT (%u) from %u changing state to MAVLINK_WPM_STATE_GETLIST\n", wpc.count, msg->sysid); #endif } if (wpm->current_state == MAVLINK_WPM_STATE_GETLIST) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("WP CMD OK AGAIN"); #else if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_COUNT (%u) again from %u\n", wpc.count, msg->sysid); #endif } wpm->current_state = MAVLINK_WPM_STATE_GETLIST; wpm->current_wp_id = 0; wpm->current_partner_sysid = msg->sysid; wpm->current_partner_compid = msg->compid; wpm->current_count = wpc.count; #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("CLR RCV BUF: READY"); #else if (MAVLINK_WPM_VERBOSE) printf("clearing receive buffer and readying for receiving waypoints\n"); #endif wpm->rcv_size = 0; //while(waypoints_receive_buffer->size() > 0) // { // delete waypoints_receive_buffer->back(); // waypoints_receive_buffer->pop_back(); // } mavlink_wpm_send_waypoint_request(wpm->current_partner_sysid, wpm->current_partner_compid, wpm->current_wp_id); } else if (wpc.count == 0) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("COUNT 0"); #else if (MAVLINK_WPM_VERBOSE) printf("got waypoint count of 0, clearing waypoint list and staying in state MAVLINK_WPM_STATE_IDLE\n"); #endif wpm->rcv_size = 0; //while(waypoints_receive_buffer->size() > 0) // { // delete waypoints->back(); // waypoints->pop_back(); // } wpm->current_active_wp_id = -1; wpm->yaw_reached = false; wpm->pos_reached = false; break; } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("IGN WP CMD"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignoring MAVLINK_MSG_ID_MISSION_ITEM_COUNT from %u with count of %u\n", msg->sysid, wpc.count); #endif } } else { if (!(wpm->current_state == MAVLINK_WPM_STATE_IDLE || wpm->current_state == MAVLINK_WPM_STATE_GETLIST)) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_COUNT because i'm doing something else already (state=%i).\n", wpm->current_state); #endif } else if (wpm->current_state == MAVLINK_WPM_STATE_GETLIST && wpm->current_wp_id != 0) { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_COUNT because i'm already receiving waypoint %u.\n", wpm->current_wp_id); #endif } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: ?"); #else if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_COUNT - FIXME: missed error description\n"); #endif } } } else { #ifdef MAVLINK_WPM_NO_PRINTF mavlink_missionlib_send_gcs_string("REJ. WP CMD: target id mismatch"); #else if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n"); #endif } } break; case MAVLINK_MSG_ID_MISSION_ITEM: { mavlink_mission_item_t wp; mavlink_msg_mission_item_decode(msg, &wp); mavlink_missionlib_send_gcs_string("GOT WP"); // printf("sysid=%d, current_partner_sysid=%d\n", msg->sysid, wpm->current_partner_sysid); // printf("compid=%d, current_partner_compid=%d\n", msg->compid, wpm->current_partner_compid); // if((msg->sysid == wpm->current_partner_sysid && msg->compid == wpm->current_partner_compid) && (wp.target_system == mavlink_system.sysid /*&& wp.target_component == mavlink_wpm_comp_id*/)) if (wp.target_system == mavlink_system.sysid && wp.target_component == mavlink_wpm_comp_id) { wpm->timestamp_lastaction = now; // printf("wpm->current_state=%u, wp.seq = %d, wpm->current_wp_id=%d\n", wpm->current_state, wp.seq, wpm->current_wp_id); // wpm->current_state = MAVLINK_WPM_STATE_GETLIST;//removeme debug XXX TODO //ensure that we are in the correct state and that the first waypoint has id 0 and the following waypoints have the correct ids if ((wpm->current_state == MAVLINK_WPM_STATE_GETLIST && wp.seq == 0) || (wpm->current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS && wp.seq == wpm->current_wp_id && wp.seq < wpm->current_count)) { //mavlink_missionlib_send_gcs_string("DEBUG 2"); // if (verbose && wpm->current_state == MAVLINK_WPM_STATE_GETLIST) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM %u from %u changing state to MAVLINK_WPM_STATE_GETLIST_GETWPS\n", wp.seq, msg->sysid); // if (verbose && wpm->current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS && wp.seq == wpm->current_wp_id) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM %u from %u\n", wp.seq, msg->sysid); // if (verbose && wpm->current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS && wp.seq-1 == wpm->current_wp_id) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM %u (again) from %u\n", wp.seq, msg->sysid); // wpm->current_state = MAVLINK_WPM_STATE_GETLIST_GETWPS; mavlink_mission_item_t *newwp = &(wpm->rcv_waypoints[wp.seq]); memcpy(newwp, &wp, sizeof(mavlink_mission_item_t)); // printf("WP seq: %d\n",wp.seq); wpm->current_wp_id = wp.seq + 1; // if (verbose) // printf ("Added new waypoint to list. X= %f\t Y= %f\t Z= %f\t Yaw= %f\n", newwp->x, newwp->y, newwp->z, newwp->param4); // printf ("Added new waypoint to list. X= %f\t Y= %f\t Z= %f\t Yaw= %f\n", newwp->x, newwp->y, newwp->z, newwp->param4); // printf ("wpm->current_wp_id =%d, wpm->current_count=%d\n\n", wpm->current_wp_id, wpm->current_count); if (wpm->current_wp_id == wpm->current_count && wpm->current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS) { mavlink_missionlib_send_gcs_string("GOT ALL WPS"); // if (verbose) // printf("Got all %u waypoints, changing state to MAVLINK_WPM_STATE_IDLE\n", wpm->current_count); mavlink_wpm_send_waypoint_ack(wpm->current_partner_sysid, wpm->current_partner_compid, 0); if (wpm->current_active_wp_id > wpm->rcv_size - 1) { wpm->current_active_wp_id = wpm->rcv_size - 1; } // switch the waypoints list // FIXME CHECK!!! uint32_t i; for (i = 0; i < wpm->current_count; ++i) { wpm->waypoints[i] = wpm->rcv_waypoints[i]; } wpm->size = wpm->current_count; //get the new current waypoint for (i = 0; i < wpm->size; i++) { if (wpm->waypoints[i].current == 1) { wpm->current_active_wp_id = i; //// if (verbose) // printf("New current waypoint %u\n", current_active_wp_id); wpm->yaw_reached = false; wpm->pos_reached = false; mavlink_wpm_send_waypoint_current(wpm->current_active_wp_id); mavlink_wpm_send_setpoint(wpm->current_active_wp_id); wpm->timestamp_firstinside_orbit = 0; break; } } if (i == wpm->size) { wpm->current_active_wp_id = -1; wpm->yaw_reached = false; wpm->pos_reached = false; wpm->timestamp_firstinside_orbit = 0; } wpm->current_state = MAVLINK_WPM_STATE_IDLE; } else { mavlink_wpm_send_waypoint_request(wpm->current_partner_sysid, wpm->current_partner_compid, wpm->current_wp_id); } } else { if (wpm->current_state == MAVLINK_WPM_STATE_IDLE) { //we're done receiving waypoints, answer with ack. mavlink_wpm_send_waypoint_ack(wpm->current_partner_sysid, wpm->current_partner_compid, 0); printf("Received MAVLINK_MSG_ID_MISSION_ITEM while state=MAVLINK_WPM_STATE_IDLE, answered with WAYPOINT_ACK.\n"); } // if (verbose) { if (!(wpm->current_state == MAVLINK_WPM_STATE_GETLIST || wpm->current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS)) { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u because i'm doing something else already (state=%i).\n", wp.seq, wpm->current_state); break; } else if (wpm->current_state == MAVLINK_WPM_STATE_GETLIST) { if (!(wp.seq == 0)) { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM because the first waypoint ID (%u) was not 0.\n", wp.seq); } else { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u - FIXME: missed error description\n", wp.seq); } } else if (wpm->current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS) { if (!(wp.seq == wpm->current_wp_id)) { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM because the waypoint ID (%u) was not the expected %u.\n", wp.seq, wpm->current_wp_id); mavlink_wpm_send_waypoint_request(wpm->current_partner_sysid, wpm->current_partner_compid, wpm->current_wp_id); } else if (!(wp.seq < wpm->current_count)) { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM because the waypoint ID (%u) was out of bounds.\n", wp.seq); } else { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u - FIXME: missed error description\n", wp.seq); } } else { // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u - FIXME: missed error description\n", wp.seq); } } } } else { //we we're target but already communicating with someone else if ((wp.target_system == mavlink_system.sysid /*&& wp.target_component == mavlink_wpm_comp_id*/) && !(msg->sysid == wpm->current_partner_sysid && msg->compid == wpm->current_partner_compid) && wpm->current_state != MAVLINK_WPM_STATE_IDLE) { // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u from ID %u because i'm already talking to ID %u.\n", wp.seq, msg->sysid, wpm->current_partner_sysid); } else if (wp.target_system == mavlink_system.sysid /* && wp.target_component == mavlink_wpm_comp_id*/) { // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u from ID %u because i have no idea what to do with it\n", wp.seq, msg->sysid); } } break; } case MAVLINK_MSG_ID_MISSION_CLEAR_ALL: { mavlink_mission_clear_all_t wpca; mavlink_msg_mission_clear_all_decode(msg, &wpca); if (wpca.target_system == mavlink_system.sysid /*&& wpca.target_component == mavlink_wpm_comp_id */ && wpm->current_state == MAVLINK_WPM_STATE_IDLE) { wpm->timestamp_lastaction = now; // if (verbose) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_CLEAR_LIST from %u deleting all waypoints\n", msg->sysid); // Delete all waypoints wpm->size = 0; wpm->current_active_wp_id = -1; wpm->yaw_reached = false; wpm->pos_reached = false; } else if (wpca.target_system == mavlink_system.sysid /*&& wpca.target_component == mavlink_wpm_comp_id */ && wpm->current_state != MAVLINK_WPM_STATE_IDLE) { // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_CLEAR_LIST from %u because i'm doing something else already (state=%i).\n", msg->sysid, wpm->current_state); } break; } default: { // if (debug) // printf("Waypoint: received message of unknown type"); break; } } check_waypoints_reached(now, global_pos, local_pos); }
static inline void MissionRequest(mavlink_message_t* handle_msg) { mavlink_mission_request_t packet; //send_text((uint8_t*)"waypoint request\r\n"); //DPRINT("mission request\r\n"); // Check if in sending waypoint mode ... if (!mavlink_flags.mavlink_sending_waypoints) { DPRINT("mission request not valid, no longer sending\r\n"); return; } // decode mavlink_msg_mission_request_decode(handle_msg, &packet); if (mavlink_check_target(packet.target_system, packet.target_component)) return; mavlink_waypoint_timeout = MAVLINK_WAYPOINT_TIMEOUT; mavlink_waypoint_requested_sequence_number = packet.seq; DPRINT("mission request: packet.seq %u\r\n", packet.seq); mavlink_waypoint_frame = MAV_FRAME_GLOBAL; // reference frame if (mavlink_waypoint_requested_sequence_number == waypointIndex) { mavlink_waypoint_current = true; } else { mavlink_waypoint_current = false; } // send waypoint mavlink_flags.mavlink_send_specific_waypoint = 1; /************** Not converted to MAVLink wire protocol 1.0 yet *******************/ //uint8_t action = MAV_ACTION_NAVIGATE; // action //uint8_t orbit_direction = 0; // clockwise(0), counter-clockwise(1) //float orbit = 0; // loiter radius //float param1 = 0, param2 = 0; //switch(tell_command.id) //{ //case CMD_WAYPOINT: // navigate //action = MAV_ACTION_NAVIGATE; // action //break; // case CMD_LOITER_TIME: // loiter //orbit = get(PARAM_WP_RADIUS); // XXX setting loiter radius as waypoint acceptance radius //action = MAV_ACTION_LOITER; // action //param1 = get(PARAM_WP_RADIUS); //param2 = tell_command.p1*100; // loiter time //break; // case CMD_TAKEOFF: // takeoff //action = MAV_ACTION_TAKEOFF; //break; //case CMD_LAND: // land //action = MAV_ACTION_LAND; //break; //defaut: //gcs.send_text("command not handled"); //break; //} // time that the mav should loiter in milliseconds //uint8_t current = 0; // 1 (true), 0 (false) //if (packet.seq == get(PARAM_WP_INDEX)) current = 1; //float yaw_dir = 0; // yaw orientation in radians, 0 = north XXX: what does this do? //uint8_t autocontinue = 1; // 1 (true), 0 (false) //float x = tell_command.lng/1.0e7; // local (x), global (longitude) //float y = tell_command.lat/1.0e7; // local (y), global (latitude) //float z = tell_command.alt/1.0e2; // local (z), global (altitude) // note XXX: documented x,y,z order does not match with gps raw //mavlink_msg_waypoint_send(chan,handle_msg->sysid, //handle_msg->compid,packet.seq,frame,action, //orbit,orbit_direction,param1,param2,current,x,y,z,yaw_dir,autocontinue); // update last waypoint comm stamp //global_data.waypoint_timelast_send = millis(); }
void mavlink_handleMessage(mavlink_message_t* msg) { mavlink_message_t msg2; char sysmsg_str[1024]; switch (msg->msgid) { case MAVLINK_MSG_ID_HEARTBEAT: { mavlink_heartbeat_t packet; mavlink_msg_heartbeat_decode(msg, &packet); droneType = packet.type; autoPilot = packet.autopilot; if (packet.base_mode == MAV_MODE_MANUAL_ARMED) { ModelData.mode = MODEL_MODE_MANUAL; } else if (packet.base_mode == 128 + 64 + 16) { ModelData.mode = MODEL_MODE_RTL; } else if (packet.base_mode == 128 + 16) { ModelData.mode = MODEL_MODE_POSHOLD; } else if (packet.base_mode == 128 + 4) { ModelData.mode = MODEL_MODE_MISSION; } if (packet.system_status == MAV_STATE_ACTIVE) { ModelData.armed = MODEL_ARMED; } else { ModelData.armed = MODEL_DISARMED; } // SDL_Log("Heartbeat: %i, %i, %i\n", ModelData.armed, ModelData.mode, ModelData.status); ModelData.heartbeat = 100; // sprintf(sysmsg_str, "Heartbeat: %i", (int)time(0)); if ((*msg).sysid != 0xff) { ModelData.sysid = (*msg).sysid; ModelData.compid = (*msg).compid; if (mavlink_maxparam == 0) { mavlink_start_feeds(); } } redraw_flag = 1; break; } case MAVLINK_MSG_ID_RC_CHANNELS_SCALED: { mavlink_rc_channels_scaled_t packet; mavlink_msg_rc_channels_scaled_decode(msg, &packet); // SDL_Log("Radio: %i,%i,%i\n", packet.chan1_scaled, packet.chan2_scaled, packet.chan3_scaled); /* if ((int)packet.chan6_scaled > 1000) { mode = MODE_MISSION; } else if ((int)packet.chan6_scaled < -1000) { mode = MODE_MANUEL; } else { mode = MODE_POSHOLD; } if ((int)packet.chan7_scaled > 1000) { mode = MODE_RTL; } else if ((int)packet.chan7_scaled < -1000) { mode = MODE_SETHOME; } */ ModelData.radio[0] = (int)packet.chan1_scaled / 100.0; ModelData.radio[1] = (int)packet.chan2_scaled / 100.0; ModelData.radio[2] = (int)packet.chan3_scaled / 100.0; ModelData.radio[3] = (int)packet.chan4_scaled / 100.0; ModelData.radio[4] = (int)packet.chan5_scaled / 100.0; ModelData.radio[5] = (int)packet.chan6_scaled / 100.0; ModelData.radio[6] = (int)packet.chan7_scaled / 100.0; ModelData.radio[7] = (int)packet.chan8_scaled / 100.0; redraw_flag = 1; break; } case MAVLINK_MSG_ID_SCALED_PRESSURE: { mavlink_scaled_pressure_t packet; mavlink_msg_scaled_pressure_decode(msg, &packet); // SDL_Log("BAR;%i;%0.2f;%0.2f;%0.2f\n", time(0), packet.press_abs, packet.press_diff, packet.temperature / 100.0); // redraw_flag = 1; break; } case MAVLINK_MSG_ID_ATTITUDE: { mavlink_attitude_t packet; mavlink_msg_attitude_decode(msg, &packet); ModelData.roll = toDeg(packet.roll); ModelData.pitch = toDeg(packet.pitch); if (toDeg(packet.yaw) < 0.0) { ModelData.yaw = 360.0 + toDeg(packet.yaw); } else { ModelData.yaw = toDeg(packet.yaw); } mavlink_update_yaw = 1; // SDL_Log("ATT;%i;%0.2f;%0.2f;%0.2f\n", time(0), toDeg(packet.roll), toDeg(packet.pitch), toDeg(packet.yaw)); redraw_flag = 1; break; } case MAVLINK_MSG_ID_SCALED_IMU: { // SDL_Log("SCALED_IMU\n"); break; } case MAVLINK_MSG_ID_GPS_RAW_INT: { mavlink_gps_raw_int_t packet; mavlink_msg_gps_raw_int_decode(msg, &packet); if (packet.lat != 0.0) { GPS_found = 1; ModelData.p_lat = (float)packet.lat / 10000000.0; ModelData.p_long = (float)packet.lon / 10000000.0; ModelData.p_alt = (float)packet.alt / 1000.0; ModelData.speed = (float)packet.vel / 100.0; ModelData.numSat = packet.satellites_visible; ModelData.gpsfix = packet.fix_type; redraw_flag = 1; } break; } case MAVLINK_MSG_ID_RC_CHANNELS_RAW: { // SDL_Log("RC_CHANNELS_RAW\n"); break; } case MAVLINK_MSG_ID_SERVO_OUTPUT_RAW: { // SDL_Log("SERVO_OUTPUT_RAW\n"); break; } case MAVLINK_MSG_ID_SYS_STATUS: { mavlink_sys_status_t packet; mavlink_msg_sys_status_decode(msg, &packet); // SDL_Log("%0.1f %%, %0.3f V)\n", packet.load / 10.0, packet.voltage_battery / 1000.0); ModelData.voltage = packet.voltage_battery / 1000.0; ModelData.load = packet.load / 10.0; redraw_flag = 1; break; } case MAVLINK_MSG_ID_STATUSTEXT: { mavlink_statustext_t packet; mavlink_msg_statustext_decode(msg, &packet); SDL_Log("mavlink: ## %s ##\n", packet.text); sys_message((char *)packet.text); redraw_flag = 1; break; } case MAVLINK_MSG_ID_PARAM_VALUE: { mavlink_param_value_t packet; mavlink_msg_param_value_decode(msg, &packet); char var[101]; uint16_t n1 = 0; uint16_t n2 = 0; for (n1 = 0; n1 < strlen(packet.param_id); n1++) { if (packet.param_id[n1] != 9 && packet.param_id[n1] != ' ' && packet.param_id[n1] != '\t') { var[n2++] = packet.param_id[n1]; } } var[n2++] = 0; // MAV_VAR_FLOAT=0, /* 32 bit float | */ // MAV_VAR_UINT8=1, /* 8 bit unsigned integer | */ // MAV_VAR_INT8=2, /* 8 bit signed integer | */ // MAV_VAR_UINT16=3, /* 16 bit unsigned integer | */ // MAV_VAR_INT16=4, /* 16 bit signed integer | */ // MAV_VAR_UINT32=5, /* 32 bit unsigned integer | */ // MAV_VAR_INT32=6, /* 32 bit signed integer | */ sprintf(sysmsg_str, "PARAM_VALUE (%i/%i): #%s# = %f (Type: %i)", packet.param_index + 1, packet.param_count, var, packet.param_value, packet.param_type); SDL_Log("mavlink: %s\n", sysmsg_str); sys_message(sysmsg_str); mavlink_maxparam = packet.param_count; mavlink_timeout = 0; mavlink_set_value(var, packet.param_value, packet.param_type, packet.param_index); if (packet.param_index + 1 == packet.param_count || packet.param_index % 10 == 0) { mavlink_param_xml_meta_load(); } redraw_flag = 1; break; } case MAVLINK_MSG_ID_MISSION_COUNT: { mavlink_mission_count_t packet; mavlink_msg_mission_count_decode(msg, &packet); sprintf(sysmsg_str, "MISSION_COUNT: %i\n", packet.count); sys_message(sysmsg_str); mission_max = packet.count; if (mission_max > 0) { mavlink_msg_mission_request_pack(127, 0, &msg2, ModelData.sysid, ModelData.compid, 0); mavlink_send_message(&msg2); } redraw_flag = 1; break; } case MAVLINK_MSG_ID_MISSION_ACK: { SDL_Log("mavlink: Mission-Transfer ACK\n"); break; } case MAVLINK_MSG_ID_MISSION_REQUEST: { mavlink_mission_request_t packet; mavlink_msg_mission_request_decode(msg, &packet); uint16_t id = packet.seq; uint16_t id2 = packet.seq; uint16_t type = 0; if (ModelData.teletype == TELETYPE_MEGAPIRATE_NG || ModelData.teletype == TELETYPE_ARDUPILOT) { if (id2 > 0) { id2 = id2 - 1; } else { SDL_Log("mavlink: WORKAROUND: first WP == HOME ?\n"); } } sprintf(sysmsg_str, "sending Waypoint (%i): %s\n", id, WayPoints[1 + id2].name); sys_message(sysmsg_str); if (strcmp(WayPoints[1 + id2].command, "WAYPOINT") == 0) { SDL_Log("mavlink: Type: MAV_CMD_NAV_WAYPOINT\n"); type = MAV_CMD_NAV_WAYPOINT; } else if (strcmp(WayPoints[1 + id2].command, "RTL") == 0) { SDL_Log("mavlink: Type: MAV_CMD_NAV_RETURN_TO_LAUNCH\n"); type = MAV_CMD_NAV_RETURN_TO_LAUNCH; } else if (strcmp(WayPoints[1 + id2].command, "LAND") == 0) { SDL_Log("mavlink: Type: MAV_CMD_NAV_LAND\n"); type = MAV_CMD_NAV_LAND; } else if (strcmp(WayPoints[1 + id2].command, "TAKEOFF") == 0) { SDL_Log("mavlink: Type: MAV_CMD_NAV_TAKEOFF\n"); type = MAV_CMD_NAV_TAKEOFF; } else { SDL_Log("mavlink: Type: UNKNOWN\n"); type = MAV_CMD_NAV_WAYPOINT; } sprintf(sysmsg_str, "SENDING MISSION_ITEM: %i: %f, %f, %f\n", id, WayPoints[1 + id2].p_lat, WayPoints[1 + id2].p_long, WayPoints[1 + id2].p_alt); SDL_Log("mavlink: %s\n", sysmsg_str); mavlink_msg_mission_item_pack(127, 0, &msg2, ModelData.sysid, ModelData.compid, id, 0, type, 0.0, 0.0, WayPoints[1 + id2].radius, WayPoints[1 + id2].wait, WayPoints[1 + id2].orbit, WayPoints[1 + id2].yaw, WayPoints[1 + id2].p_lat, WayPoints[1 + id2].p_long, WayPoints[1 + id2].p_alt); mavlink_send_message(&msg2); /* mavlink_msg_mission_item_pack(system_id, component_id, &msg , packet1.target_system , packet1.target_component , packet1.seq , packet1.frame , packet1.command , packet1.current , packet1.autocontinue , packet1.param1 , packet1.param2 , packet1.param3 , packet1.param4 , packet1.x , packet1.y , packet1.z ); float param1; ///< PARAM1 / For NAV command MISSIONs: Radius in which the MISSION is accepted as reached, in meters float param2; ///< PARAM2 / For NAV command MISSIONs: Time that the MAV should stay inside the PARAM1 radius before advancing, in milliseconds float param3; ///< PARAM3 / For LOITER command MISSIONs: Orbit to circle around the MISSION, in meters. If positive the orbit direction should be clockwise, if negative the orbit direction should be counter-clockwise. float param4; ///< PARAM4 / For NAV and LOITER command MISSIONs: Yaw orientation in degrees, [0..360] 0 = NORTH float x; ///< PARAM5 / local: x position, global: latitude float y; ///< PARAM6 / y position: global: longitude float z; ///< PARAM7 / z position: global: altitude uint16_t seq; ///< Sequence uint16_t command; ///< The scheduled action for the MISSION. see MAV_CMD in common.xml MAVLink specs uint8_t target_system; ///< System ID uint8_t target_component; ///< Component ID uint8_t frame; ///< The coordinate system of the MISSION. see MAV_FRAME in mavlink_types.h uint8_t current; ///< false:0, true:1 uint8_t autocontinue; ///< autocontinue to next wp */ redraw_flag = 1; break; } case MAVLINK_MSG_ID_MISSION_ITEM: { mavlink_mission_item_t packet; mavlink_msg_mission_item_decode(msg, &packet); sprintf(sysmsg_str, "RECEIVED MISSION_ITEM: %i/%i: %f, %f, %f (%i)\n", packet.seq, mission_max, packet.x, packet.y, packet.z, packet.frame); SDL_Log("mavlink: %s\n", sysmsg_str); sys_message(sysmsg_str); if (packet.seq < mission_max - 1) { mavlink_msg_mission_request_pack(127, 0, &msg2, ModelData.sysid, ModelData.compid, packet.seq + 1); mavlink_send_message(&msg2); } else { mavlink_msg_mission_ack_pack(127, 0, &msg2, ModelData.sysid, ModelData.compid, 15); mavlink_send_message(&msg2); } if (ModelData.teletype == TELETYPE_MEGAPIRATE_NG || ModelData.teletype == TELETYPE_ARDUPILOT) { if (packet.seq > 0) { packet.seq = packet.seq - 1; } else { SDL_Log("mavlink: WORKAROUND: ignore first WP\n"); break; } } SDL_Log("mavlink: getting WP(%i): %f, %f\n", packet.seq, packet.x, packet.y); switch (packet.command) { case MAV_CMD_NAV_WAYPOINT: { strcpy(WayPoints[1 + packet.seq].command, "WAYPOINT"); break; } case MAV_CMD_NAV_LOITER_UNLIM: { strcpy(WayPoints[1 + packet.seq].command, "LOITER_UNLIM"); break; } case MAV_CMD_NAV_LOITER_TURNS: { strcpy(WayPoints[1 + packet.seq].command, "LOITER_TURNS"); break; } case MAV_CMD_NAV_LOITER_TIME: { strcpy(WayPoints[1 + packet.seq].command, "LOITER_TIME"); break; } case MAV_CMD_NAV_RETURN_TO_LAUNCH: { strcpy(WayPoints[1 + packet.seq].command, "RTL"); break; } case MAV_CMD_NAV_LAND: { strcpy(WayPoints[1 + packet.seq].command, "LAND"); break; } case MAV_CMD_NAV_TAKEOFF: { strcpy(WayPoints[1 + packet.seq].command, "TAKEOFF"); break; } default: { sprintf(WayPoints[1 + packet.seq].command, "CMD:%i", packet.command); break; } } if (packet.x == 0.0) { packet.x = 0.00001; } if (packet.y == 0.0) { packet.y = 0.00001; } if (packet.z == 0.0) { packet.z = 0.00001; } WayPoints[1 + packet.seq].p_lat = packet.x; WayPoints[1 + packet.seq].p_long = packet.y; WayPoints[1 + packet.seq].p_alt = packet.z; WayPoints[1 + packet.seq].yaw = packet.param4; sprintf(WayPoints[1 + packet.seq].name, "WP%i", packet.seq + 1); WayPoints[1 + packet.seq + 1].p_lat = 0.0; WayPoints[1 + packet.seq + 1].p_long = 0.0; WayPoints[1 + packet.seq + 1].p_alt = 0.0; WayPoints[1 + packet.seq + 1].yaw = 0.0; WayPoints[1 + packet.seq + 1].name[0] = 0; WayPoints[1 + packet.seq + 1].command[0] = 0; /* float param1; ///< PARAM1 / For NAV command MISSIONs: Radius in which the MISSION is accepted as reached, in meters float param2; ///< PARAM2 / For NAV command MISSIONs: Time that the MAV should stay inside the PARAM1 radius before advancing, in milliseconds float param3; ///< PARAM3 / For LOITER command MISSIONs: Orbit to circle around the MISSION, in meters. If positive the orbit direction should be clockwise, if negative the orbit direction should be counter-clockwise. float param4; ///< PARAM4 / For NAV and LOITER command MISSIONs: Yaw orientation in degrees, [0..360] 0 = NORTH float x; ///< PARAM5 / local: x position, global: latitude float y; ///< PARAM6 / y position: global: longitude float z; ///< PARAM7 / z position: global: altitude uint16_t seq; ///< Sequence uint16_t command; ///< The scheduled action for the MISSION. see MAV_CMD in common.xml MAVLink specs uint8_t target_system; ///< System ID uint8_t target_component; ///< Component ID uint8_t frame; ///< The coordinate system of the MISSION. see MAV_FRAME in mavlink_types.h uint8_t current; ///< false:0, true:1 uint8_t autocontinue; ///< autocontinue to next wp GCS_MAVLink/message_definitions_v1.0/common.xml: <entry value="0" name="MAV_FRAME_GLOBAL"> GCS_MAVLink/message_definitions_v1.0/common.xml: <entry value="1" name="MAV_FRAME_LOCAL_NED"> GCS_MAVLink/message_definitions_v1.0/common.xml: <entry value="2" name="MAV_FRAME_MISSION"> GCS_MAVLink/message_definitions_v1.0/common.xml: <entry value="3" name="MAV_FRAME_GLOBAL_RELATIVE_ALT"> GCS_MAVLink/message_definitions_v1.0/common.xml: <entry value="4" name="MAV_FRAME_LOCAL_ENU"> */ redraw_flag = 1; break; } case MAVLINK_MSG_ID_MISSION_CURRENT: { mavlink_mission_current_t packet; mavlink_msg_mission_current_decode(msg, &packet); // SDL_Log("mavlink: ## Active_WP %f ##\n", packet.seq); uav_active_waypoint = (uint8_t)packet.seq; break; } case MAVLINK_MSG_ID_RAW_IMU: { mavlink_raw_imu_t packet; mavlink_msg_raw_imu_decode(msg, &packet); /* SDL_Log("## IMU_RAW_ACC_X %i ##\n", packet.xacc); SDL_Log("## IMU_RAW_ACC_Y %i ##\n", packet.yacc); SDL_Log("## IMU_RAW_ACC_Z %i ##\n", packet.zacc); SDL_Log("## IMU_RAW_GYRO_X %i ##\n", packet.xgyro); SDL_Log("## IMU_RAW_GYRO_Y %i ##\n", packet.ygyro); SDL_Log("## IMU_RAW_GYRO_Z %i ##\n", packet.zgyro); SDL_Log("## IMU_RAW_MAG_X %i ##\n", packet.xmag); SDL_Log("## IMU_RAW_MAG_Y %i ##\n", packet.ymag); SDL_Log("## IMU_RAW_MAG_Z %i ##\n", packet.zmag); */ ModelData.acc_x = (float)packet.xacc / 1000.0; ModelData.acc_y = (float)packet.yacc / 1000.0; ModelData.acc_z = (float)packet.zacc / 1000.0; ModelData.gyro_x = (float)packet.zgyro; ModelData.gyro_y = (float)packet.zgyro; ModelData.gyro_z = (float)packet.zgyro; redraw_flag = 1; break; } case MAVLINK_MSG_ID_NAV_CONTROLLER_OUTPUT: { mavlink_nav_controller_output_t packet; mavlink_msg_nav_controller_output_decode(msg, &packet); /* nav_roll nav_pitch alt_error aspd_error xtrack_error nav_bearing target_bearing wp_dist */ break; } case MAVLINK_MSG_ID_VFR_HUD: { mavlink_vfr_hud_t packet; mavlink_msg_vfr_hud_decode(msg, &packet); // SDL_Log("## pa %f ##\n", packet.airspeed); // SDL_Log("## pg %f ##\n", packet.groundspeed); // SDL_Log("## palt %f ##\n", packet.alt); if (GPS_found == 0) { ModelData.p_alt = packet.alt; } // SDL_Log("## pc %f ##\n", packet.climb); // SDL_Log("## ph %i ##\n", packet.heading); // SDL_Log("## pt %i ##\n", packet.throttle); break; } case MAVLINK_MSG_ID_RADIO: { mavlink_radio_t packet; mavlink_msg_radio_decode(msg, &packet); SDL_Log("mavlink: ## rxerrors %i ##\n", packet.rxerrors); SDL_Log("mavlink: ## fixed %i ##\n", packet.fixed); SDL_Log("mavlink: ## rssi %i ##\n", packet.rssi); SDL_Log("mavlink: ## remrssi %i ##\n", packet.remrssi); SDL_Log("mavlink: ## txbuf %i ##\n", packet.txbuf); SDL_Log("mavlink: ## noise %i ##\n", packet.noise); SDL_Log("mavlink: ## remnoise %i ##\n", packet.remnoise); break; } default: { // SDL_Log(" ## MSG_ID == %i ##\n", msg->msgid); break; } } }
void mission_read_waypoint_list(void) { uint32_t start_time, cur_time; waypoint_t *cur_wp = waypoint_info.waypoint_list; //First node of the waypoint list mavlink_mission_request_t mmrt; mavlink_msg_mission_count_pack( 1, 0, &msg, 255, 0, waypoint_info.waypoint_count /* Waypoint count */ ); send_package(&msg); int i; for(i = 0; i < waypoint_info.waypoint_count; i++) { start_time = get_system_time_ms(); /* Waiting for mission request command */ while(received_msg.msgid != 40) { cur_time = get_system_time_ms(); //Suspend the task to read the new message vTaskDelay(100); /* Time out, leave */ if((cur_time - start_time) > TIMEOUT_CNT) return; } /* Waiting for mission request command */ mavlink_msg_mission_request_decode(&received_msg, &mmrt); /* Clear the received message */ clear_message_id(&received_msg); /* Send the waypoint to the ground station */ mavlink_msg_mission_item_pack( 1, 0, &msg, 255, 0, cur_wp->data.seq, cur_wp->data.frame, cur_wp->data.command, cur_wp->data.current, cur_wp->data.autocontinue, cur_wp->data.param1, cur_wp->data.param2, cur_wp->data.param3, cur_wp->data.param4, cur_wp->data.x, cur_wp->data.y, cur_wp->data.z ); send_package(&msg); cur_wp = cur_wp->next; } /* Send a mission ack Message at the end */ mavlink_msg_mission_ack_pack(1, 0, &msg, 255, 0, 0); send_package(&msg); }