example_omnibase_free_roam.cpp
Go to the documentation of this file.
1 
10 #include <ros/ros.h>
11 #include <geometry_msgs/Twist.h>
12 #include "sensor_msgs/JointState.h"
13 #include "hebiros/AddGroupFromNamesSrv.h"
14 
15 #include <ros/console.h>
16 
17 using namespace hebiros;
18 
19 // Global Variables
20 sensor_msgs::JointState feedback;
21 geometry_msgs::Twist directions;
22 std::array<double, 3> omniVels;
23 std::array<double, 3> omniPos;
24 double rate_of_command = 60;
25 bool feedback_init = false;
26 bool keys_init = false;
27 
28 void feedback_callback(sensor_msgs::JointState data) {
29  /* Callback function which keeps up to date with the feedback from modules*/
30  feedback = data;
31  feedback_init = true;
32 }
33 
34 
35 void directions_callback(geometry_msgs::Twist data) {
36  /* Callback function that keeps up to date with key presses and commands */
37  directions = data;
38  keys_init = true;
39 }
40 
41 
43  /* Declare main kinematic variables */
44  double wheelRadius = 0.0762; // m
45  double baseRadius = 0.235; // m (center of omni to origin of base)
46  double speed = 0.3; // m/s
47  double wheelRotSpeed = M_PI/3; // (rad/s)
48  double ratio = sqrt(3)/2;
49 
50  // Wheel 1, front right
51  omniVels[0] = directions.linear.x * speed * 0.5/wheelRadius +
52  directions.linear.y * speed * -ratio/wheelRadius +
53  directions.angular.z * wheelRotSpeed * baseRadius/wheelRadius;
54 
55  // Wheel 2, front left
56  omniVels[1] = directions.linear.x * speed * 0.5/wheelRadius +
57  directions.linear.y * speed * ratio/wheelRadius +
58  directions.angular.z *wheelRotSpeed * baseRadius/wheelRadius;
59 
60  // Wheel 3, back center
61  omniVels[2] = directions.linear.x * -speed * 1/wheelRadius +
62  0 +
63  directions.angular.z * wheelRotSpeed * baseRadius/wheelRadius;
64 }
65 
66 
67 void updatePoseCmd() {
68  /* We assume that we have access to: */
69  // - feedback from modules
70  // - omniVels; the velocities being commanded to each module
71  // - rate-of-command; in hertz
72 
73  omniPos[0] = omniPos[0] + omniVels[0] * (1/rate_of_command);
74  omniPos[1] = omniPos[1] + omniVels[1] * (1/rate_of_command);
75  omniPos[2] = omniPos[2] + omniVels[2] * (1/rate_of_command);
76 }
77 
78 
79 int main(int argc, char ** argv) {
80 
81  // Initialize ROS node
82  ros::init(argc, argv, "example_omnibase_free_roam");
83 
84  ros::NodeHandle node;
85 
86  ros::Rate loop_rate(rate_of_command);
87 
88  ros::Subscriber key_subscriber = node.subscribe("keys/cmd_vel", 20,
90 
94 
95  std::string group_name = "omniGroup";
96 
97  // Create a group
98  ros::ServiceClient add_group_client = node.serviceClient<AddGroupFromNamesSrv>(
99  "/hebiros/add_group_from_names");
100 
101  // Create a subscriber to receive feedback from a group
102  // Register a callback that keeps the feedback updated
103  ros::Subscriber feedback_subscriber = node.subscribe(
104  "/hebiros/"+group_name+"/feedback/joint_state", 100, feedback_callback);
105 
106  // Publisher to send desired commands to a the group
107  ros::Publisher command_publisher = node.advertise<sensor_msgs::JointState>(
108  "/hebiros/"+group_name+"/command/joint_state", 100);
109 
110  // Construct the group using 3 known modules, connected to the network
111  AddGroupFromNamesSrv add_group_srv;
112  add_group_srv.request.group_name = group_name;
113  add_group_srv.request.names = {"_Wheel1", "_Wheel2", "_Wheel3"};
114  add_group_srv.request.families = {"Rosie"};
115 
116  // Call the add_group_from_urdf service to create a group until it succeeds
117  while(!add_group_client.call(add_group_srv)) {}
118 
119  sensor_msgs::JointState command_msg;
120  command_msg.name.push_back("Rosie/_Wheel1");
121  command_msg.name.push_back("Rosie/_Wheel2");
122  command_msg.name.push_back("Rosie/_Wheel3");
123 
124  command_msg.velocity.resize(3);
125  command_msg.position.resize(3);
126  feedback.position.resize(3);
127 
131 
132  /******** MAIN LOOP **********/
133 
134  bool startup_complete = false;
135 
136  while (ros::ok()) {
137  if ( !startup_complete ) {
138  /* Get the initial position of the wheels at startup */
139  if (feedback_init == true && keys_init == true) {
140  omniPos[0] = feedback.position[0];
141  omniPos[1] = feedback.position[1];
142  omniPos[2] = feedback.position[2];
143  startup_complete = true;
144  }
145 
146  } else {
147 
148  // Get the new velocities and position commands
149  updateOmniVels();
150  updatePoseCmd();
151 
152  /* Uncomment to see what velocity commands are being sent */
153  //ROS_INFO("%lg %lg %lg", omniVels[0], omniVels[1], omniVels[2]);
154 
155  // Set the velocity commands
156  command_msg.velocity[0] = omniVels[0];
157  command_msg.velocity[1] = omniVels[1];
158  command_msg.velocity[2] = omniVels[2];
159 
160  /* Uncomment to see what position commands are being sent */
161  //ROS_INFO("%lg %lg %lg", omniPos[0], omniPos[1], omniPos[2]);
162 
163  // Set the position commands
164  command_msg.position[0] = omniPos[0];
165  command_msg.position[1] = omniPos[1];
166  command_msg.position[2] = omniPos[2];
167 
168  // Send the commands
169  command_publisher.publish(command_msg);
170  }
171 
172  ros::spinOnce();
173  loop_rate.sleep();
174  }
175 
176  return 0;
177 }
178 
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
std::array< double, 3 > omniPos
void updatePoseCmd()
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool call(MReq &req, MRes &res)
double rate_of_command
void updateOmniVels()
geometry_msgs::Twist directions
#define M_PI
void feedback_callback(sensor_msgs::JointState data)
ROSCPP_DECL bool ok()
std::array< double, 3 > omniVels
int speed
PARAMETERS ##########.
Definition: key_read.py:91
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool sleep()
int main(int argc, char **argv)
void directions_callback(geometry_msgs::Twist data)
sensor_msgs::JointState feedback
ROSCPP_DECL void spinOnce()


hebiros_advanced_examples
Author(s): Xavier Artache , Matthew Tesch
autogenerated on Thu Sep 3 2020 04:13:22