Tetrapod Project
single_motor_controller.cpp
Go to the documentation of this file.
2 
3 SingleMotorController::SingleMotorController(double _publish_frequency, bool _use_position_control)
4 {
5  publish_frequency = _publish_frequency;
6 
8 }
9 
11 {
12  publish_frequency = _publish_frequency;
13 
15 }
16 
18 {
19  if(!ros::isInitialized())
20  {
21  int argc = 0;
22  char **argv = NULL;
23  ros::init
24  (
25  argc,
26  argv,
27  "single_motor_controller_node",
28  ros::init_options::NoSigintHandler
29  );
30  }
31 
32  node_handle.reset(new ros::NodeHandle("single_motor_controller_node"));
33 
35  (
36  "/motor/states",
37  100,
39  this
40  );
41 
43  (
44  "/readyToProceed",
45  1,
47  this
48  );
49 
50  set_goal_subscriber = node_handle->subscribe
51  (
52  "/set_goal",
53  1,
55  this
56  );
57 
59  (
60  "/motor/confirmation",
61  10,
63  this
64  );
65 
67  (
68  "/logging/continue",
69  10,
71  this
72  );
73 
74  joint_command_publisher = node_handle->advertise<sensor_msgs::JointState>("/my_robot/joint_state_cmd", 10);
75 
76  motor_gain_publisher = node_handle->advertise<std_msgs::Float64MultiArray>("/motor/gains", 1);
77 
78  log_motor_state_publisher = node_handle->advertise<sensor_msgs::JointState>("/logging/states", 10);
79 
80  log_motor_reference_publisher = node_handle->advertise<sensor_msgs::JointState>("/logging/references", 10);
81 
82  ROS_INFO("initROS complete");
83 }
84 
85 void SingleMotorController::motorStateCallback(const sensor_msgs::JointStatePtr &_msg)
86 {
87  //ROS_INFO("MOTOR STATE CALLBACK");
88  angle_pos = _msg->position[0];
89  angle_vel = _msg->velocity[0];
90  torque = _msg->effort[0];
91 }
92 
93 void SingleMotorController::readyToProceedCallback(const std_msgs::Bool &_msg)
94 {
95  ROS_INFO("READY!");
96  ready_to_proceed = _msg.data;
97 }
98 
99 void SingleMotorController::setGoalCallback(const std_msgs::Float32 &_msg)
100 {
101  double angle_goal_pos = _msg.data*M_PI/180.0;
102 
103  max_travel = angle_goal_pos - angle_offset;
104 
105  current_iteration = 0.0;
106 }
107 
108 void SingleMotorController::motorConfirmationCallback(const std_msgs::Bool &_msg)
109 {
110  if(_msg.data)
111  {
112  motor_initialized = true;
113  }
114 }
115 
116 void SingleMotorController::keepLoggingCallback(const std_msgs::Bool &_msg)
117 {
118  keep_logging = _msg.data;
119 }
120 
122 (
123  const double &_percentage,
124  const double &_period,
125  const double &_max_travel,
126  double &_x,
127  double &_x_d,
128  double &_x_dd
129 )
130 {
131  double a = 30.0*_max_travel;
132  double b = -15.0*_max_travel;
133  double c = 1.875*_max_travel;
134  double d = -_max_travel*7.0/16.0;
135 
136  _x = 0.2*a*pow((_percentage - 0.5), 5.0) + b*pow((_percentage - 0.5), 3.0)/3.0 + c*_percentage + d;
137  _x_d = (a*pow((_percentage - 0.5), 4.0) + b*pow((_percentage - 0.5), 2.0) + c)/_period;
138  _x_dd = (4.0*a*pow((_percentage - 0.5), 3.0) + 2.0*b*(_percentage - 0.5))/(_period*_period);
139 }
140 
142 {
143  double desired_angle_travel;
144 
146 
147  angle_pos_ref = angle_offset + desired_angle_travel;
148 }
149 
151 {
152  sensor_msgs::JointState joint_command_msg;
153 
154  joint_command_msg.position.push_back(angle_pos_ref);
155  joint_command_msg.velocity.push_back(IDLE_COMMAND);
156  joint_command_msg.effort.push_back(IDLE_COMMAND);
157 
158  joint_command_msg.header.stamp = ros::Time::now();
159 
160  joint_command_publisher.publish(joint_command_msg);
161 }
162 
164 {
165  sensor_msgs::JointState joint_command_msg;
166 
168 
169  joint_command_msg.position.push_back(IDLE_COMMAND);
170  joint_command_msg.velocity.push_back(IDLE_COMMAND);
171  joint_command_msg.effort.push_back(torque_ref);
172 
173  joint_command_msg.header.stamp = ros::Time::now();
174 
175  joint_command_publisher.publish(joint_command_msg);
176 }
177 
179 {
181 
183  {
185 
187 
188  max_travel = 0.0;
189  }
190 }
191 
192 
194 {
195  ros::Rate publish_position_command_rate(10);
196 
197  sensor_msgs::JointState joint_command_msg;
198 
199  joint_command_msg.position.push_back(0.0);
200  joint_command_msg.velocity.push_back(IDLE_COMMAND);
201  joint_command_msg.effort.push_back(IDLE_COMMAND);
202 
203  joint_command_msg.header.stamp = ros::Time::now();
204 
205  while(abs(angle_pos) > 0.0174)
206  {
207  ros::spinOnce();
208 
209  joint_command_publisher.publish(joint_command_msg);
210 
211  publish_position_command_rate.sleep();
212  }
213 }
214 
216 {
217  sensor_msgs::JointState joint_command_msg;
218 
219  angle_pos_ref = _joint_pos;
220 
221  joint_command_msg.position.push_back(_joint_pos);
222  joint_command_msg.velocity.push_back(IDLE_COMMAND);
223  joint_command_msg.effort.push_back(IDLE_COMMAND);
224 
225  joint_command_msg.header.stamp = ros::Time::now();
226 
227  joint_command_publisher.publish(joint_command_msg);
228 }
229 
231 {
232  sensor_msgs::JointState joint_command_msg;
233 
234  angle_vel_ref = _joint_vel;
235 
236  joint_command_msg.position.push_back(IDLE_COMMAND);
237  joint_command_msg.velocity.push_back(_joint_vel);
238  joint_command_msg.effort.push_back(IDLE_COMMAND);
239 
240  joint_command_msg.header.stamp = ros::Time::now();
241 
242  joint_command_publisher.publish(joint_command_msg);
243 }
244 
246 {
247  torque_ref = _torque;
248 
249  sensor_msgs::JointState joint_command_msg;
250 
251  joint_command_msg.position.push_back(IDLE_COMMAND);
252  joint_command_msg.velocity.push_back(IDLE_COMMAND);
253  joint_command_msg.effort.push_back(_torque);
254 
255  joint_command_msg.header.stamp = ros::Time::now();
256 
257  joint_command_publisher.publish(joint_command_msg);
258 }
259 
260 void SingleMotorController::initializeMotor(double _k_p_pos, double _k_i_pos, double _k_p_vel, double _k_i_vel, double _k_p_torque, double _k_i_torque)
261 {
262  ros::Rate set_gain_rate(0.5);
263 
264  motor_initialized = false;
265 
266  std_msgs::Float64MultiArray motor_gains_msg;
267 
268  motor_gains_msg.data.push_back(_k_p_pos);
269  motor_gains_msg.data.push_back(_k_i_pos);
270  motor_gains_msg.data.push_back(_k_p_vel);
271  motor_gains_msg.data.push_back(_k_i_vel);
272  motor_gains_msg.data.push_back(_k_p_torque);
273  motor_gains_msg.data.push_back(_k_i_torque);
274 
275  ROS_INFO("Trying to set motor gains");
276 
277  while(!motor_initialized)
278  {
279  motor_gain_publisher.publish(motor_gains_msg);
280 
281  ROS_INFO("Requisting motor reply");
282 
283  set_gain_rate.sleep();
284 
286  }
287 
288  ROS_INFO("Motor setup complete");
289 }
290 
292 {
294 }
295 
297 {
298  if(ready_to_proceed)
299  {
300  return true;
301  }
302  else
303  {
304  return false;
305  }
306 }
307 
309 {
311  {
312  return false;
313  }
314  else
315  {
316  return true;
317  }
318 }
319 
321 {
322  ros::spinOnce();
323 }
324 
326 {
327  ROS_INFO("I: %f\tq: %f\tq_ref: %f\tq_d: %f\tq_d_ref: %f\tq_dd_ref: %f\tT: %f\tT_ref: %f",
329 }
330 
332 {
333  sensor_msgs::JointState joint_state_msg;
334 
335  joint_state_msg.position.push_back(angle_pos);
336  joint_state_msg.velocity.push_back(angle_vel);
337  joint_state_msg.effort.push_back(torque);
338 
339  joint_state_msg.header.stamp = ros::Time::now();
340 
341  sensor_msgs::JointState joint_reference_msg;
342 
343  joint_reference_msg.position.push_back(angle_pos_ref);
344  joint_reference_msg.velocity.push_back(angle_vel_ref);
345  joint_reference_msg.effort.push_back(torque_ref);
346 
347  joint_reference_msg.header.stamp = ros::Time::now();
348 
349  log_motor_state_publisher.publish(joint_state_msg);
350 
351  log_motor_reference_publisher.publish(joint_reference_msg);
352 }
ros::Subscriber ready_to_proceed_subscriber
ros::Subscriber motor_confirmation_subscriber
void readyToProceedCallback(const std_msgs::Bool &_msg)
void calculateSingleAxisTrajectory(const double &_percentage, const double &_period, const double &_max_travel, double &_x, double &_x_d, double &_x_dd)
ros::Subscriber keep_logging_subscriber
std::unique_ptr< ros::NodeHandle > node_handle
void setPositionDirectly(double _joint_pos)
void setTorqueDirectly(double _torque)
ros::Publisher joint_command_publisher
ros::Subscriber motor_state_subscriber
void setVelocityDirectly(double _joint_vel)
ros::Publisher log_motor_state_publisher
void keepLoggingCallback(const std_msgs::Bool &_msg)
void motorConfirmationCallback(const std_msgs::Bool &_msg)
SingleMotorController(double _publish_frequency, bool _use_position_control)
void motorStateCallback(const sensor_msgs::JointStatePtr &_msg)
void setGoalCallback(const std_msgs::Float32 &_msg)
ros::Publisher log_motor_reference_publisher