HapticFormationController.cpp
Go to the documentation of this file.
00001 /*
00002  * FormationController.cpp
00003  *
00004  *  Created on: Mar 4, 2012
00005  *      Author: mriedel
00006  */
00007 
00008 #include "HapticFormationController.hpp"
00009 
00010 #include <telekyb_base/ROS/ROSModule.hpp>
00011 
00012 // plugin stuff
00013 #include <pluginlib/class_list_macros.h>
00014 
00015 #include <ros/console.h>
00016 
00017 // to get the system
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         // Gains for Controller
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         // free generic subscribers
00060         for (unsigned int i = 0; i < stateSubscribers.size(); ++i) {
00061                 delete stateSubscribers[i];
00062         }
00063 
00064         if (options) { delete options; }
00065 }
00066 
00067 // Identifier (e.g. for NodeHandle)
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         //stateSubscribers.resize(stateSubscribers, NULL);
00077         for (unsigned int i = 0; i < robotIDs.size(); ++i) {
00078                 ros::NodeHandle nh; // wait also 2s
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 // Get's specific Axes mapping, Set if needed
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 // Get the Range of each axes
00105 void HapticFormationController::setAxesRange(const Position3D& minValues, const Position3D& maxValues) {
00106 
00107 }
00108 
00109 void HapticFormationController::willEnterSpinLoop()
00110 {
00111         frequencyTimer.reset();
00112 }
00113 
00114 // has to be fast and should not slow down the loop
00115 void HapticFormationController::loopCB(const HapticOuput& output, HapticInput& input) {
00116 
00117         // Del Velocity
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         // Calculate force
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                 //ROS_INFO("Output every second");
00143 
00144 //              ROS_INFO("Position: (%f,%f,%f)", output.position(0), output.position(1), output.position(2));
00145 //              ROS_INFO("Velocity: (%f,%f,%f)", output.linVelocity(0), output.linVelocity(1), output.linVelocity(2));
00146 //              Eigen::Vector3d angles = output.orientation.toRotationMatrix().eulerAngles(0,1,2);
00147 //              ROS_INFO("Orientation: (%f,%f,%f)", angles(0), angles(1), angles(2));
00148 //              ROS_INFO("Force: (%f,%f,%f)", output.force(0), output.force(1), output.force(2));
00149 //              ROS_INFO("Loop Frequency: %d", (int)(output.frequency) );
00150 //              ROS_INFO("Primary Button: %d", output.primaryButton);
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines


tk_formation
Author(s): Martin Riedel
autogenerated on Mon Nov 11 2013 11:14:18