Robotics Lab 12 - C++ Programming in ROS (Open-Ended Lab)
Robotics Lab 12 - C++ Programming in ROS (Open-Ended Lab)
EE381 Robotics
Lab 12: C++ Programming in ROS
<Open-ended Lab>
EE-381 – Robotics
Introduction
Objectives
Lab Conduct
EE-381 – Robotics
Theory
In robotics, the two most popular languages for programming robots are C++
and Python. For prototype development and design concepts, python is used
due to its user-friendly nature. For practical implementation, C++ is used as the
code is compiled and thus runs much faster on the machine. A major issue with
C++ programming is its’ high difficulty. In ROS, there is extensive support for
both Python (rclpy) and C++ (rclcpp) as well as limited support for other
programming languages.
. install/setup.bash
make the terminal “aware” of the workspace (notice the dot and space)
EE-381 – Robotics
Open-Ended Lab Details ____________________________________________________________
Design and implement a ROS implementation that solves a specified problem with the
constraint of using C++ programming in the nodes.
Note that the problem to be solved, as well as the solution to be designed are both
open-ended in nature. Students are expected to come up with their own creative
ideas and implementations for the lab.
/*
* you may not use this file except in compliance with the License.
EE-381 – Robotics
* https://www.apache.org/licenses/LICENSE-2.0
* See the License for the specific language governing permissions and
*/
#include <math.h>
#include <stdio.h>
#include <webots/compass.h>
#include <webots/gps.h>
#include <webots/keyboard.h>
#include <webots/motor.h>
#include <webots/robot.h>
#define TIME_STEP 16
#define TARGET_POINTS_SIZE 13
EE-381 – Robotics
#define TURN_COEFFICIENT 4.0
double u;
double v;
} Vector;
};
EE-381 – Robotics
static int current_target_index = 0;
double r = a - div * m;
if (r < 0.0)
r += m;
return r;
int i;
EE-381 – Robotics
static void check_keyboard() {
if (key >= 0) {
switch (key) {
case WB_KEYBOARD_UP:
speeds[LEFT] = MAX_SPEED;
speeds[RIGHT] = MAX_SPEED;
autopilot = false;
break;
case WB_KEYBOARD_DOWN:
speeds[LEFT] = -MAX_SPEED;
speeds[RIGHT] = -MAX_SPEED;
autopilot = false;
break;
case WB_KEYBOARD_RIGHT:
speeds[LEFT] = MAX_SPEED;
speeds[RIGHT] = -MAX_SPEED;
autopilot = false;
EE-381 – Robotics
break;
case WB_KEYBOARD_LEFT:
speeds[LEFT] = -MAX_SPEED;
speeds[RIGHT] = MAX_SPEED;
autopilot = false;
break;
case 'P':
break;
case 'A':
autopilot = !autopilot;
break;
if (autopilot != old_autopilot) {
old_autopilot = autopilot;
if (autopilot)
EE-381 – Robotics
printf("auto control\n");
else
printf("manual control\n");
robot_set_speed(speeds[LEFT], speeds[RIGHT]);
old_key = key;
// ||v||
// v = v/||v||
double n = norm(v);
v->u /= n;
v->v /= n;
EE-381 – Robotics
// v = v1-v2
static void minus(Vector *v, const Vector *const v1, const Vector *const v2) {
// autopilot
Vector direction;
EE-381 – Robotics
minus(&direction, &(targets[current_target_index]), &position);
normalize(&direction);
// move singularity
if (beta > 0)
else
if (current_target_index == 0)
sprintf(index_char, "st");
else if (current_target_index == 1)
EE-381 – Robotics
sprintf(index_char, "nd");
else if (current_target_index == 2)
sprintf(index_char, "rd");
current_target_index++;
current_target_index %= TARGET_POINTS_SIZE;
else {
robot_set_speed(speeds[LEFT], speeds[RIGHT]);
wb_robot_init();
EE-381 – Robotics
// print user instructions
printf("\n");
wb_robot_step(1000);
const char *names[8] = {"left motor 1", "left motor 2", "left motor 3", "left motor 4",
"right motor 1", "right motor 2", "right motor 3", "right motor 4"};
int i;
motors[i] = wb_robot_get_device(names[i]);
wb_motor_set_position(motors[i], INFINITY);
gps = wb_robot_get_device("gps");
EE-381 – Robotics
wb_gps_enable(gps, TIME_STEP);
compass = wb_robot_get_device("compass");
wb_compass_enable(compass, TIME_STEP);
// enable keyboard
wb_keyboard_enable(TIME_STEP);
robot_set_speed(MAX_SPEED, MAX_SPEED);
// main loop
check_keyboard();
if (autopilot)
run_autopilot();
wb_robot_cleanup();
EE-381 – Robotics
return 0;
EE-381 – Robotics
TIME_STEP, TARGET_POINTS_SIZE, DISTANCE_TOLERANCE,
MAX_SPEED, and TURN_COEFFICIENT.
2. Data Structures:
Vector struct to represent 2D vectors.
Enums for array indexing and side identification.
3. Global Variables:
Motor tags, GPS, and compass device tags.
An array of target points (targets) and control variables for autopilot
and keyboard states.
4. Utility Functions:
modulus_double: Calculates the modulus of a double value.
robot_set_speed: Sets the speed for all motors.
check_keyboard: Processes keyboard inputs to control the robot
manually or toggle autopilot.
norm, normalize, minus: Vector operations for distance calculation
and direction normalization.
5. Autopilot Function (run_autopilot):
Reads GPS and compass data.
Computes the direction and distance to the current target.
Normalizes the direction vector.
Calculates the error angle between the robot's orientation and the
target direction.
Adjusts the robot's speed to move towards the target.
Advances to the next target upon reaching the current one.
6. Main Function:
Initializes Webots communication.
Prints user instructions.
Retrieves motor, GPS, and compass devices.
Enables GPS, compass, and keyboard.
Sets initial motor speeds.
Main loop to continually check keyboard input and run autopilot if
enabled.
EE-381 – Robotics
Cleans up Webots resources upon exit.
EE-381 – Robotics