00001
00002
00003
00004
00005
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
00029 batteryTimer = mainNodeHandle.createTimer(
00030 ros::Duration(options.tBatteryUpdatePeriod->getValue()), &MKROSInterface::batteryTimerCB, this);
00031
00032
00033
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
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
00098 if (request.input.size() != ACTIVEDATA_SIZE) {
00099
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
00153
00154
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
00169
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
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
00206 mkValuePublisher.publish(singleValueMsg);
00207
00208
00209 mkDataMirror.values[value->getID()] = singleValueMsg;
00210 mkValueArrayPublisher.publish(mkDataMirror);
00211 }
00212
00213 void MKROSInterface::activateCommandsCB()
00214 {
00215
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 }