robot_copy.cpp
Go to the documentation of this file.
1 // std lib
2 #include <sstream>
3 #include <iostream>
4 #include <fstream>
5 
6 // robotics cape library
7 #include <robotcontrol.h>
8 
9 // ros includes
10 #include <dynamic_reconfigure/server.h>
11 #include <geometry_msgs/Quaternion.h>
12 #include <geometry_msgs/Twist.h>
13 #include <imu_filter_madgwick/imu_filter.h>
14 #include <nav_msgs/Odometry.h>
15 #include <geometry_msgs/TwistWithCovarianceStamped.h>
16 #include <ros/package.h>
17 #include <ros/ros.h>
18 #include <std_msgs/Float32MultiArray.h>
19 #include <tf/transform_broadcaster.h>
20 #include <tf2/LinearMath/Quaternion.h>
21 #include <tf/transform_listener.h>
22 #include <sensor_msgs/Imu.h>
23 
24 // generated headers
25 #include <robot/RobotConfig.h>
26 
27 // definitions, constants, and macros
28 #include "robot/robot.h"
29 
30 // reference values (SI units)
31 float v_left_ref = 0.0;
32 float v_right_ref = 0.0;
33 float w_left_ref = 0.0;
34 float w_right_ref = 0.0;
35 
36 // actual values
37 int left_encoder = 0;
39 int right_encoder = 0;
41 float position_x = 0.0;
42 float position_y = 0.0;
43 float angle_th = 0.0;
44 float v_robot = 0.0;
45 float w_robot = 0.0;
46 float yaw = 0.0;
47 float pitch = 0.0;
48 float roll = 0.0;
49 
50 // odom
52 rc_mpu_data_t data;
53 ImuFilter imu_filter;
54 
55 // controller
56 float integral_left = 0.0;
57 float integral_right = 0.0;
58 float kp = 0.0;
59 float ki = 0.0;
60 
61 // line sensor
62 float line_values[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
63 
64 // pubs
65 ros::Publisher line_raw_pub;
66 ros::Publisher twist_pub;
67 
68 ros::Publisher imu_pub;
69 
70 /****************************************************************************************************
71  * Functions, procedures
72  ****************************************************************************************************/
73 // rc initialisation
74 int rc_init()
75 {
76  rc_kill_existing_process(2.0);
77  rc_enable_signal_handler();
78  rc_make_pid_file();
79  rc_motor_init();
80  rc_encoder_init();
81  rc_adc_init();
82  rc_gpio_init(S0, GPIOHANDLE_REQUEST_OUTPUT);
83  rc_gpio_init(S1, GPIOHANDLE_REQUEST_OUTPUT);
84  rc_gpio_init(S2, GPIOHANDLE_REQUEST_OUTPUT);
85  rc_gpio_init(LINE_LED, GPIOHANDLE_REQUEST_OUTPUT);
86  rc_mpu_config_t conf = rc_mpu_default_config();
87  conf.i2c_bus = 2;
88  conf.enable_magnetometer = 1;
89  conf.gpio_interrupt_pin_chip = 3;
90  conf.gpio_interrupt_pin = 21;
91  conf.dmp_sample_rate = 100; // sample rate
92  conf.compass_time_constant = 10; // default 25
93  conf.dmp_fetch_accel_gyro = 1;
94  conf.mag_sample_rate_div = 1;
95  rc_mpu_initialize_dmp(&data, conf);
96  return 0;
97 }
98 
99 // read line sensors
100 void read_sensors()
101 {
102  try
103  {
104  // line sensors
105  rc_gpio_set_value(LINE_LED, 1);
106  rc_usleep(1000);
107  for (int i = 1; i <= 6; i++)
108  {
109  rc_gpio_set_value(S0, bitRead(i, 0));
110  rc_gpio_set_value(S1, bitRead(i, 1));
111  rc_gpio_set_value(S2, bitRead(i, 2));
112  line_values[6 - i] = rc_adc_read_volt(1);
113  }
114  rc_gpio_set_value(LINE_LED, 0);
115  rc_usleep(1000);
116  for (int i = 1; i <= 6; i++)
117  {
118  rc_gpio_set_value(S0, bitRead(i, 0));
119  rc_gpio_set_value(S1, bitRead(i, 1));
120  rc_gpio_set_value(S2, bitRead(i, 2));
121  line_values[6 - i] = line_values[6 - i] - rc_adc_read_volt(1) + 1.8;
122  }
123  std_msgs::Float32MultiArray line_raw_msg;
124  for (int i = 0; i < 6; i++)
125  {
126  line_raw_msg.data.push_back(line_values[i]);
127  }
128  line_raw_pub.publish(line_raw_msg);
129  }
130  catch (const std::exception &e)
131  {
132  ROS_ERROR_STREAM(e.what());
133  }
134 }
135 
136 /****************************************************************************************************
137  * Callbacks
138  ****************************************************************************************************/
139 
140 // Twist message callback: sets reference speeds
141 void twistCallback(const geometry_msgs::Twist::ConstPtr &msg)
142 {
143  v_left_ref = msg->linear.x - msg->angular.z * TRACK_WIDTH_HALF_M;
144  v_right_ref = msg->linear.x + msg->angular.z * TRACK_WIDTH_HALF_M;
147 }
148 
149 // dynamic reconfigure params
150 void dynamic_callback(robot::RobotConfig &config, uint32_t level)
151 {
152  ROS_INFO_STREAM("Parameter reconfigure requested.");
153  kp = config.motor_p;
154  ki = config.motor_i;
155  odom_source = config.odom_source;
156 }
157 
158 /****************************************************************************************************
159  * Main
160  ****************************************************************************************************/
161 
162 int main(int argc, char **argv)
163 {
164  ros::init(argc, argv, "robot_node");
165  ros::NodeHandle n;
166  ros::Subscriber sub = n.subscribe("cmd_vel", 1000, twistCallback);
167  line_raw_pub = n.advertise<std_msgs::Float32MultiArray>("line_sensors_raw", 1000);
168  twist_pub = n.advertise<geometry_msgs::TwistWithCovarianceStamped>("twist_beagle", 1000);
169  //
170  imu_pub = n.advertise<sensor_msgs::Imu>("imu_beagle", 1000);
171 
172  static tf::TransformBroadcaster imu_broadcaster;
173 
174  std::string odom_tf;
175  std::string base_link_tf;
176  std::string imu_link_tf;
177 
178 
179  if (n.getParam("odom_tf", odom_tf) && n.getParam("base_link_tf", base_link_tf)
180  && n.getParam("imu_link_tf", imu_link_tf)){}
181  else
182  {
183  ROS_ERROR("Failed to get param.");
184  }
185 
186  tf::TransformListener listener;
187 
188  // dynamic reconfigure
189  dynamic_reconfigure::Server<robot::RobotConfig> server;
190  dynamic_reconfigure::Server<robot::RobotConfig>::CallbackType f;
191  f = boost::bind(&dynamic_callback, _1, _2);
192  server.setCallback(f);
193 
194  rc_init();
195 
196  // filter config
197  imu_filter.setAlgorithmGain(0.2);
198  // main loop
199  ros::Rate loop_rate(SAMPLE_RATE_HZ);
200  double start_time = ros::Time::now().toSec();
201  ROS_INFO_STREAM("Sensor calibration in progress...");
202  // while (ros::ok() && ros::Time::now().toSec() - start_time < 5)
203  // {
204  // imu_filter.madgwickAHRSupdate(
205  // data.gyro[1] * DEG_TO_RAD, -data.gyro[0] * DEG_TO_RAD, data.gyro[2] * DEG_TO_RAD,
206  // data.accel[1], -data.accel[0], data.accel[2],
207  // data.mag[1], -data.mag[0], data.mag[2],
208  // DT);
209  // double q0, q1, q2, q3;
210  // imu_filter.getOrientation(q0, q1, q2, q3);
211  // yaw = atan2(2.0f * (q1 * q2 + q0 * q3), q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3);
212  // pitch = -asin(2.0f * (q1 * q3 - q0 * q2));
213  // roll = atan2(2.0f * (q0 * q1 + q2 * q3), q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3);
214  // angle_th = yaw;
215  // w_robot = data.gyro[2] * DEG_TO_RAD;
216  // ros::spinOnce();
217  // loop_rate.sleep();
218  // }
219  ROS_INFO_STREAM("Sensor calibration complete...");
220  while (ros::ok())
221  {
222  // speed measurement
227  float v_left = s_left / DT;
228  float v_right = s_right / DT;
229  float w_left = v_left / WHEEL_RADIUS_M;
230  float w_right = v_right / WHEEL_RADIUS_M;
231 
232  // odometry
233  float s_total = (s_left + s_right) / 2.0;
234 
235  tf::StampedTransform transform;
236  try{
237  listener.lookupTransform(odom_tf, base_link_tf, ros::Time(0), transform);
238  }
239  catch (tf::TransformException ex){
240  }
241  angle_th = tf::getYaw(transform.getRotation());
242 
243  v_robot = s_total / DT;
244 
247 
248 
249  w_robot = (s_right - s_left) / TRACK_WIDTH_M / DT;
250  // publihs speed
251  ros::Time current_time = ros::Time::now();
252  geometry_msgs::TwistWithCovarianceStamped measured_twist;
253  measured_twist.header.stamp = current_time;
254  measured_twist.header.frame_id = odom_tf;
255  measured_twist.twist.twist.linear.x = v_robot * cos(angle_th);
256  measured_twist.twist.twist.linear.y = v_robot * sin(angle_th);
257  measured_twist.twist.twist.angular.z = w_robot;
258 
259  measured_twist.twist.covariance[0] = 0.1;
260  measured_twist.twist.covariance[7] = 0.1;
261  measured_twist.twist.covariance[14] = 0.1;
262  measured_twist.twist.covariance[21] = 0.1;
263  measured_twist.twist.covariance[28] = 0.1;
264  measured_twist.twist.covariance[35] = 0.1;
265 
266  twist_pub.publish(measured_twist);
267 
268  // publish base->imu_link transform
269  geometry_msgs::TransformStamped imu_trans;
270  imu_trans.header.stamp = current_time;
271  imu_trans.header.frame_id = base_link_tf;
272  imu_trans.child_frame_id = imu_link_tf;
273  imu_trans.transform.translation.x = 0.04; // [m]
274  imu_trans.transform.translation.y = 0.0;
275  imu_trans.transform.translation.z = 0.0;
276  imu_trans.transform.rotation = tf::createQuaternionMsgFromRollPitchYaw(0.0, 0.0, 0.0); // kao izklopljeno
277  imu_broadcaster.sendTransform(imu_trans);
278 
279  // publish imu
280  sensor_msgs::Imu imu;
281  imu.header.stamp = current_time;
282  imu.header.frame_id = imu_link_tf;
283  geometry_msgs::Quaternion imu_quat = tf::createQuaternionMsgFromRollPitchYaw(0.0, 0.0, angle_th);
284  //geometry_msgs::Quaternion imu_quat = tf::createQuaternionMsgFromRollPitchYaw(data.fused_TaitBryan[1], -data.fused_TaitBryan[0], data.fused_TaitBryan[2]);
285  imu.orientation = imu_quat;
286  imu.angular_velocity.x = data.gyro[1] * DEG_TO_RAD; //vrol
287  imu.angular_velocity.y = -data.gyro[0] * DEG_TO_RAD; //vpitch
288  imu.angular_velocity.z = data.gyro[2] * DEG_TO_RAD; //vyaw
289  imu.linear_acceleration.x = data.accel[1]; //ax
290  imu.linear_acceleration.y = -data.accel[0]; //ay
291  imu.linear_acceleration.z = data.accel[2]; //az
292 
293  imu.orientation_covariance[0] = 0.1;
294  imu.orientation_covariance[4] = 0.1;
295  imu.orientation_covariance[8] = 0.1;
296 
297  imu.angular_velocity_covariance[0] = 0.1;
298  imu.angular_velocity_covariance[4] = 0.1;
299  imu.angular_velocity_covariance[8] = 0.1;
300 
301  imu.linear_acceleration_covariance[0] = 0.1;
302  imu.linear_acceleration_covariance[4] = 0.1;
303  imu.linear_acceleration_covariance[8] = 0.1;
304 
305  imu_pub.publish(imu);
306 
307  // PID control
308  float error_left = w_left_ref - w_left;
309  integral_left = constrain(integral_left + error_left * DT, -10.0, 10.0);
310  float pwm_left = constrain(kp * error_left + ki * integral_left, -1.0, 1.0);
311  float error_right = w_right_ref - w_right;
312  integral_right = constrain(integral_right + error_right * DT, -10.0, 10.0);
313  float pwm_right = constrain(kp * error_right + ki * integral_right, -1.0, 1.0);
314  rc_motor_set(MOTOR_CHANNEL_L, pwm_left * MOTOR_POLARITY_L);
315  rc_motor_set(MOTOR_CHANNEL_R, pwm_right * MOTOR_POLARITY_R);
316 
317  ros::spinOnce();
318  loop_rate.sleep();
319  }
320 
321  // rc cleanup
322  rc_adc_cleanup();
323  rc_gpio_cleanup(S0);
324  rc_gpio_cleanup(S1);
325  rc_gpio_cleanup(S2);
326  rc_gpio_cleanup(LINE_LED);
327  rc_encoder_cleanup();
328  rc_motor_cleanup();
329  rc_remove_pid_file();
330 
331  return 0;
332 }
main
int main(int argc, char **argv)
Definition: robot_copy.cpp:159
twist_pub
ros::Publisher twist_pub
Definition: robot_copy.cpp:66
bitRead
#define bitRead(value, bit)
Definition: robot.h:6
robot.h
GEARBOX
#define GEARBOX
Structural properties.
Definition: robot.h:21
v_robot
float v_robot
Definition: robot_copy.cpp:44
roll
float roll
Definition: robot_copy.cpp:48
v_right_ref
float v_right_ref
Definition: robot_copy.cpp:32
DEG_TO_RAD
#define DEG_TO_RAD
Definition: robot.h:13
constrain
#define constrain(amt, low, high)
Macros (Arduino-style here)
Definition: robot.h:5
kp
float kp
Definition: robot_copy.cpp:58
angle_th
float angle_th
Definition: robot_copy.cpp:43
v_left_ref
float v_left_ref
Definition: robot_copy.cpp:31
right_encoder
int right_encoder
Definition: robot_copy.cpp:39
w_robot
float w_robot
Definition: robot_copy.cpp:45
S1
#define S1
Definition: robot.h:40
data
rc_mpu_data_t data
Definition: robot_copy.cpp:52
rc_init
int rc_init()
Definition: robot_copy.cpp:73
left_encoder
int left_encoder
Definition: robot_copy.cpp:37
MOTOR_CHANNEL_L
#define MOTOR_CHANNEL_L
Electrical hookups.
Definition: robot.h:31
imu_pub
ros::Publisher imu_pub
Definition: robot_copy.cpp:68
ENCODER_CHANNEL_R
#define ENCODER_CHANNEL_R
Definition: robot.h:36
line_values
float line_values[6]
Definition: robot_copy.cpp:62
left_encoder_previous
int left_encoder_previous
Definition: robot_copy.cpp:38
DT
#define DT
Definition: robot.h:18
position_x
float position_x
Definition: robot_copy.cpp:41
w_right_ref
float w_right_ref
Definition: robot_copy.cpp:34
integral_right
float integral_right
Definition: robot_copy.cpp:57
TRACK_WIDTH_HALF_M
#define TRACK_WIDTH_HALF_M
Definition: robot.h:26
TRACK_WIDTH_M
#define TRACK_WIDTH_M
Definition: robot.h:25
right_encoder_previous
int right_encoder_previous
Definition: robot_copy.cpp:40
read_sensors
void read_sensors()
Definition: robot_copy.cpp:99
yaw
float yaw
Definition: robot_copy.cpp:46
WHEEL_DIAMETER_M
#define WHEEL_DIAMETER_M
Definition: robot.h:23
S2
#define S2
Definition: robot.h:41
LINE_LED
#define LINE_LED
Definition: robot.h:42
ki
float ki
Definition: robot_copy.cpp:59
dynamic_callback
void dynamic_callback(robot::RobotConfig &config, uint32_t level)
Definition: robot_copy.cpp:148
MOTOR_CHANNEL_R
#define MOTOR_CHANNEL_R
Definition: robot.h:32
position_y
float position_y
Definition: robot_copy.cpp:42
SAMPLE_RATE_HZ
#define SAMPLE_RATE_HZ
Control loop properties.
Definition: robot.h:17
S0
#define S0
Definition: robot.h:39
integral_left
float integral_left
Definition: robot_copy.cpp:56
PI
#define PI
Constants.
Definition: robot.h:11
MOTOR_POLARITY_R
#define MOTOR_POLARITY_R
Definition: robot.h:34
twistCallback
void twistCallback(const geometry_msgs::Twist::ConstPtr &msg)
Definition: robot_copy.cpp:139
MOTOR_POLARITY_L
#define MOTOR_POLARITY_L
Definition: robot.h:33
line_raw_pub
ros::Publisher line_raw_pub
Definition: robot_copy.cpp:65
ENCODER_POLARITY_L
#define ENCODER_POLARITY_L
Definition: robot.h:37
ENCODER_CHANNEL_L
#define ENCODER_CHANNEL_L
Definition: robot.h:35
ENCODER_POLARITY_R
#define ENCODER_POLARITY_R
Definition: robot.h:38
WHEEL_RADIUS_M
#define WHEEL_RADIUS_M
Definition: robot.h:24
w_left_ref
float w_left_ref
Definition: robot_copy.cpp:33
odom_source
int odom_source
Definition: robot_copy.cpp:51
ENCODER_RES
#define ENCODER_RES
Definition: robot.h:22
pitch
float pitch
Definition: robot_copy.cpp:47
imu_filter
ImuFilter imu_filter
Definition: robot_copy.cpp:53


rosinljubljana
Author(s): Igor Banfi
autogenerated on Mon Feb 24 2020 12:32:36