AddForcePlugin.cpp
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     // Initialize
00028     void Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf)
00029     {
00030       // Store the pointer to the model
00031       this->model = _parent;
00032 
00033       // read option args in sdf tags
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       // find root link
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       // Make sure the ROS node for Gazebo has already been initialized                                                                                    
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       // ros node
00069       this->rosNode = new ros::NodeHandle("");
00070       // ros callback queue for processing subscription
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       // ros topic subscribtions
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       // Enable TCP_NODELAY because TCP causes bursty communication with high jitter,
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       // ros callback queue for processing subscription
00093       this->callbackQueeuThread = boost::thread(boost::bind(&AddForce::RosQueueThread, this));
00094 
00095       // Listen to the update event.
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     // Called by the world update start event
00119     void OnUpdate(const common::UpdateInfo & /*_info*/)
00120     {
00121       this->link->AddForce(this->force);
00122       // this->link->AddRelativeForce(this->force);
00123       // this->link->AddForceAtRelativePosition(this->force, this->position);
00124       this->link->AddTorque(this->torque);
00125     }
00126 
00127     // Ros loop thread function
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 }


hrpsys_gazebo_general
Author(s): Yohei Kakiuchi , Kei Okada , Masaki Murooka
autogenerated on Thu Jun 6 2019 20:56:53