Frame 06CourseworkRoboticsUMD 2023 to 2025
Finding a path is not the same as proving it is the shortest
Planning, perception and manipulation coursework from the M.Eng in Robotics at the University of Maryland, with the planners running live on a map you can draw on. Group projects are labelled as such, and commit dates here are upload dates, not authoring dates.
Planning
Three course planners on one canvas. Draw obstacles, drag the start and goal, watch the counters.
Last push Jan 2025
Group project, ENPM661 Group 43
Fast-RRT: two small rules, measured by us rather than by the paper
Group project with Vijay Chevireddi and Abraruddin Syed for ENPM661. We implemented the initial-path half of Fast-RRT (Wu et al. 2021) in Python and OpenCV on a 1400 by 600 map. fast_sample discards any random sample within one step of an existing node, so growth goes into unexplored space; random_steer retries at a random angle when the straight steer hits an obstacle, which is what gets the tree through narrow gaps.
Our report times plain RRT against Fast-RRT on two maps: 0.36 s against 0.12 s on map 1 at step 30, 29.15 s against 5.02 s on map 2 at step 10, so about 3x and 5.8x. The README repeats the paper's "up to 20x"; that is the paper's number, not ours. The paper's second half, the path fusion that earns the word "optimal" in the repo title, is not implemented: the path returned is the first feasible one.
The lesson I keep: the tree was drawn onto the same pixel buffer that is_valid reads for collisions, so drawn edges later counted as obstacles and the visualization silently became part of the planner. Collision checks are endpoint-only, and nearest-neighbour search is a linear scan, which is why step 10 takes tens of seconds.
Last push Jan 2025
Sole author
Bidirectional A*: meeting in the middle is intuitive, and it is not optimal
Two priority queues, one growing from the start and one from the goal, on a 1200 by 600 map with three circular obstacles. Euclidean distance is both the step cost and the heuristic, moves are eight-connected, and the search stops the moment a node popped from one queue is already known to the other side.
That stop rule is the one everybody writes first, and it does not guarantee the shortest path: the frontiers can first touch along a route longer than one still sitting in the queues. The sound stop keeps expanding until the best f-value on either side cannot beat the best joined path found so far. The README says "the shortest path is reconstructed"; the code does not earn that sentence. The toggle in the bench above exists so you can watch the two rules disagree.
Also missing: a bounds check in is_valid_point and a closed set, so nodes can be expanded more than once. Obstacle geometry is hard-coded twice, once for collision and once for drawing.
Last push Jan 2025
Sole author
Dijkstra with a clearance halo: the map the planner actually reasons about
Textbook Dijkstra on a 1200 by 500 map of rectangles and a hexagon: a heap, eight moves at cost 1.0 orthogonal and 1.4 diagonal, a closed set, parent pointers for the trace back. No heuristic, so it floods nearly the whole free map before reaching the goal; the bench's Dijkstra mode shows this next to A*.
The part worth keeping: the map has two obstacle layers, the strict geometry and the same geometry inflated by 5 px of clearance, painted in two colours, and the planner only ever sees the inflated one. That is what a costmap does for a robot with a footprint, and drawing both layers makes the safety margin visible instead of implied.
One notebook cell, no tests. The README tells you to run a .py file that is not in the repo.
Perception
Two have their own pages, printed below; the third is one notebook.
-
TurtleBot3 perception stack
ROS 2 node: RANSAC horizon, optical-flow and YOLO halts zero the Twist before a homography lane follower steers; ran in Gazebo and on a real TurtleBot3. Case study -
0.966 mask mAP on 133 held-out images
Pallet detection and ground segmentation on ROS 2
Two YOLO11 models, one trained from binary masks, wrapped as ROS 2 Humble nodes; 0.966 mask mAP on 133 held-out images, QoS matched to the rosbag. Read more
Last push Mar 2024
Sole author
Panorama by hand: DLT plus RANSAC instead of findHomography
A classic-CV notebook that stitches four photos with SIFT keypoints, a 0.75 Lowe ratio test, and a homography estimated from first principles: the 8 by 9 DLT system for four random matches solved by SVD, inside a RANSAC loop of 1000 iterations with a 5 px inlier threshold.
The committed notebook does not run as-is: two cells call functions under names that no longer exist, and the saved outputs predate the code. The repo name misspells panorama.
Manipulation
Two ways to move the same arm: learn a policy, or hand the planning to MoveIt and write almost nothing.
Last push Apr 2025
Group project, four authors
SAC on a Panda in robosuite: the wiring, not the results
Group course project, four authors. One script wires robosuite's Panda environment (MuJoCo underneath) through a Gym wrapper into a Stable Baselines3 Soft Actor-Critic agent, with a CLI to resume from the latest checkpoint, start fresh, or evaluate. As committed: 1.5M timesteps, an 8M replay buffer, batch size 49,152, [1024, 1024, 512] actor and critic MLPs, 180 Hz control, a checkpoint every 5,000 steps.
The committed script trains robosuite's Lift task, not the pick-and-place the repo title names. The README says batch size 1024; the code says 49,152. The repo holds no success rate, no reward numbers and no trained model, so no result is claimed here.
Last push Jan 2025
Sole author
MoveIt 2 pick-and-place: seven steps and one missing check
A Setup Assistant config for the Panda with four named SRDF states (open_gripper, closed_gripper, home_hand, home_arm), and a C++ node with one MoveGroupInterface for the arm and one for the hand that runs a fixed sequence, one second apart:
- open the gripper
- plan and execute to the pick pose
- close the gripper
- plan and execute to the place pose
- open the gripper
- return to home_arm
- close the gripper
Every trajectory comes from move_group; the application code is a list of targets, which is the point of MoveIt and also its trap.
The node ignores what plan() and execute() return. A plan that fails executes an empty trajectory and the sequence carries on as if the arm had moved. That is the quiet failure this page keeps coming back to.
- All of this is coursework from the M.Eng. None of it is deployed, and no repo here has tests or CI.
- Most of these repos were uploaded through the GitHub web UI months after the work, so commit dates are upload dates. Authoring terms are given where a report, a dated screenshot or a first commit pins them, otherwise marked unknown.
- Fast-RRT and the SAC project are group projects. The repos do not record which lines I wrote.
- The planning bench runs in your browser on illustrative maps. The timings on this page come from the group report, not from the bench.
Sources Fast-RRT Group 43 report Bi-direction-A- Dijkstra TurtleBot Pallet detection Edge detection and panorama SAC Panda SAC report MoveIt Panda Scope: coursework, sole and group Verified 3 Sep 2026