Coursework for the Experimental Robotics Laboratory (ERL) course, MSc in Robotics Engineering, University of Genoa (UniGe), 2024–2025.
Two ROS 2 assignments built around ArUco marker perception: the first focuses on camera-based marker detection and tracking, the second on autonomous exploration driven by a PDDL planner.
- AmirMahdi Matin — 5884715
- Sayna Arghideh — 5934809
| Directory | Package | Topic |
|---|---|---|
| Assignment1/ | erl1_amirmat98 |
ArUco marker detection and tracking with a rotating camera / rotating robot |
| Assignment2/ | erl2_amirmat98 |
PlanSys2 (PDDL) waypoint exploration with SLAM and Nav2 |
Each directory is a self-contained ROS 2 (Foxy) ament_cmake package with its own
detailed README covering the design, logic and build instructions.
A wheeled robot is surrounded by ArUco markers and has to find, order and re-visit all of them, highlighting each one on the camera stream. The same task is solved in two different ways, selected interactively at startup:
r— whole-robot rotation: the chassis spins on/cmd_veluntil every marker is found.c— camera-only rotation: the chassis stays still and only the camera link turns on a dedicated revolute joint (camera_joint), driven through aros2_controlJointGroupVelocityController.
Structure — three classes behind a shared Mover interface:
| Class | Role |
|---|---|
ArucoDetector |
Wraps OpenCV cv::aruco::detectMarkers (dictionary DICT_ARUCO_ORIGINAL), converting ROS images via cv_bridge |
RobotMover |
Rotates the whole chassis; publishes geometry_msgs/Twist on /cmd_vel |
CamMover |
Rotates only the camera joint; synchronises /camera/image_raw with /joint_states (message_filters approximate time) and records the joint angle at which each marker was seen, then servos back to each one in ID order |
Annotated frames are republished on /assignment/detected_markers.
ros2 launch erl1_amirmat98 assignment1.launch.pyA differential-drive mobile robot with an onboard camera and a 2D laser scanner explores a Gazebo world containing four waypoints, each carrying one ArUco marker. The robot visits every waypoint, reads the marker ID there, and once all four are known, navigates to the waypoint holding the smallest marker ID.
Planning — the mission is expressed in PDDL and solved by PlanSys2
(a PDDL-based planning framework for ROS 2; not ROSPlan). The domain
(pddl/domain.pddl) defines the types robot and
waypoint, the predicates at-robby / explored / to_go / min, and three durative
actions:
| Action | Meaning | Implementation |
|---|---|---|
move |
Drive to a waypoint | move_action_node.cpp — Nav2 NavigateToPose client, pose from /amcl_pose |
explore_waypoint |
Inspect a waypoint and read its marker | explore_waypoint_action_node.cpp — ArUco detection, ID reported through action feedback |
move_to_min |
Drive to the smallest-ID waypoint | move_to_min.cpp |
Mission control — mission_controller_node.cpp drives a state machine:
STARTING → EXPLORE_WP → FINISHED_EXPLORING → GO_TO_SMALLEST → FINISHED
It seeds the PlanSys2 problem (robot at unknown, to_go on wp0…wp3), sets the goal
(and (explored wp0) … (explored wp3)), and parses action feedback to build the
waypoint ↔ marker-ID mapping in sorted order. If an action fails — e.g. a waypoint turns
out to be unreachable — it resets at-robby and re-plans on the fly rather than
aborting. Once exploration is complete it swaps in the goal (min wpX) for the waypoint
with the lowest marker ID and executes the second plan.
Navigation stack — slam_toolbox for online mapping and localisation, Nav2 for
path planning and obstacle avoidance around walls and marker boxes.
ros2 launch erl2_amirmat98 assignment2.launch.py # simulation, SLAM, Nav2, PlanSys2
ros2 run erl2_amirmat98 mission_controller_node # in a second terminalBoth assignments include a recorded simulation run. The videos are embedded in the Testing section at the bottom of each assignment's README:
- Assignment1/README.md — the robot rotating and locking onto the surrounding markers
- Assignment2/README.md — the full plan-and-explore mission in Gazebo
Both packages target ROS 2 Foxy on Ubuntu 20.04 and were developed in the
carms84/noetic_ros2 Docker image. Each
one also depends on ros2_aruco, cloned
alongside it in the workspace src/. Per-assignment apt dependencies and build steps
are listed in the respective READMEs.
Released under the MIT License.