00001
00002
00003
00004
00005
00006
00007
00008 #include "HapticFormationController.hpp"
00009
00010 #include <telekyb_base/ROS/ROSModule.hpp>
00011
00012
00013 #include <pluginlib/class_list_macros.h>
00014
00015 #include <ros/console.h>
00016
00017
00018 #include <telekyb_interface/TeleKybCore.hpp>
00019
00020 PLUGINLIB_DECLARE_CLASS(tk_formation, HapticFormationController, telekyb_haptic::HapticFormationController, TELEKYB_NAMESPACE::HapticDeviceController);
00021
00022 namespace telekyb_haptic {
00023
00024 HapticFormationControllerOptions::HapticFormationControllerOptions(const std::string& identifier)
00025 : OptionContainer("HapticFormationController_" + identifier)
00026 {
00027 tRobotIDs = addOption< std::vector<int> >("tRobotIDs",
00028 "Specifies the ID of the Robots to connect to", std::vector<int>() , true, true);
00029 tSendFrequency = addOption< double >("tSendFrequency",
00030 "Send Frequency", 100.0 , false, true);
00031 tInputTopicName = addOption< std::string >("tInputTopicName",
00032 "Appended Topicname for TKState Subscription of UAVs", "Sensor/TKState" , false, true);
00033 tOutputTopicName = addOption< std::string >("tOutputTopicName",
00034 "Topic to send Vector3Stamped to", "output" , false, true);
00035 tVelocityGain = addOption< double >("tVelocityGain",
00036 "Gain of Velocity", 5.0 , false, true);
00037 Eigen::Matrix3d rotationMatrix = Eigen::Matrix3d::Zero();
00038 rotationMatrix.diagonal() << 1.0,-1.0,-1.0;
00039 tRotationMatrix = addOption<Eigen::Matrix3d>("tRotationMatrix","ConversionMatrix from TKState to Haptic", rotationMatrix, false, true);
00040
00041
00042
00043 tPropGain = addOption< double >("tPropGain",
00044 "Gain of Velocity", -20.0 , false, false);
00045 tDeriGain = addOption< double >("tDeriGain",
00046 "Gain of Velocity", -5.0 , false, false);
00047 tErrGain = addOption< double >("tErrGain",
00048 "Gain of Velocity", 100.0 , false, false);
00049 }
00050
00051 HapticFormationController::HapticFormationController()
00052 : options(NULL)
00053 {
00054
00055 }
00056
00057 HapticFormationController::~HapticFormationController()
00058 {
00059
00060 for (unsigned int i = 0; i < stateSubscribers.size(); ++i) {
00061 delete stateSubscribers[i];
00062 }
00063
00064 if (options) { delete options; }
00065 }
00066
00067
00068 void HapticFormationController::setIdentifier(const std::string& identifier)
00069 {
00070 ROS_INFO("HapticFormationController: Got identifier %s", identifier.c_str());
00071
00072 options = new HapticFormationControllerOptions(identifier);
00073
00074 std::vector<int> robotIDs = options->tRobotIDs->getValue();
00075
00076
00077 for (unsigned int i = 0; i < robotIDs.size(); ++i) {
00078 ros::NodeHandle nh;
00079 if (! telekyb_interface::TeleKybCore::getTeleKybCoreMainNodeHandle(robotIDs[i], nh, 4.0)) {
00080 continue;
00081 }
00082
00083 GenericSubscriber< telekyb_msgs::TKState > *sub =
00084 new GenericSubscriber< telekyb_msgs::TKState >(nh, options->tInputTopicName->getValue(), 1);
00085 stateSubscribers.push_back(sub);
00086 }
00087
00088 if (stateSubscribers.empty()) {
00089 ROS_WARN("TKState Subscriber list empty. Unable to determine any Velocity.");
00090 }
00091
00092 nodeHandle = ros::NodeHandle(ROSModule::Instance().getMainNodeHandle(), identifier);
00093
00094 vectorPub = nodeHandle.advertise<geometry_msgs::Vector3Stamped>(options->tOutputTopicName->getValue(),10);
00095
00096 }
00097
00098
00099 void HapticFormationController::setAxesMapping(HapticAxesMapping& xAxis, HapticAxesMapping& yAxis, HapticAxesMapping& zAxis)
00100 {
00101 ROS_INFO("Recv Axes Mapping (X,Y,Z): (%s,%s,%s)", xAxis.str(), yAxis.str(), zAxis.str());
00102 }
00103
00104
00105 void HapticFormationController::setAxesRange(const Position3D& minValues, const Position3D& maxValues) {
00106
00107 }
00108
00109 void HapticFormationController::willEnterSpinLoop()
00110 {
00111 frequencyTimer.reset();
00112 }
00113
00114
00115 void HapticFormationController::loopCB(const HapticOuput& output, HapticInput& input) {
00116
00117
00118 Velocity3D desVel = output.position * options->tVelocityGain->getValue();
00119 desVel = options->tRotationMatrix->getValue() * desVel;
00120
00121 Velocity3D curVel = Velocity3D::Zero();
00122 for (unsigned int i = 0; i < stateSubscribers.size(); ++i) {
00123 TKState velMsg(stateSubscribers[i]->getLastMsg());
00124 curVel += velMsg.linVelocity;
00125 }
00126
00127 if (stateSubscribers.size() != 0) {
00128 curVel /= stateSubscribers.size();
00129 }
00130
00131
00132 Velocity3D velError = (curVel - desVel) / options->tVelocityGain->getValue();
00133 velError = options->tRotationMatrix->getValue() * velError;
00134
00135
00136 input.force = options->tPropGain->getValue() * output.position
00137 + options->tDeriGain->getValue() * output.linVelocity
00138 + options->tErrGain->getValue() * velError;
00139
00140
00141 if (frequencyTimer.frequency() < options->tSendFrequency->getValue()) {
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 geometry_msgs::Vector3Stamped outputMsg;
00152 outputMsg.header.stamp = ros::Time::now();
00153 outputMsg.vector.x = desVel(0);
00154 outputMsg.vector.y = desVel(1);
00155 outputMsg.vector.z = desVel(2);
00156
00157 vectorPub.publish(outputMsg);
00158 frequencyTimer.reset();
00159 }
00160
00161 }
00162
00163 void HapticFormationController::didLeaveSpinLoop()
00164 {
00165
00166 }
00167
00168 }