One foundational concept in robotics is sensory-motor loops and control. The robot's sensor readings inform how it moves in its environment, which will then influence the next sensor readings from the robot, and the loop goes on. One of the most well known sensory-motor control methods is PID (Proportional Integral Derivative) control, which is depicted in the block diagram below:
The PID control function can be represented as follows:
Where Kp, Ki, and Kd, are the constant coefficients for the proportional, integral, and derivative terms; e(t) represents the difference between the goal (setpoint) and the sensor measurement (process variable). The three following graphs display how a system responds to a step change in the setpoint to each component of the PID controller separately and all the components combined at different values of Kp, Ki, and Kd.
This YouTube video by Brian Douglas is a great resource providing a clear explanation of the PID controller.
setup.py
gazebo_lineFollow.launch.py
camera_lidar_gazebo.urdf
line_world.world
launch_config.rviz
$ ros2 launch iml_buche gazebo_lineFollow.launch.py
In Gazebo, you should see a vehicule at the beginning of a yellow line in an enclosed room (see image below). Your goal is to program the robot to follow the yellow line, writing your code in line_follower.py
.
The starter code implements a helpful debugging window to help visualize the center of the computed yellow pixels. Once you've correctly identified the center of the yellow pixes, your window should look something like the following:
Read through the starter code in line_follower.py
. We encourage you to look up what certain OpenCV functions do to better understand what's going on. Make sure that you all discuss and understand what the following variables represent and what values they will hold: h
, w
, d
, cx
, cy
.
This programming exercise contains 2 main components:
H: 0-179, S: 0-255, V: 0-255
. As this OpenCV documentation suggests, you may find the following helpful (except you'll want to investigate yellow instead of green):
green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print(hsv_green)
H: 0-360, S: 0.0-1.0, V: 0.0-1.0
to the numeric ranges OpenCV expects H: 0-179, S: 0-255, V: 0-255
.
To run your code:
$ ros2 run iml_buche line_follower_mode
Once you've successfully implemented your proportional control line follower, it should look something like the following: