diff --git a/robot/src/raspbot_v2/config/controllers.yaml b/robot/src/raspbot_v2/config/controllers.yaml
new file mode 100644
index 0000000..e78d744
--- /dev/null
+++ b/robot/src/raspbot_v2/config/controllers.yaml
@@ -0,0 +1,38 @@
+controller_manager:
+ ros__parameters:
+ update_rate: 50 # Hz — must be >= the fastest controller's publish rate
+
+ joint_state_broadcaster:
+ type: joint_state_broadcaster/JointStateBroadcaster
+
+ pan_tilt_controller:
+ type: joint_trajectory_controller/JointTrajectoryController
+
+# ─── pan_tilt_controller ─────────────────────────────────────────────────────
+# Accepts goals on:
+# /pan_tilt_controller/follow_joint_trajectory (action, JointTrajectory)
+#
+# allow_partial_joints_goal: true lets you command only pan or only tilt,
+# matching the behaviour of the real camera_orientation_node which handles
+# the joints independently.
+pan_tilt_controller:
+ ros__parameters:
+ joints:
+ - pan
+ - tilt
+ command_interfaces:
+ - position
+ state_interfaces:
+ - position
+ - velocity
+ allow_partial_joints_goal: true
+ open_loop_control: false
+ goal_time: 5.0 # seconds — trajectory must complete within this window
+ stopped_velocity_tolerance: 0.01 # rad/s
+ constraints:
+ goal_time: 0.5 # seconds — tolerance after goal_time expires
+ stopped_velocity_tolerance: 0.01
+ pan:
+ goal: 0.05 # rad — acceptable position error at goal
+ tilt:
+ goal: 0.05 # rad
diff --git a/robot/src/raspbot_v2/launch/robot.launch.py b/robot/src/raspbot_v2/launch/robot.launch.py
index a54f189..2ee0801 100644
--- a/robot/src/raspbot_v2/launch/robot.launch.py
+++ b/robot/src/raspbot_v2/launch/robot.launch.py
@@ -12,10 +12,15 @@ def generate_launch_description():
urdf_file = os.path.join(
get_package_share_directory('raspbot_v2'), 'urdf', 'raspbot_v2.urdf.xacro'
)
+ controllers_config = os.path.join(
+ get_package_share_directory('raspbot_v2'), 'config', 'controllers.yaml'
+ )
+
robot_description = ParameterValue(
Command([
'xacro ', urdf_file,
' wheel_separation:=', LaunchConfiguration('wheel_base'),
+ ' controllers_config:=', controllers_config,
]),
value_type=str,
)
diff --git a/robot/src/raspbot_v2/setup.py b/robot/src/raspbot_v2/setup.py
index 61221cf..0db3946 100644
--- a/robot/src/raspbot_v2/setup.py
+++ b/robot/src/raspbot_v2/setup.py
@@ -13,6 +13,7 @@ setup(
('share/' + package_name, ['package.xml']),
('share/' + package_name + '/launch', ['launch/robot.launch.py']),
('share/' + package_name + '/urdf', glob.glob('urdf/*.xacro')),
+ ('share/' + package_name + '/config', glob.glob('config/*.yaml')),
],
install_requires=['setuptools'],
zip_safe=True,
diff --git a/robot/src/raspbot_v2/urdf/raspbot_v2.ros2_control.xacro b/robot/src/raspbot_v2/urdf/raspbot_v2.ros2_control.xacro
new file mode 100644
index 0000000..3db0a29
--- /dev/null
+++ b/robot/src/raspbot_v2/urdf/raspbot_v2.ros2_control.xacro
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+ robot_description
+ robot_state_publisher
+
+
+ ${controllers_config}
+
+
+
+
+
diff --git a/robot/src/raspbot_v2/urdf/raspbot_v2.urdf.xacro b/robot/src/raspbot_v2/urdf/raspbot_v2.urdf.xacro
index 8d3e511..69bb155 100644
--- a/robot/src/raspbot_v2/urdf/raspbot_v2.urdf.xacro
+++ b/robot/src/raspbot_v2/urdf/raspbot_v2.urdf.xacro
@@ -53,6 +53,11 @@
+
+
+
+
@@ -86,6 +91,8 @@
+
+
@@ -95,5 +102,6 @@
+
diff --git a/robot/src/raspbot_v2/urdf/robot_base.xacro b/robot/src/raspbot_v2/urdf/robot_base.xacro
index 2022983..12ee135 100644
--- a/robot/src/raspbot_v2/urdf/robot_base.xacro
+++ b/robot/src/raspbot_v2/urdf/robot_base.xacro
@@ -110,12 +110,15 @@
-
wheel_front_left_joint
wheel_rear_left_joint
wheel_front_right_joint
@@ -123,11 +126,30 @@
${wheel_separation}
${wheel_radius}
10
- cmd_vel
- odom
+ /cmd_vel
+ /odom
+ /tf
odom
base_footprint
+
+
+
+ /gz/joint_states
+ wheel_front_left_joint
+ wheel_front_right_joint
+ wheel_rear_left_joint
+ wheel_rear_right_joint
+
+
+
diff --git a/robot/src/raspbot_v2/urdf/sonar.xacro b/robot/src/raspbot_v2/urdf/sonar.xacro
index b6fd96e..092c56f 100644
--- a/robot/src/raspbot_v2/urdf/sonar.xacro
+++ b/robot/src/raspbot_v2/urdf/sonar.xacro
@@ -34,24 +34,47 @@
-
+
1
10
true
- /ultrasonic/range
+ /ultrasonic/scan
ultrasonic
-
-
- ${sonar_min_range}
- ${sonar_max_range}
-
- 0.13
-
+
+
+
+ 5
+ 1
+ -0.1309
+ 0.1309
+
+
+ 5
+ -0.1309
+ 0.1309
+
+
+
+ ${sonar_min_range}
+ ${sonar_max_range}
+ 0.01
+
+
+ gaussian
+ 0.0
+ 0.005
+
+