00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <pluginlib/class_list_macros.h>
00014 #include <uwsim/ForceSensor.h>
00015
00016 ForceSensor::ForceSensor(ForceSensor_Config * cfg, osg::ref_ptr<osg::Node> target) :
00017 SimulatedDevice(cfg)
00018 {
00019 this->target = target;
00020 this->offsetp[0]=cfg->offsetp[0]; this->offsetp[1]=cfg->offsetp[1]; this->offsetp[2]=cfg->offsetp[2];
00021 offset.makeRotate(osg::Quat(cfg->offsetr[0], osg::Vec3d(1, 0, 0), cfg->offsetr[1], osg::Vec3d(0, 1, 0), cfg->offsetr[2],osg::Vec3d(0, 0, 1)));
00022 physics=NULL;
00023 physicsApplied=0;
00024 }
00025
00026 void ForceSensor::applyPhysics(BulletPhysics * bulletPhysics)
00027 {
00028 physics=bulletPhysics;
00029 osg::ref_ptr<NodeDataType> data = dynamic_cast<NodeDataType*>(target->getUserData());
00030 copy=physics->copyObject(data->rigidBody);
00031 copy->setGravity(btVector3(0,0,0));
00032 copy->setCenterOfMassTransform(btTransform(btQuaternion(0,0,0,1),btVector3(offsetp[0],offsetp[1],offsetp[2])));
00033 btTarget = data->rigidBody;
00034 btTarget->setCenterOfMassTransform(btTransform(btQuaternion(0,0,0,1),btVector3(offsetp[0],offsetp[1],offsetp[2])));
00035
00036 if(btTarget->getInvMass()==0)
00037 {
00038 ROS_FATAL("ForceSensor %s used in a null mass object.", name.c_str());
00039 exit(0);
00040 }
00041
00042 CBreference=physics->callbackManager->addForceSensor(copy,btTarget);
00043 physicsApplied=1;
00044 }
00045
00046 void ForceSensor::getForceTorque(double force[3], double torque[3])
00047 {
00048
00049 if(!physics)
00050 {
00051 ROS_FATAL("ForceSensor %s can't retrieve physics information. Missing enable physics?", name.c_str());
00052 exit(0);
00053 }
00054 if(physics->physicsStep ==0)
00055 {
00056
00057 osg::Matrix ObjectMat= offset * *getWorldCoords(target);
00058
00059 double linSpeed[3],angSpeed[3];
00060 physics->callbackManager->getForceSensorSpeed(CBreference,linSpeed,angSpeed);
00061
00062 osg::Vec3 res=ObjectMat.getRotate().inverse()*osg::Vec3(linSpeed[0],linSpeed[1],linSpeed[2]);
00063
00064 force[0]=res.x();
00065 force[1]=res.y();
00066 force[2]=res.z();
00067
00068 res=ObjectMat.getRotate().inverse()*osg::Vec3(angSpeed[0],angSpeed[1],angSpeed[2]);
00069
00070
00071 torque[0]=res.x()/10;
00072 torque[1]=res.y()/10;
00073 torque[2]=res.z()/10;
00074 }
00075 else
00076 {
00077 force[0]=0;
00078 force[1]=0;
00079 force[2]=0;
00080
00081 torque[0]=0;
00082 torque[1]=0;
00083 torque[2]=0;
00084
00085 }
00086 }
00087
00088 SimulatedDeviceConfig::Ptr ForceSensor_Factory::processConfig(const xmlpp::Node* node, ConfigFile * config)
00089 {
00090 ForceSensor_Config * cfg = new ForceSensor_Config(getType());
00091 xmlpp::Node::NodeList list = node->get_children();
00092 for (xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
00093 {
00094 const xmlpp::Node* child = dynamic_cast<const xmlpp::Node*>(*iter);
00095 if(child->get_name() == "target")
00096 config->extractStringChar(child, cfg->target);
00097 else if(child->get_name() == "offsetp")
00098 config->extractPositionOrColor(child, cfg->offsetp);
00099 else if(child->get_name() == "offsetr")
00100 config->extractPositionOrColor(child, cfg->offsetr);
00101 }
00102 return SimulatedDeviceConfig::Ptr(cfg);
00103 }
00104
00105 bool ForceSensor_Factory::applyConfig(SimulatedIAUV * auv, Vehicle &vehicleChars, SceneBuilder *sceneBuilder,
00106 size_t iteration)
00107 {
00108 if (iteration > 0)
00109 return true;
00110 for (size_t i = 0; i < vehicleChars.simulated_devices.size(); ++i)
00111 if (vehicleChars.simulated_devices[i]->getType() == this->getType())
00112 {
00113 ForceSensor_Config * cfg = dynamic_cast<ForceSensor_Config *>(vehicleChars.simulated_devices[i].get());
00114 osg::ref_ptr<osg::Node> target;
00115 for(int j=0;j<auv->urdf->link.size();j++)
00116 {
00117 if(auv->urdf->link[j]->getName()==cfg->target)
00118 {
00119 target=auv->urdf->link[j];
00120 }
00121 }
00122 auv->devices->all.push_back(ForceSensor::Ptr(new ForceSensor(cfg,target)));
00123 }
00124 return true;
00125 }
00126
00127 std::vector<boost::shared_ptr<ROSInterface> > ForceSensor_Factory::getInterface(
00128 ROSInterfaceInfo & rosInterface, std::vector<boost::shared_ptr<SimulatedIAUV> > & iauvFile)
00129 {
00130 std::vector < boost::shared_ptr<ROSInterface> > ifaces;
00131 for (size_t i = 0; i < iauvFile.size(); ++i)
00132 for (size_t d = 0; d < iauvFile[i]->devices->all.size(); ++d)
00133 if (iauvFile[i]->devices->all[d]->getType() == this->getType()
00134 && iauvFile[i]->devices->all[d]->name == rosInterface.targetName)
00135 {
00136 ifaces.push_back(
00137 boost::shared_ptr < ROSInterface
00138 > (new ForceSensor_ROSPublisher(dynamic_cast<ForceSensor*>(iauvFile[i]->devices->all[d].get()),
00139 rosInterface.topic, rosInterface.rate)));
00140
00141
00142
00143
00144 }
00145 if (ifaces.size() == 0)
00146 ROS_WARN("Returning empty ROS interface for device %s...", rosInterface.targetName.c_str());
00147 return ifaces;
00148 }
00149
00150 void ForceSensor_ROSPublisher::createPublisher(ros::NodeHandle &nh)
00151 {
00152 ROS_INFO("ForceSensor_ROSPublisher on topic %s", topic.c_str());
00153 pub_ = nh.advertise < geometry_msgs::WrenchStamped > (topic, 1);
00154 while (!dev->physicsApplied)
00155 {
00156 ROS_INFO("ForceSensor_ROSPublisher Waiting for physics to be initialized...");
00157 sleep(1.0);
00158 }
00159 }
00160
00161 void ForceSensor_ROSPublisher::publish()
00162 {
00163
00164 double force[3], torque[3], elapsed;
00165
00166 dev->getForceTorque(force,torque);
00167
00168 elapsed = 1.0/publish_rate;
00169
00170 geometry_msgs::WrenchStamped msg;
00171 msg.header.stamp = getROSTime();
00172 msg.header.frame_id =dev->target->getName();
00173
00174 msg.wrench.force.x=force[0]/elapsed*(1/dev->btTarget->getInvMass());
00175 msg.wrench.force.y=force[1]/elapsed*(1/dev->btTarget->getInvMass());
00176 msg.wrench.force.z=force[2]/elapsed*(1/dev->btTarget->getInvMass());
00177
00178 msg.wrench.torque.x=torque[0]/elapsed*(1/dev->btTarget->getInvMass());
00179 msg.wrench.torque.y=torque[1]/elapsed*(1/dev->btTarget->getInvMass());
00180 msg.wrench.torque.z=torque[2]/elapsed*(1/dev->btTarget->getInvMass());
00181
00182 pub_.publish(msg);
00183 }
00184
00185 #if ROS_VERSION_MINIMUM(1, 9, 0)
00186
00187 PLUGINLIB_EXPORT_CLASS(ForceSensor_Factory, uwsim::SimulatedDeviceFactory)
00188 #else
00189 PLUGINLIB_REGISTER_CLASS(ForceSensor_Factory, ForceSensor_Factory, uwsim::SimulatedDeviceFactory)
00190 #endif
00191