Go to the documentation of this file.00001 #include <iostream>
00002 #include <stdio.h>
00003
00004 #include <boost/bind.hpp>
00005 #include <gazebo/gazebo.hh>
00006 #include <gazebo/physics/physics.hh>
00007 #include <gazebo/common/common.hh>
00008
00009 #include <ros/ros.h>
00010 #include <ros/callback_queue.h>
00011 #include <ros/advertise_options.h>
00012 #include <ros/subscribe_options.h>
00013
00014 #include <geometry_msgs/Twist.h>
00015 #include <geometry_msgs/Pose.h>
00016 #include <geometry_msgs/Vector3.h>
00017 #include <geometry_msgs/Wrench.h>
00018 #include <std_msgs/String.h>
00019
00020
00021 namespace gazebo
00022 {
00023 class AddForce : public ModelPlugin
00024 {
00025
00026 public:
00027
00028 void Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf)
00029 {
00030
00031 this->model = _parent;
00032
00033
00034 this->obj_name = "";
00035 if (_sdf->HasElement("objname")) {
00036 this->obj_name = _sdf->Get<std::string>("objname");
00037 }
00038 this->link_name = "root";
00039 if (_sdf->HasElement("linkname")) {
00040 this->link_name = _sdf->Get<std::string>("linkname");
00041 }
00042 this->force = math::Vector3(0, 0, 0);
00043 if (_sdf->HasElement("force")) {
00044 this->force = _sdf->Get<math::Vector3>("force");
00045 }
00046 this->torque = math::Vector3(0, 0, 0);
00047 if (_sdf->HasElement("torque")) {
00048 this->torque = _sdf->Get<math::Vector3>("torque");
00049 }
00050 this->position = math::Vector3(0, 0, 0);
00051 if(_sdf->HasElement("position")) {
00052 this->position = _sdf->Get<math::Vector3>("position");
00053 }
00054
00055
00056 this->link = this->model->GetLink(this->link_name);
00057 if(!this->link) {
00058 gzerr << "Root link are not found. (link_name is "<< this->link_name << ")" << std::endl;
00059 return;
00060 }
00061
00062
00063 if (!ros::isInitialized()) {
00064 gzerr << "A ROS node for Gazebo has not been initialized, unable to load plugin. "
00065 << "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)";
00066 return;
00067 }
00068
00069 this->rosNode = new ros::NodeHandle("");
00070
00071 this->deferredLoadThread = boost::thread(boost::bind(&AddForce::DeferredLoad, this));
00072
00073 gzmsg << "AddForcePlugin was loaded ! ( force: " << this->force << " torque: " << this->torque << " position: " << this->position << ")" << std::endl;
00074 }
00075
00076 void DeferredLoad() {
00077
00078 ros::SubscribeOptions ForceCommandSo =
00079 ros::SubscribeOptions::create<geometry_msgs::Wrench>("/" + this->obj_name + "/AddForcePlugin/ForceCommand", 100,
00080 boost::bind(&AddForce::SetForceCommand, this, _1),
00081 ros::VoidPtr(), &this->rosQueue);
00082 ros::SubscribeOptions ForcePositionSo =
00083 ros::SubscribeOptions::create<geometry_msgs::Vector3>("/" + this->obj_name + "/AddForcePlugin/ForcePosition", 100,
00084 boost::bind(&AddForce::SetForcePosition, this, _1),
00085 ros::VoidPtr(), &this->rosQueue);
00086
00087 ForceCommandSo.transport_hints = ros::TransportHints().reliable().tcpNoDelay(true);
00088 this->subForceCommand = this->rosNode->subscribe(ForceCommandSo);
00089 ForcePositionSo.transport_hints = ros::TransportHints().reliable().tcpNoDelay(true);
00090 this->subForcePosition = this->rosNode->subscribe(ForcePositionSo);
00091
00092
00093 this->callbackQueeuThread = boost::thread(boost::bind(&AddForce::RosQueueThread, this));
00094
00095
00096 this->updateConnection = event::Events::ConnectWorldUpdateBegin(boost::bind(&AddForce::OnUpdate, this, _1));
00097 }
00098
00099 void SetForceCommand(const geometry_msgs::Wrench::ConstPtr &_msg)
00100 {
00101 this->force.x = _msg->force.x;
00102 this->force.y = _msg->force.y;
00103 this->force.z = _msg->force.z;
00104 this->torque.x = _msg->torque.x;
00105 this->torque.y = _msg->torque.y;
00106 this->torque.z = _msg->torque.z;
00107 gzmsg << "subscribed AddForceCommand. ( force: " << this->force << " torque: " << this->torque << " )" << std::endl;
00108 }
00109
00110 void SetForcePosition(const geometry_msgs::Vector3::ConstPtr &_msg)
00111 {
00112 this->position.x = _msg->x;
00113 this->position.y = _msg->y;
00114 this->position.z = _msg->z;
00115 gzmsg << "subscribed AddForcePosition. ( position: " << this->position << " )" << std::endl;
00116 }
00117
00118
00119 void OnUpdate(const common::UpdateInfo & )
00120 {
00121 this->link->AddForce(this->force);
00122
00123
00124 this->link->AddTorque(this->torque);
00125 }
00126
00127
00128 void RosQueueThread() {
00129 static const double timeout = 0.01;
00130
00131 while (this->rosNode->ok()) {
00132 this->rosQueue.callAvailable(ros::WallDuration(timeout));
00133 }
00134 }
00135
00136 private:
00137 physics::ModelPtr model;
00138 std::string link_name;
00139 std::string obj_name;
00140 math::Vector3 force;
00141 math::Vector3 torque;
00142 math::Vector3 position;
00143 physics::LinkPtr link;
00144 event::ConnectionPtr updateConnection;
00145
00146 ros::NodeHandle* rosNode;
00147 ros::CallbackQueue rosQueue;
00148 ros::Subscriber subForceCommand;
00149 ros::Subscriber subForcePosition;
00150 boost::thread callbackQueeuThread;
00151 boost::thread deferredLoadThread;
00152 };
00153
00154 GZ_REGISTER_MODEL_PLUGIN(AddForce)
00155 }