/* * AP_Autopilot.cpp * * Created on: Apr 30, 2011 * Author: jgoppert */ #include "AP_Autopilot.h" namespace apo { class AP_HardwareAbstractionLayer; AP_Autopilot::AP_Autopilot(AP_Navigator * navigator, AP_Guide * guide, AP_Controller * controller, AP_HardwareAbstractionLayer * hal, float loop0Rate, float loop1Rate, float loop2Rate, float loop3Rate) : Loop(loop0Rate, callback0, this), _navigator(navigator), _guide(guide), _controller(controller), _hal(hal), _loop0Rate(loop0Rate), _loop1Rate(loop1Rate), _loop2Rate(loop2Rate), _loop3Rate(loop3Rate), _loop4Rate(loop3Rate), callback0Calls(0), clockInit(millis()) { hal->setState(MAV_STATE_BOOT); hal->gcs->sendMessage(MAVLINK_MSG_ID_HEARTBEAT); hal->gcs->sendMessage(MAVLINK_MSG_ID_SYS_STATUS); /* * Calibration */ hal->setState(MAV_STATE_CALIBRATING); hal->gcs->sendMessage(MAVLINK_MSG_ID_HEARTBEAT); hal->gcs->sendMessage(MAVLINK_MSG_ID_SYS_STATUS); if (navigator) navigator->calibrate(); /* * Look for valid initial state */ while (_navigator) { // letc gcs known we are alive hal->gcs->sendMessage(MAVLINK_MSG_ID_HEARTBEAT); hal->gcs->sendMessage(MAVLINK_MSG_ID_SYS_STATUS); if (hal->getMode() == MODE_LIVE) { _navigator->updateSlow(0); if (hal->gps) { if (hal->gps->fix) { break; } else { hal->gps->update(); hal->gcs->sendText(SEVERITY_LOW, PSTR("waiting for gps lock\n")); hal->debug->printf_P(PSTR("waiting for gps lock\n")); } } else { // no gps, can skip break; } } else if (hal->getMode() == MODE_HIL_CNTL) { // hil hal->hil->sendMessage(MAVLINK_MSG_ID_HEARTBEAT); hal->hil->receive(); Serial.println("HIL Receive Called"); if (_navigator->getTimeStamp() != 0) { // give hil a chance to send some packets for (int i = 0; i < 5; i++) { hal->debug->println_P(PSTR("reading initial hil packets")); hal->gcs->sendText(SEVERITY_LOW, PSTR("reading initial hil packets")); delay(1000); } break; } hal->debug->println_P(PSTR("waiting for hil packet")); } delay(1000); } AP_MavlinkCommand::home.setAlt(_navigator->getAlt()); AP_MavlinkCommand::home.setLat(_navigator->getLat()); AP_MavlinkCommand::home.setLon(_navigator->getLon()); AP_MavlinkCommand::home.setCommand(MAV_CMD_NAV_WAYPOINT); AP_MavlinkCommand::home.save(); _hal->debug->printf_P(PSTR("\nhome before load lat: %f deg, lon: %f deg, cmd: %d\n"), AP_MavlinkCommand::home.getLat()*rad2Deg, AP_MavlinkCommand::home.getLon()*rad2Deg, AP_MavlinkCommand::home.getCommand()); AP_MavlinkCommand::home.load(); _hal->debug->printf_P(PSTR("\nhome after load lat: %f deg, lon: %f deg, cmd: %d\n"), AP_MavlinkCommand::home.getLat()*rad2Deg, AP_MavlinkCommand::home.getLon()*rad2Deg, AP_MavlinkCommand::home.getCommand()); /* * Attach loops */ hal->debug->println_P(PSTR("attaching loops")); subLoops().push_back(new Loop(getLoopRate(1), callback1, this)); subLoops().push_back(new Loop(getLoopRate(2), callback2, this)); subLoops().push_back(new Loop(getLoopRate(3), callback3, this)); subLoops().push_back(new Loop(getLoopRate(4), callback4, this)); hal->debug->println_P(PSTR("running")); hal->gcs->sendText(SEVERITY_LOW, PSTR("running")); if (hal->getMode() == MODE_LIVE) { hal->setState(MAV_STATE_ACTIVE); } else { hal->setState(MAV_STATE_HILSIM); } /* * Radio setup */ hal->debug->println_P(PSTR("initializing radio")); APM_RC.Init(); // APM Radio initialization, // start this after control loop is running clockInit = millis(); } void AP_Autopilot::callback0(void * data) { AP_Autopilot * apo = (AP_Autopilot *) data; //apo->hal()->debug->println_P(PSTR("callback 0")); /* * ahrs update */ apo->callback0Calls++; if (apo->getNavigator()) apo->getNavigator()->updateFast(1.0 / apo->getLoopRate(0)); } void AP_Autopilot::callback1(void * data) { AP_Autopilot * apo = (AP_Autopilot *) data; //apo->getHal()->debug->println_P(PSTR("callback 1")); /* * hardware in the loop */ if (apo->getHal()->hil && apo->getHal()->getMode() != MODE_LIVE) { apo->getHal()->hil->receive(); apo->getHal()->hil->sendMessage(MAVLINK_MSG_ID_RC_CHANNELS_SCALED); } /* * update control laws */ if (apo->getController()) { //apo->getHal()->debug->println_P(PSTR("updating controller")); apo->getController()->update(1. / apo->getLoopRate(1)); } /* char msg[50]; sprintf(msg, "c_hdg: %f, c_thr: %f", apo->guide()->headingCommand, apo->guide()->groundSpeedCommand); apo->hal()->gcs->sendText(AP_CommLink::SEVERITY_LOW, msg); */ } void AP_Autopilot::callback2(void * data) { AP_Autopilot * apo = (AP_Autopilot *) data; //apo->getHal()->debug->println_P(PSTR("callback 2")); /* * update guidance laws */ if (apo->getGuide()) { //apo->getHal()->debug->println_P(PSTR("updating guide")); apo->getGuide()->update(); } /* * slow navigation loop update */ if (apo->getNavigator()) { apo->getNavigator()->updateSlow(1.0 / apo->getLoopRate(2)); } /* * send telemetry */ if (apo->getHal()->gcs) { apo->getHal()->gcs->sendMessage(MAVLINK_MSG_ID_ATTITUDE); } /* * handle ground control station communication */ if (apo->getHal()->gcs) { // send messages apo->getHal()->gcs->requestCmds(); apo->getHal()->gcs->sendParameters(); // receive messages apo->getHal()->gcs->receive(); } /* * navigator debug */ /* if (apo->navigator()) { apo->getHal()->debug->printf_P(PSTR("roll: %f deg\tpitch: %f deg\tyaw: %f deg\n"), apo->navigator()->getRoll()*rad2Deg, apo->navigator()->getPitch()*rad2Deg, apo->navigator()->getYaw()*rad2Deg); apo->getHal()->debug->printf_P(PSTR("lat: %f deg\tlon: %f deg\talt: %f m\n"), apo->navigator()->getLat()*rad2Deg, apo->navigator()->getLon()*rad2Deg, apo->navigator()->getAlt()); } */ } void AP_Autopilot::callback3(void * data) { AP_Autopilot * apo = (AP_Autopilot *) data; //apo->getHal()->debug->println_P(PSTR("callback 3")); /* * send telemetry */ if (apo->getHal()->gcs) { // send messages apo->getHal()->gcs->sendMessage(MAVLINK_MSG_ID_GPS_RAW); //apo->getHal()->gcs->sendMessage(MAVLINK_MSG_ID_RC_CHANNELS_SCALED); //apo->getHal()->gcs->sendMessage(MAVLINK_MSG_ID_GLOBAL_POSITION); //apo->getHal()->gcs->sendMessage(MAVLINK_MSG_ID_RC_CHANNELS_RAW); //apo->getHal()->gcs->sendMessage(MAVLINK_MSG_ID_SCALED_IMU); } /* * send heartbeat */ apo->getHal()->gcs->sendMessage(MAVLINK_MSG_ID_HEARTBEAT); /* * load/loop rate/ram debug */ apo->getHal()->load = apo->load(); apo->getHal()->debug->printf_P(PSTR("missed calls: %d\n"),uint16_t(millis()*apo->getLoopRate(0)/1000-apo->callback0Calls)); apo->getHal()->debug->printf_P(PSTR("load: %d%%\trate: %f Hz\tfree ram: %d bytes\n"), apo->load(),1.0/apo->dt(),freeMemory()); apo->getHal()->gcs->sendMessage(MAVLINK_MSG_ID_SYS_STATUS); /* * adc debug */ //apo->getDebug().printf_P(PSTR("adc: %d %d %d %d %d %d %d %d\n"), //apo->adc()->Ch(0), apo->adc()->Ch(1), apo->adc()->Ch(2), //apo->adc()->Ch(3), apo->adc()->Ch(4), apo->adc()->Ch(5), //apo->adc()->Ch(6), apo->adc()->Ch(7), apo->adc()->Ch(8)); } void AP_Autopilot::callback4(void * data) { //AP_Autopilot * apo = (AP_Autopilot *) data; //apo->getHal()->debug->println_P(PSTR("callback 4")); } } // apo