omni.cpp
Go to the documentation of this file.
1 //
2 // Created by qiayuan on 2022/7/29.
3 //
4 
5 #include <string>
6 #include <Eigen/QR>
7 
10 
12 
13 namespace rm_chassis_controllers
14 {
16  ros::NodeHandle& controller_nh)
17 {
18  ChassisBase::init(robot_hw, root_nh, controller_nh);
19 
20  XmlRpc::XmlRpcValue wheels;
21  controller_nh.getParam("wheels", wheels);
22  chassis2joints_.resize(wheels.size(), 3);
23 
24  size_t i = 0;
25  for (const auto& wheel : wheels)
26  {
27  ROS_ASSERT(wheel.second.hasMember("pose"));
28  ROS_ASSERT(wheel.second["pose"].getType() == XmlRpc::XmlRpcValue::TypeArray);
29  ROS_ASSERT(wheel.second["pose"].size() == 3);
30  ROS_ASSERT(wheel.second.hasMember("roller_angle"));
31  ROS_ASSERT(wheel.second.hasMember("radius"));
32 
33  // Ref: Modern Robotics, Chapter 13.2: Omnidirectional Wheeled Mobile Robots
34  Eigen::MatrixXd direction(1, 2), in_wheel(2, 2), in_chassis(2, 3);
35  double beta = (double)wheel.second["pose"][2];
36  double roller_angle = (double)wheel.second["roller_angle"];
37  direction << 1, tan(roller_angle);
38  in_wheel << cos(beta), sin(beta), -sin(beta), cos(beta);
39  in_chassis << -(double)wheel.second["pose"][1], 1., 0., (double)wheel.second["pose"][0], 0., 1.;
40  Eigen::MatrixXd chassis2joint = 1. / (double)wheel.second["radius"] * direction * in_wheel * in_chassis;
41  chassis2joints_.block<1, 3>(i, 0) = chassis2joint;
42 
43  ros::NodeHandle nh_wheel = ros::NodeHandle(controller_nh, "wheels/" + wheel.first);
44  joints_.push_back(std::make_shared<effort_controllers::JointVelocityController>());
45  if (!joints_.back()->init(effort_joint_interface_, nh_wheel))
46  return false;
47  joint_handles_.push_back(joints_[i]->joint_);
48 
49  i++;
50  }
51  return true;
52 }
53 
54 void OmniController::moveJoint(const ros::Time& time, const ros::Duration& period)
55 {
56  Eigen::Vector3d vel_chassis;
57  vel_chassis << vel_cmd_.z, vel_cmd_.x, vel_cmd_.y;
58  Eigen::VectorXd vel_joints = chassis2joints_ * vel_chassis;
59  for (size_t i = 0; i < joints_.size(); i++)
60  {
61  joints_[i]->setCommand(vel_joints(i));
62  joints_[i]->update(time, period);
63  }
64 }
65 
66 geometry_msgs::Twist OmniController::odometry()
67 {
68  Eigen::VectorXd vel_joints(joints_.size());
69  for (size_t i = 0; i < joints_.size(); i++)
70  vel_joints[i] = joints_[i]->joint_.getVelocity();
71  Eigen::Vector3d vel_chassis =
72  (chassis2joints_.transpose() * chassis2joints_).inverse() * chassis2joints_.transpose() * vel_joints;
73  geometry_msgs::Twist twist;
74  twist.angular.z = vel_chassis(0);
75  twist.linear.x = vel_chassis(1);
76  twist.linear.y = vel_chassis(2);
77  return twist;
78 }
79 
80 } // namespace rm_chassis_controllers
XmlRpc::XmlRpcValue::size
int size() const
rm_chassis_controllers::ChassisBase< rm_control::RobotStateInterface, hardware_interface::EffortJointInterface >::twist
void twist(const ros::Time &time, const ros::Duration &period)
The mode TWIST: Just moving chassis.
Definition: chassis_base.cpp:241
rm_chassis_controllers::OmniController::init
bool init(hardware_interface::RobotHW *robot_hw, ros::NodeHandle &root_nh, ros::NodeHandle &controller_nh) override
Definition: omni.cpp:15
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
rm_chassis_controllers::ChassisBase< rm_control::RobotStateInterface, hardware_interface::EffortJointInterface >::vel_cmd_
geometry_msgs::Vector3 vel_cmd_
Definition: chassis_base.h:200
rm_chassis_controllers::ChassisBase< rm_control::RobotStateInterface, hardware_interface::EffortJointInterface >::effort_joint_interface_
hardware_interface::EffortJointInterface * effort_joint_interface_
Definition: chassis_base.h:177
rm_chassis_controllers::OmniController
Definition: omni.h:13
rm_chassis_controllers::OmniController::joints_
std::vector< std::shared_ptr< effort_controllers::JointVelocityController > > joints_
Definition: omni.h:23
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(RobotLocalization::EkfNodelet, nodelet::Nodelet)
controller_interface::ControllerBase
hardware_interface::RobotHW
XmlRpc::XmlRpcValue::TypeArray
TypeArray
rm_chassis_controllers::ChassisBase::init
bool init(hardware_interface::RobotHW *robot_hw, ros::NodeHandle &root_nh, ros::NodeHandle &controller_nh) override
Get and check params for covariances. Setup odometry realtime publisher + odom message constant field...
Definition: chassis_base.cpp:83
ros::Time
rm_chassis_controllers::ChassisBase< rm_control::RobotStateInterface, hardware_interface::EffortJointInterface >::joint_handles_
std::vector< hardware_interface::JointHandle > joint_handles_
Definition: chassis_base.h:178
class_list_macros.hpp
ros_utilities.h
inverse
TFSIMD_FORCE_INLINE Quaternion inverse(const Quaternion &q)
rm_chassis_controllers::OmniController::chassis2joints_
Eigen::MatrixXd chassis2joints_
Definition: omni.h:24
ROS_ASSERT
#define ROS_ASSERT(cond)
omni.h
ros::Duration
rm_chassis_controllers::OmniController::moveJoint
void moveJoint(const ros::Time &time, const ros::Duration &period) override
Definition: omni.cpp:54
XmlRpc::XmlRpcValue
ros::NodeHandle
rm_chassis_controllers
Definition: balance.h:15
rm_chassis_controllers::OmniController::odometry
geometry_msgs::Twist odometry() override
Definition: omni.cpp:66


rm_chassis_controllers
Author(s): Qiayuan Liao
autogenerated on Sun May 4 2025 02:57:17