Welcome to MicroROS V2 Robot Car repository
8. Object Follow
Object Follow
Package: microros_v2_kcf_follow_pkg
1. Feature Description
microros_v2_kcf_follow_pkg is a follow controller based on the target bounding box. It only subscribes to the target box published by a tracking node, and then controls the pan-tilt and/or the body motion.
Therefore, the complete functionality consists of two parts:
- A tracker obtains the target bounding box from the image, e.g.
smart_tracker/super_trackeror the KCF tracking node. tracking_bbox_follow_nodecomputes the pan-tilt angle, the body angular velocity, and the body linear velocity from the target box center and the target box size.
The default control rate is 10 Hz. When the target box is invalid, its confidence is too low, or it has not been updated for longer than target_stale_timeout_sec, the node immediately publishes zero velocity; the source code has no "allow 5 more frames of movement" lost-target tolerance logic.
2. Control Chain
Camera / vision tracker └── /tracking_bbox └── tracking_bbox_follow_node (10 Hz) ├── PTZ follow: target center -> /cmd_ptz_angle ├── Body turning: target horizontal error or pan-tilt angle -> /cmd_vel.angular.z └── Distance follow: target box size error -> /cmd_vel.linear.xPTZ Version
enable_ptz_follow:=true by default:
- Based on the pixel error of the target center relative to the image center, independent X/Y PD control updates the pan-tilt angles.
- Once the pan-tilt horizontal angle deviates from the initial angle by
servo1_engage_deg, the body PD control drivesangular.z, letting the body gradually follow the pan-tilt back to center. linear.xcan be controlled simultaneously based on the target box size.
No-PTZ Version
A fixed camera cannot adjust its line of sight through the pan-tilt, so at startup you must set:
xxxxxxxxxxenable_ptz_follow:=false publish_initial_ptz_command:=falseIn this mode the node uses the target center's horizontal pixel error to control the body angular.z, and controls linear.x based on the target box size. Setting only publish_initial_ptz_command:=false does not disable the PTZ follow logic, so it cannot be the only change for a No-PTZ configuration.
3. Topics and Messages
| Topic | Direction | Message Type | QoS | Description |
|---|---|---|---|---|
/tracking_bbox | Subscribe | Auto-discovered by default | BEST_EFFORT, depth=1 | Target bounding box input |
/cmd_vel | Publish | geometry_msgs/msg/Twist | BEST_EFFORT, depth=1 | linear.x forward/back, angular.z left/right turn |
/cmd_ptz_angle | Publish | geometry_msgs/msg/Vector3 | depth=10 | Published in PTZ mode; x is the horizontal angle, y is the tilt angle, in degrees |
/JoyState | Subscribe | std_msgs/msg/Bool | depth=10 | When true, pauses auto-follow and publishes zero velocity |
The node is also compatible with:
smart_tracker/msg/TrackBox, auto-discovered viatracking_bbox_msg_type:=auto;std_msgs/msg/Int32MultiArray: when the length is at least 11, it is parsed as[valid, x1, y1, x2, y2, cx, cy, width, height, image_width, image_height]; when the length is 4 to 10, the first four elements are taken as the bounding box;- messages with
x1,y1,x2,y2fields.
The bounding box format is uniformly the top-left (x1, y1) and bottom-right (x2, y2). The node auto-sorts the coordinates and checks the width, height, and confidence.
4. Startup Steps
The following commands assume the workspace is ~/microros_car_v2_ws and the ROS 2 environment is already configured.
4.1 Start the Chassis, Agent, Camera, and Model
Terminal 1:
xxxxxxxxxxros2 launch microros_v2_bringup car_base.launch.py
4.2 Start the Target Tracker
Run smart_tracker/super_tracker, Terminal 2:
xxxxxxxxxxros2 launch microros_v2_bringup super_tracker.launch.py
Press c to enter the box-selection mode, then select with the mouse:

Then press Enter to start following the coordinate data:

4.3 Start the Follow Controller
Terminal 3:
xxxxxxxxxxros2 launch microros_v2_kcf_follow_pkg tracking_bbox_follow.launch.py After a successful startup, slowly move the object for left/right tracking and forward/back following:

5. Distance-follow Algorithm
The node does not use the color radius to estimate distance; instead it uses the geometric size of the bounding box:
xxxxxxxxxxcurrent_size = sqrt(width * height)size_error = (target_size - current_size) / target_sizeauto_set_target_bbox_size:=true by default. The first valid bounding box received after startup is used as the target distance baseline. You can also specify target_bbox_size_px manually, in which case the node no longer waits for the first bounding box to initialize the baseline.
Distance control uses the PID form, with distance_ki:=0.0 by default, so it is actually PD:
xxxxxxxxxxlinear.x = linear_dir * (distance_kp * size_error + distance_ki * integral + distance_kd * d_error)- When the target box is smaller than the baseline,
size_error > 0, the default is to move forward and approach; - When the target box is larger than the baseline,
size_error < 0, the default is to move backward and move away; - When
abs(size_error) <= distance_tolerance_ratio, forward/back movement stops; linear.xis limited to[-max_linear_x, max_linear_x], with the default maximum absolute value being0.12 m/s.
6. Key Parameters
Common Parameters
| Parameter | Default Value | Description |
|---|---|---|
tracking_bbox_topic | /tracking_bbox | Target box input topic; changing it requires a node restart |
tracking_bbox_msg_type | auto | Auto-discovers the message type; a full ROS type name can also be filled in |
cmd_vel_topic | /cmd_vel | Body velocity output topic; changing it requires a node restart |
ptz_command_topic | /cmd_ptz_angle | PTZ angle output topic; changing it requires a node restart |
joy_state_topic | /JoyState | Gamepad takeover state topic; changing it requires a node restart |
enable_follow | true | Master follow switch; when off, zero velocity is published continuously |
enable_ptz_follow | true | Enable pan-tilt following; No-PTZ must be set to false |
enable_body_turn_follow | true | Enable body horizontal turning |
enable_distance_follow | true | Enable forward/back distance following |
enable_joy_override | true | Pause auto-follow when the gamepad takes over |
image_width / image_height | 640 / 480 | Used when the input message does not provide the image size |
tracking_confidence_threshold | 0.1 | Minimum valid confidence |
target_stale_timeout_sec | 1.2 | Stop when the target box has not been updated for longer than this time |
follow_rate_hz | 10.0 | Control timer rate, minimum 1 Hz |
Pan-Tilt and Body Turning Parameters
| Parameter | Default Value | Description |
|---|---|---|
pixel_tolerance | 15.0 px | PTZ horizontal/tilt pixel deadband |
kp_x / kd_x | 0.6 / 0.15 | PTZ horizontal PD coefficients |
kp_y / kd_y | 0.6 / 0.15 | PTZ tilt PD coefficients |
max_step_xy | 5.0 deg | Maximum pan-tilt angle step per control cycle |
horizontal_min_deg / horizontal_max_deg | -90 / 90 deg | Horizontal angle limits |
pitch_min_deg / pitch_max_deg | -90 / 20 deg | Tilt angle limits |
initial_horizontal_deg | 0.0 deg | Initial horizontal angle, also the body homing reference angle |
initial_pitch_deg | -45.0 deg | Initial tilt angle |
body_kp / body_kd | 0.03 / 0.0 | PTZ-mode body turning PD coefficients |
servo1_engage_deg | 5.0 deg | Body turning starts when the pan-tilt horizontal deviation reaches this value |
body_tolerance_deg | 3.0 deg | Body homing stop deadband |
max_angular_z | 0.6 rad/s | Maximum absolute body angular velocity |
body_ff_gain | 1.0 | In PTZ mode, the feedforward coefficient compensating the pan-tilt horizontal angle from the body angular velocity |
fixed_camera_pixel_tolerance | 15.0 px | No-PTZ body turning stop deadband |
fixed_camera_engage_px | 30.0 px | No-PTZ body turning start threshold |
fixed_camera_body_kp / fixed_camera_body_kd | 0.6 / 0.15 | No-PTZ body turning PD coefficients |
body_dir / fixed_camera_body_dir | -1.0 / -1.0 | Body turning direction correction; change to 1.0 if necessary |
sign_x / sign_y | 1.0 / -1.0 | PTZ horizontal/tilt direction correction |
Distance-follow Parameters
| Parameter | Default Value | Description |
|---|---|---|
target_bbox_size_px | 0.0 | Target baseline size; when 0, set automatically from the first valid box |
auto_set_target_bbox_size | true | Whether to initialize the baseline size from the first valid box |
distance_tolerance_ratio | 0.06 | Relative size deadband, 6% by default |
distance_kp / distance_ki / distance_kd | 0.18 / 0.0 / 0.02 | Distance PID coefficients |
distance_integral_limit | 0.5 | Integral limit |
max_linear_x | 0.12 m/s | Maximum absolute linear velocity |
linear_dir | 1.0 | Forward/back direction correction; change to -1.0 if necessary |