57 this->
world = _model->GetWorld();
64 this->
base = _model->GetLink(this->
model_name +
"::single_leg::sliding_base");
67 this->
joints = this->
model->GetJointController()->GetJoints();
72 ROS_INFO_STREAM(
t.first);
81 ROS_ERROR(
"Could not load parameters.");
98 ignition::math::Pose3d base_pose = this->
base->WorldPose();
100 Eigen::Matrix<double, 6, 1> q_b;
102 q_b(0) = base_pose.X();
103 q_b(1) = base_pose.Y();
104 q_b(2) = base_pose.Z();
105 q_b(3) = base_pose.Roll();
106 q_b(4) = base_pose.Pitch();
107 q_b(5) = base_pose.Yaw();
119 Eigen::Matrix<double, 6, 1> u_b;
121 u_b(0) = base_linear_velocity.X();
122 u_b(1) = base_linear_velocity.Y();
123 u_b(2) = base_linear_velocity.Z();
124 u_b(3) = base_angular_velocity.X();
125 u_b(4) = base_angular_velocity.Y();
126 u_b(5) = base_angular_velocity.Z();
136 double force = this->
joints[this->
model_name +
"::" + _joint_name]->GetForce(0);
144 Eigen::Matrix<double, 3, 1> tau_r;
156 double vel = this->
joints[this->
model_name +
"::" + _joint_name]->GetVelocity(0);
164 Eigen::Matrix<double, 3, 1> dot_q_r;
176 double pos = this->
joints[this->
model_name +
"::" + _joint_name]->Position();
184 Eigen::Matrix<double, 3, 1> q_r;
197 this->
model->GetJointController()->SetForce(
206 auto start = std::chrono::steady_clock::now();
210 this->
model->GetJointController()->Reset();
215 for (
size_t i = 0; i < this->
joint_names.size(); i++)
217 this->
model->GetJointController()->SetForce(
223 auto end = std::chrono::steady_clock::now();
225 std::chrono::duration<double,std::micro> diff = end - start;
227 ROS_DEBUG_STREAM(
"Time spent resetting commands and applying torques: " << diff.count() <<
" microseconds.");
233 this->
model->GetJointController()->SetVelocityTarget(
242 auto start = std::chrono::steady_clock::now();
246 this->
model->GetJointController()->Reset();
251 for (
size_t i = 0; i < this->
joint_names.size(); i++)
253 this->
model->GetJointController()->SetVelocityTarget(
259 auto end = std::chrono::steady_clock::now();
261 std::chrono::duration<double,std::micro> diff = end - start;
263 ROS_DEBUG_STREAM(
"Time spent resetting commands and setting velocity targets: " << diff.count() <<
" microseconds.");
269 auto start = std::chrono::steady_clock::now();
273 this->
model->GetJointController()->Reset();
278 for (
size_t i = 0; i < this->
joint_names.size(); i++)
280 this->
model->GetJointController()->SetPositionTarget(
286 auto end = std::chrono::steady_clock::now();
288 std::chrono::duration<double,std::micro> diff = end - start;
290 ROS_DEBUG_STREAM(
"Time spent resetting commands and setting position targets: " << diff.count() <<
" microseconds.");
296 if ((!_msg->position.empty()) && (_msg->position.size() ==
NUMJOINTS))
301 if ((!_msg->velocity.empty()) && (_msg->velocity.size() ==
NUMJOINTS))
306 if ((!_msg->effort.empty()) && (_msg->effort.size() ==
NUMJOINTS))
333 static const double timeout = 0.000001;
343 ros::Rate loop_rate(300);
346 Eigen::Matrix<double, 9, 1> q;
347 Eigen::Matrix<double, 9, 1> u;
348 Eigen::Matrix<double, 3, 1> tau;
358 std_msgs::Float64MultiArray gen_coord_msg;
359 std_msgs::Float64MultiArray gen_vel_msg;
360 std_msgs::Float64MultiArray joint_forces_msg;
362 tf::matrixEigenToMsg(q, gen_coord_msg);
363 tf::matrixEigenToMsg(u, gen_vel_msg);
364 tf::matrixEigenToMsg(tau, joint_forces_msg);
377 if (!ros::isInitialized())
385 ros::init_options::NoSigintHandler
389 this->
rosNode.reset(
new ros::NodeHandle(
"gazebo_client"));
391 ros::AdvertiseServiceOptions reset_simulation_aso =
392 ros::AdvertiseServiceOptions::create<std_srvs::Empty>(
393 "/" + this->
model->GetName() +
"/reset_simulation",
396 &this->rosProcessQueue
399 ros::AdvertiseOptions gen_coord_ao =
400 ros::AdvertiseOptions::create<std_msgs::Float64MultiArray>(
401 "/" + this->
model->GetName() +
"/gen_coord",
403 ros::SubscriberStatusCallback(),
404 ros::SubscriberStatusCallback(),
406 &this->rosPublishQueue
409 ros::AdvertiseOptions gen_vel_ao =
410 ros::AdvertiseOptions::create<std_msgs::Float64MultiArray>(
411 "/" + this->
model->GetName() +
"/gen_vel",
413 ros::SubscriberStatusCallback(),
414 ros::SubscriberStatusCallback(),
416 &this->rosPublishQueue
419 ros::AdvertiseOptions joint_forces_ao =
420 ros::AdvertiseOptions::create<std_msgs::Float64MultiArray>(
421 "/" + this->
model->GetName() +
"/joint_forces",
423 ros::SubscriberStatusCallback(),
424 ros::SubscriberStatusCallback(),
426 &this->rosPublishQueue
429 ros::SubscribeOptions joint_state_so =
430 ros::SubscribeOptions::create<sensor_msgs::JointState>(
431 "/" + this->
model->GetName() +
"/joint_state_cmd",
435 &this->rosProcessQueue
438 ros::SubscribeOptions force_so =
439 ros::SubscribeOptions::create<std_msgs::Float64MultiArray>(
440 "/" + this->
model->GetName() +
"/force_cmd",
444 &this->rosProcessQueue
447 ros::SubscribeOptions vel_so =
448 ros::SubscribeOptions::create<std_msgs::Float64MultiArray>(
449 "/" + this->
model->GetName() +
"/vel_cmd",
453 &this->rosProcessQueue
456 ros::SubscribeOptions pos_so =
457 ros::SubscribeOptions::create<std_msgs::Float64MultiArray>(
458 "/" + this->
model->GetName() +
"/pos_cmd",
462 &this->rosProcessQueue
498 if (!this->
rosNode->getParam(
"joint_names", this->joint_names))
500 ROS_ERROR(
"Could not read joint names from parameter server.");
504 if (!this->
rosNode->getParam(
"joint_config", this->joint_config))
506 ROS_ERROR(
"Could not read joint config from parameter server.");
510 if (!this->
rosNode->getParam(
"joint_velocity_controller/p_gains", this->vel_p_gains))
512 ROS_ERROR(
"Could not read velocity P-gains from parameter server.");
516 if (!this->
rosNode->getParam(
"joint_velocity_controller/i_gains", this->vel_i_gains))
518 ROS_ERROR(
"Could not read velocity I-gains from parameter server.");
522 if (!this->
rosNode->getParam(
"joint_velocity_controller/d_gains", this->vel_d_gains))
524 ROS_ERROR(
"Could not read velocity D-gains from parameter server.");
528 if (!this->
rosNode->getParam(
"joint_position_controller/p_gains", this->pos_p_gains))
530 ROS_ERROR(
"Could not read position P-gains from parameter server.");
534 if (!this->
rosNode->getParam(
"joint_position_controller/i_gains", this->pos_i_gains))
536 ROS_ERROR(
"Could not read position I-gains from parameter server.");
540 if (!this->
rosNode->getParam(
"joint_position_controller/d_gains", this->pos_d_gains))
542 ROS_ERROR(
"Could not read position D-gains from parameter server.");
553 ROS_ERROR(
"Mismatch in number of joints and number of gains.");
563 for (
size_t i = 0; i < this->
joint_names.size(); i++)
565 this->
model->GetJointController()->SetVelocityPID(
570 this->
model->GetJointController()->SetPositionPID(
582 for (
size_t i = 0; i < this->
joint_names.size(); i++)
585 this->
model->GetJointController()->SetJointPosition(
591 this->
model->GetJointController()->SetPositionTarget(
600 std_srvs::Empty::Response &_res)
602 this->
world->Reset();
604 this->
model->GetJointController()->Reset();
608 for (
size_t i = 0; i < this->
joint_names.size(); i++)
611 this->
model->GetJointController()->SetForce(
617 this->
model->GetJointController()->SetJointPosition(
623 this->
model->GetJointController()->SetPositionTarget(
void OnForceMsg(const std_msgs::Float64MultiArrayConstPtr &_msg)
The OnRosMsg function handles an incoming force message from ROS.
void ProcessQueueThread()
The ProcessQueueThread function is a ROS helper function that processes messages.
std::thread rosProcessQueueThread
Thread running the rosProcessQueue.
ros::Subscriber posSub
ROS Position Subscriber.
void SetJointPositions(const std::vector< double > &_pos)
Set the position of the joints.
virtual void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
The Load function is called by Gazebo when the plugin is inserted into simulation.
virtual ~SingleLegPlugin()
Destructor.
double GetJointPosition(const std::string &_joint_name)
Get current position at a specific joint.
ros::Subscriber forceSub
ROS Force Subscriber.
Eigen::Matrix< double, 6, 1 > GetBaseTwist()
Get current base twist for the robot.
Eigen::Matrix< double, 6, 1 > GetBasePose()
Get current base pose for the robot.
bool LoadParametersRos()
The LoadParametersRos function is called to load conffloatiguration from the parameter server.
std::vector< double > vel_i_gains
Vector of Velocity I-gains.
double GetJointVelocity(const std::string &_joint_name)
Get current velocity at a specific joint.
std::vector< double > joint_config
Vector of joint configuration.
ros::Publisher genCoordPub
ROS Generalized Coordinates Publisher.
void SetJointForce(const std::string &_joint_name, const double &_force)
Apply force at a specific joint.
void OnJointStateMsg(const sensor_msgs::JointStateConstPtr &_msg)
The OnJointStateMsg function handles an incoming joint state message from ROS.
Eigen::Matrix< double, 3, 1 > GetJointPositions()
Get current joint positions for the robot.
std::string model_name
Model name.
SingleLegPlugin()
Constructor.
ros::Publisher jointForcesPub
ROS Joint Forces (Torques) Publisher.
void InitRos()
The initRos function is called to initialize ROS.
physics::LinkPtr base
Pointer to the body link.
std::unique_ptr< ros::NodeHandle > rosNode
Node used for ROS transport.
std::vector< double > vel_p_gains
Vector of Velocity P-gains.
std::map< std::string, physics::JointPtr > joints
Pointers to the joints.
void PublishQueueThread()
The PublishQueueThread function is a ROS helper function that publish state messages.
std::vector< double > pos_i_gains
Vector of Position I-gains.
Eigen::Matrix< double, 3, 1 > GetJointVelocities()
Get current joint velocities for the robot.
physics::WorldPtr world
Pointer to the world.
ControlMode controlMode
Control mode indicator { position = 1, velocity = 2, torque = 3 }.
void InitJointConfiguration()
The InitJointConfiguration function is called to initialize the desired joint configuration.
void SetJointForces(const std::vector< double > &_forces)
Apply joint forces.
bool ResetSimulation(const std_srvs::Empty::Request &_req, std_srvs::Empty::Response &_res)
The ResetSimulation function handles an incoming reset simulation service request.
ros::ServiceServer resetSimService
ROS Reset Simulation Service.
void OnPosMsg(const std_msgs::Float64MultiArrayConstPtr &_msg)
The OnRosMsg function handles an incoming velocity message from ROS.
void InitRosQueueThreads()
The InitRosQueueThreads function is called to initialize the ROS Publish and Process Queue Threads.
ros::Subscriber jointStateSub
ROS Joint State Subscriber.
Eigen::Matrix< double, 3, 1 > GetJointForces()
Get current joint forces for the robot.
ros::Publisher genVelPub
ROS Generalized Velocities Publisher.
std::vector< std::string > joint_names
Vector of joint names.
double GetJointForce(const std::string &_joint_name)
Get currently applied force at a specific joint.
void InitJointControllers()
The InitJointControllers function is called to setup joint PID controllers.
ros::CallbackQueue rosPublishQueue
ROS callbackque that helps publish messages.
std::vector< double > vel_d_gains
Vector of Velocity D-gains.
ros::CallbackQueue rosProcessQueue
ROS callbackque that helps process messages.
ros::Subscriber velSub
ROS Velocity Subscriber.
void SetJointVelocity(const std::string &_joint_name, const double &_vel)
Set the velocity of the joint.
std::thread rosPublishQueueThread
Thread running the rosPublishQueue.
std::vector< double > pos_d_gains
Vector of Position D-gains.
physics::ModelPtr model
Pointer to the model.
std::vector< double > pos_p_gains
Vector of Position P-gains.
void SetJointVelocities(const std::vector< double > &_vel)
Set the velocity of the joints.
void OnVelMsg(const std_msgs::Float64MultiArrayConstPtr &_msg)
The OnRosMsg function handles an incoming velocity message from ROS.
static constexpr unsigned int NUMJOINTS
Fixed variable for num joints.
double wrapAngleToPi(const double &_rad)
The wrapAngleToPi function wraps an input angle to the interval [-pi, pi).
double degToRad(const double &_deg)
The degToRad function converts degrees to radians.