MKROSInterface.cpp
Go to the documentation of this file.
00001 /*
00002  * MKROSInterface.cpp
00003  *
00004  *  Created on: Nov 29, 2011
00005  *      Author: mriedel
00006  */
00007 
00008 #include <tk_mkinterface/MKROSInterface.hpp>
00009 
00010 #include <tk_mkinterface/MKInterface.hpp>
00011 
00012 #include <telekyb_base/ROS/ROSModule.hpp>
00013 
00014 #include <boost/lexical_cast.hpp>
00015 
00016 namespace TELEKYB_NAMESPACE {
00017 
00018 MKROSInterface::MKROSInterface(MKInterface& mkInterface_, int robotID_)
00019         : mkInterface(mkInterface_),
00020           robotID(robotID_),
00021           mainNodeHandle(ROSModule::Instance().getMainNodeHandle()),
00022           robotIDNodeHandle(ROSModule::Instance().getBaseNodeHandle(), boost::lexical_cast<std::string>(robotID_))
00023 {
00024         setupMKDataMirror();
00025 
00026         setupServices();
00027 
00028         // Timer
00029         batteryTimer = mainNodeHandle.createTimer(
00030                         ros::Duration(options.tBatteryUpdatePeriod->getValue()), &MKROSInterface::batteryTimerCB, this);
00031 
00032         // This includes Async Subs. (They only work with commands!!!)
00033         //activateCommandsCB(); // gets activated by MKInterface!!!
00034 
00035         mkValuePublisher = mainNodeHandle.advertise<telekyb_msgs::MKValue>(MKINTERFACE_MKSINGLEVALUETOPIC,10);
00036         mkValueArrayPublisher = mainNodeHandle.advertise<telekyb_msgs::MKValues>(MKINTERFACE_MKSINGLEVALUEARRAYTOPIC,10);
00037 
00038         mkInterface.getConnection()->registerMKDataListener(this);
00039 }
00040 
00041 MKROSInterface::~MKROSInterface()
00042 {
00043         mkInterface.getConnection()->unRegisterMKDataListener(this);
00044 }
00045 
00046 void MKROSInterface::setupServices()
00047 {
00048         getMainMKNodeHandle = robotIDNodeHandle.advertiseService(
00049                         MKINTERFACE_GETMAINMKNODEHANDLE, &MKROSInterface::getMainMKNodeHandleCB, this);
00050         setActiveDataIDs = mainNodeHandle.advertiseService(
00051                         MKINTERFACE_SETACTIVEDATAIDS, &MKROSInterface::setActiveDataIDsCB, this);
00052         setMKValue = mainNodeHandle.advertiseService(
00053                         MKINTERFACE_SETMKVALUE, &MKROSInterface::setMKValueCB, this);
00054         updateMKValue = mainNodeHandle.advertiseService(
00055                         MKINTERFACE_UPDATEMKVALUE, &MKROSInterface::updateMKValueCB, this);
00056         doDriftEstim = mainNodeHandle.advertiseService(
00057                         MKINTERFACE_DODRIFTESTIM, &MKROSInterface::doDriftEstimCB, this);
00058         setEmergency = mainNodeHandle.advertiseService(
00059                         MKINTERFACE_SETEMERGENCY, &MKROSInterface::setEmergencyCB, this);
00060 }
00061 
00062 
00063 void MKROSInterface::batteryTimerCB(const ros::TimerEvent& event)
00064 {
00065         MKInt batteryValue;
00066         bool landingRequest;
00067 
00068         if (mkInterface.checkBattery(batteryValue, landingRequest)) {
00069                 if (landingRequest) {
00070                         // Call Empty Service
00071                         ros::ServiceClient client =
00072                                         mainNodeHandle.serviceClient<std_srvs::Empty>(options.tEmergencyLandService->getValue());
00073                         std_srvs::Empty service;
00074 
00075                         if (! client.call(service) ) {
00076                                 ROS_ERROR_STREAM("Failed to call: " << client.getService());
00077                                 ROS_ERROR_STREAM("EXTREME WARNING. Could not call EmergencyLand Service. LAND!");
00078                         }
00079                 }
00080 
00081                 ROS_INFO("MKInterface %d: Battery Level: %d", mkInterface.getOptions().tUavId->getValue(), batteryValue);
00082         }
00083 }
00084 
00085 bool MKROSInterface::getMainMKNodeHandleCB(
00086                 telekyb_srvs::StringOutput::Request& request,
00087                 telekyb_srvs::StringOutput::Response& response)
00088 {
00089         response.output = mainNodeHandle.getNamespace();
00090         return true;
00091 }
00092 
00093 bool MKROSInterface::setActiveDataIDsCB(
00094                 telekyb_srvs::IntArrayInput::Request& request,
00095                 telekyb_srvs::IntArrayInput::Response& response)
00096 {
00097         // Check size
00098         if (request.input.size() != ACTIVEDATA_SIZE) {
00099                 // TODO: Be more replaxed :)
00100                 ROS_ERROR("Cannot Set Active Data IDs: Inputsize(%d) is unequal to %d", (int)request.input.size(), ACTIVEDATA_SIZE);
00101                 return false;
00102         }
00103 
00104         MKActiveIDs ids;
00105         for (int i = 0; i < ACTIVEDATA_SIZE; ++i) {
00106 
00107                 if (request.input[i] < std::numeric_limits<MKChar>::min() || request.input[i] > std::numeric_limits<MKChar>::max()) {
00108                         ROS_ERROR("Value %d is invalid as ActiveDataID. Out of Range.", request.input[i]);
00109                         return false;
00110                 }
00111 
00112                 ids.ids[i] = (MKChar)request.input[i];
00113         }
00114 
00115         return mkInterface.getConnection()->setActiveDataIDs(ids);
00116 }
00117 
00118 bool MKROSInterface::setMKValueCB(
00119                 telekyb_srvs::MKValueInputOutput::Request& request,
00120                 telekyb_srvs::MKValueInputOutput::Response& response)
00121 {
00122         MKValue* value = mkInterface.getConnection()->getMKDataRef().getValueByID(request.value.id);
00123         if (mkInterface.getConnection()->setValue(value->getMKSingleValuePacketWithValue(request.value.value))) {
00124                 response.value.id = value->getID();
00125                 response.value.name = value->getName();
00126                 response.value.stamp = value->getStamp().toRosTime();
00127                 response.value.value = value->getValue();
00128                 return true;
00129         }
00130         return false;
00131 }
00132 
00133 bool MKROSInterface::updateMKValueCB(
00134                 telekyb_srvs::MKValueInputOutput::Request& request,
00135                 telekyb_srvs::MKValueInputOutput::Response& response)
00136 {
00137         MKValue* value = mkInterface.getConnection()->getMKDataRef().getValueByID(request.value.id);
00138         if (mkInterface.getConnection()->updateValue(request.value.id)) {
00139                 response.value.id = value->getID();
00140                 response.value.name = value->getName();
00141                 response.value.stamp = value->getStamp().toRosTime();
00142                 response.value.value = value->getValue();
00143                 return true;
00144         }
00145         return false;
00146 }
00147 
00148 bool MKROSInterface::doDriftEstimCB(
00149                 std_srvs::Empty::Request& request,
00150                 std_srvs::Empty::Response& response)
00151 {
00152 //      std::cout << "Received doDriftEstimCB!" << std::endl;
00153 //      bool test = mkInterface.performDriftEstim();
00154 //      std::cout << "Done doDriftEstimCB!" << std::endl;
00155         return mkInterface.performDriftEstim();
00156 }
00157 
00158 bool MKROSInterface::setEmergencyCB(
00159                 std_srvs::Empty::Request& request,
00160                 std_srvs::Empty::Response& response)
00161 {
00162         mkInterface.setEmergency();
00163         return true;
00164 }
00165 
00166 void MKROSInterface::commandsCB(const telekyb_msgs::TKCommands::ConstPtr& msg)
00167 {
00168         //ROS_INFO("Received Command!");
00169         // Input to Main Class. Calculation happens there.
00170         mkInterface.handleCommand(msg->mass, msg->pitch, msg->roll, msg->yaw, msg->thrust);
00171 }
00172 
00173 void MKROSInterface::setMKValueAsyncCB(const telekyb_msgs::MKValue::ConstPtr& msg)
00174 {
00175         MKSingleValuePacket packet(msg->id, msg->value);
00176         mkInterface.getConnection()->setValueAsync(packet);
00177 }
00178 void MKROSInterface::updateMKValueAsyncCB(const telekyb_msgs::MKValue::ConstPtr& msg)
00179 {
00180         mkInterface.getConnection()->updateValueAsync(msg->id);
00181 }
00182 
00183 void MKROSInterface::setupMKDataMirror()
00184 {
00185         mkDataMirror.values.resize(MKDataDefines::MKDATAIDS_NUM);
00186         const MKData& dataRef = mkInterface.getConnection()->getMKDataRef();
00187         for (int i = 0; i < MKDataDefines::MKDATAIDS_NUM; ++i) {
00188                 MKValue* value = dataRef.getValueByID(i);
00189                 mkDataMirror.values[i].id = value->getID();
00190                 mkDataMirror.values[i].name = value->getName();
00191                 mkDataMirror.values[i].stamp = value->getStamp().toRosTime();
00192                 mkDataMirror.values[i].value = value->getValue();
00193         }
00194 }
00195 
00196 void MKROSInterface::dataValueUpdated(MKValue* value)
00197 {
00198         //ROS_INFO_STREAM("MKValue updated: " << value->getName());
00199         telekyb_msgs::MKValue singleValueMsg;
00200         singleValueMsg.id = value->getID();
00201         singleValueMsg.name = value->getName();
00202         singleValueMsg.stamp = value->getStamp().toRosTime();
00203         singleValueMsg.value = value->getValue();
00204 
00205         // Single Value
00206         mkValuePublisher.publish(singleValueMsg);
00207 
00208         // Array
00209         mkDataMirror.values[value->getID()] = singleValueMsg;
00210         mkValueArrayPublisher.publish(mkDataMirror);
00211 }
00212 
00213 void MKROSInterface::activateCommandsCB()
00214 {
00215         //ROS_INFO_STREAM("Activating CommandsCB :" << options.tCommandsTopic->getValue());
00216         commandsSub = mainNodeHandle.subscribe(
00217                         options.tCommandsTopic->getValue(),1, &MKROSInterface::commandsCB, this);
00218 
00219         setMKValueAsyncSub = mainNodeHandle.subscribe(
00220                         MKINTERFACE_SETMKVALUEASYNC,SET_QUEUE_SIZE, &MKROSInterface::setMKValueAsyncCB, this);
00221 
00222         updateMKValueAsyncSub = mainNodeHandle.subscribe(
00223                         MKINTERFACE_UPDATEMKVALUEASYNC,UPDATE_QUEUE_SIZE, &MKROSInterface::updateMKValueAsyncCB, this);
00224 }
00225 
00226 void MKROSInterface::deActiavteCommandsCB()
00227 {
00228         updateMKValueAsyncSub.shutdown();
00229 
00230         setMKValueAsyncSub.shutdown();
00231 
00232         commandsSub.shutdown();
00233 }
00234 
00235 } /* namespace telekyb */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines


tk_mkinterface
Author(s): Martin Riedel
autogenerated on Wed Apr 24 2013 11:29:54