base_kinematics.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2009, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 /*
35  * Author: Sachin Chitta and Matthew Piccoli
36  */
37 
38 #include <boost/shared_ptr.hpp>
39 
41 #include <kdl/tree.hpp>
42 
43 using namespace controller;
44 
45 
46 bool Wheel::init(pr2_mechanism_model::RobotState *robot_state, ros::NodeHandle &node, std::string link_name)
47 {
48  wheel_stuck_ = 0;
52  wheel_speed_cmd_ = 0;
54 
55 #if URDFDOM_1_0_0_API
56  urdf::LinkConstSharedPtr link;
57 #else
59 #endif
60  link = robot_state->model_->robot_model_.getLink(link_name);
61  if (!link){
62  ROS_ERROR("Could not find link with name %s",link_name.c_str());
63  return false;
64  }
65 
66  if(!link->collision)
67  {
68  ROS_ERROR("Link %s does not have collision description. Add collision description for link to urdf.",link_name.c_str());
69  return false;
70  }
71  if(!link->collision->geometry)
72  {
73  ROS_ERROR("Link %s does not have collision geometry description. Add collision geometry description for link to urdf.",link_name.c_str());
74  return false;
75  }
76  if(link->collision->geometry->type != urdf::Geometry::CYLINDER)
77  {
78  ROS_ERROR("Link %s does not have cylinder geometry",link_name.c_str());
79  return false;
80  }
81  wheel_radius_ = (dynamic_cast<urdf::Cylinder*>(link->collision->geometry.get()))->radius;
82  ROS_DEBUG("wheel name: %s, radius: %f",link_name.c_str(),wheel_radius_);
83  link_name_ = link_name;
84  joint_name_ = link->parent_joint->name;
85 
86  joint_ = robot_state->getJointState(joint_name_);
87  if (!joint_){
88  ROS_ERROR("Could not find joint with name %s",joint_name_.c_str());
89  return false;
90  }
91 
92  urdf::Vector3 offset = link->parent_joint->parent_to_joint_origin_transform.position;
93  offset_.x = offset.x;
94  offset_.y = offset.y;
95  offset_.z = offset.z;
96 // node.param<double> ("wheel_radius_scaler", wheel_radius_scaler_, 1.0);
97  ROS_DEBUG("Loading wheel: %s",link_name_.c_str());
98  ROS_DEBUG("offset_.x: %f, offset_.y: %f, offset_.z: %f", offset_.x, offset_.y, offset_.z);
99  return true;
100 }
101 
102 bool Caster::init(pr2_mechanism_model::RobotState *robot_state, ros::NodeHandle &node, std::string link_name)
103 {
104  caster_stuck_ = 0;
105  caster_speed_ = 0;
106  caster_speed_filtered_ = 0;
107  caster_speed_error_ = 0;
108  caster_position_error_ = 0;
109  steer_angle_stored_ = 0;
110  steer_velocity_desired_ = 0;
111  steer_angle_actual_ = 0;
112  num_children_ = 0;
113 
114 #if URDFDOM_1_0_0_API
115  urdf::LinkConstSharedPtr link;
116 #else
118 #endif
119  link = robot_state->model_->robot_model_.getLink(link_name);
120  if (!link){
121  ROS_ERROR("Could not find link with name %s",link_name.c_str());
122  return false;
123  }
124  ROS_DEBUG("caster name: %s",link_name.c_str());
125  link_name_ = link_name;
126  joint_name_ = link->parent_joint->name;
127 
128  joint_ = robot_state->getJointState(joint_name_);
129  if (!joint_){
130  ROS_ERROR("Could not find joint with name %s",joint_name_.c_str());
131  return false;
132  }
133  urdf::Vector3 offset = link->parent_joint->parent_to_joint_origin_transform.position;
134  offset_.x = offset.x;
135  offset_.y = offset.y;
136  offset_.z = offset.z;
137 
138  for(unsigned int i=0; i < link->child_links.size(); i++)
139  {
140 #if URDFDOM_1_0_0_API
141  urdf::LinkSharedPtr child = link->child_links[i];
142 #else
143  boost::shared_ptr<urdf::Link> child = link->child_links[i];
144 #endif
145  Wheel tmp;
146  parent_->wheel_.push_back(tmp);
147  if(!parent_->wheel_[parent_->num_wheels_].init(robot_state, node, child->name))
148  {
149  ROS_ERROR("Could not initialize caster %s",link_name.c_str());
150  return false;
151  }
152  parent_->num_wheels_++;
153  num_children_++;
154  }
155  return true;
156 }
157 
159 {
160  std::string caster_names_string;
161  std::vector<std::string> caster_names;
162  name_ = node.getNamespace();
163  //Initialize stuff
164  MAX_DT_ = 0.01;
165  num_wheels_ = 0;
166  num_casters_ = 0;
167 
168  robot_state_ = robot_state;
169 
170  node.param<std::string> ("caster_names",caster_names_string,"");
171  std::stringstream ss(caster_names_string);
172  std::string tmp;
173  while(ss >> tmp)
174  {
175  caster_names.push_back(tmp);
176  }
177 
178  for(unsigned int i=0; i < caster_names.size(); i++)
179  {
180  Caster tmp;
181  caster_.push_back(tmp);
182  caster_[num_casters_].parent_ = this;
183  ROS_DEBUG("caster name: %s",caster_names[i].c_str());
184  ros::NodeHandle n(name_);
185  if(!caster_[num_casters_].init(robot_state, n, caster_names[i]))
186  {
187  ROS_ERROR("Could not initialize base kinematics");
188  return false;
189  }
190  num_casters_++;
191  }
192 
193  // node.param<double> ("wheel_radius", wheel_radius_, 0.074792);
194  double multiplier;
195  node.param<double> ("wheel_radius_multiplier", multiplier, 1.0);
196  int wheel_counter = 0;
197  for(int j = 0; j < num_casters_; j++)
198  {
199  for(int i = 0; i < caster_[j].num_children_; i++)
200  {
201  wheel_[wheel_counter].parent_ = &(caster_[j]);
202  wheel_[wheel_counter].wheel_radius_*=multiplier;
203  wheel_counter++;
204  }
205  }
206  return true;
207 }
208 
210 {
211  geometry_msgs::Point result = parent_->offset_;
212  double costh = cos(parent_->joint_->position_);
213  double sinth = sin(parent_->joint_->position_);
214  result.x += costh * offset_.x - sinth * offset_.y;
215  result.y += sinth * offset_.x + costh * offset_.y;
216  result.z = 0.0;
217  position_ = result;
218 }
219 
221 {
222  for(int i = 0; i < num_wheels_; i++)
223  {
224  wheel_[i].updatePosition();
225  }
226 
227 }
228 
229 geometry_msgs::Twist BaseKinematics::pointVel2D(const geometry_msgs::Point& pos, const geometry_msgs::Twist& vel)
230 {
231  geometry_msgs::Twist result;
232  result.linear.x = vel.linear.x - pos.y * vel.angular.z;
233  result.linear.y = vel.linear.y + pos.x * vel.angular.z;
234  result.angular.z = 0;
235  return result;
236 }
double wheel_speed_cmd_
desired wheel speed
pr2_mechanism_model::JointState * joint_
JointState for this caster joint.
std::string link_name_
name of the link
double wheel_radius_
wheel radius scale (based on the default wheel radius in Basekinematics)
geometry_msgs::Point offset_
offset from the center of the base
bool init(pr2_mechanism_model::RobotState *robot_state, ros::NodeHandle &node, std::string link_name)
#define ROS_ERROR(...)
bool init(pr2_mechanism_model::RobotState *robot_state, ros::NodeHandle &node, std::string link_name)
Loads wheel&#39;s information from the xml description file and param server.
std::string joint_name_
name of the joint
geometry_msgs::Point offset_
default offset from the parent caster before any transformations
#define ROS_DEBUG(...)
geometry_msgs::Point position_
offset_ after rotation transformation from the parent caster&#39;s position
int wheel_stuck_
remembers if the wheel is stalled
Caster * parent_
the caster on which this wheel is mounted
geometry_msgs::Twist pointVel2D(const geometry_msgs::Point &pos, const geometry_msgs::Twist &vel)
Computes 2d velocity of a point at relative distance pos to another point with velocity (and rotation...
bool param(const std::string &param_name, T &param_val, const T &default_val) const
double wheel_speed_actual_
actual wheel speeds
int direction_multiplier_
specifies the default direction of the wheel
BaseKinematics * parent_
BaseKinematics to which this caster belongs.
pr2_mechanism_model::JointState * joint_
JointState for this wheel joint.
JointState * getJointState(const std::string &name)
double wheel_speed_filtered_
wheel speed filtered with alpha
bool init(pr2_mechanism_model::RobotState *robot_state, ros::NodeHandle &node)
Loads BaseKinematic&#39;s information from the xml description file and param server. ...
const std::string & getNamespace() const
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
void computeWheelPositions()
Computes 2d postion of every wheel relative to the center of the base.
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
double wheel_speed_error_
difference between desired and actual speed
void updatePosition()
Computes 2d postion of the wheel relative to the center of the base.
int i


pr2_mechanism_controllers
Author(s): Sachin Chita, John Hsu, Melonee Wise
autogenerated on Sat Nov 12 2022 03:16:31