I built a classical robotics pipeline from scratch on a real 7-DoF arm. HSV perception, Jacobian IK, and RRTConnect motion planning work together to pick and place objects on their own.
I wanted to build a pick and place system on a real 7-DoF Franka Panda arm using only classical robotics tools. I used no end to end learning and no pretrained policies. It is just perception, planning, and control working together.
The pipeline has three stages, and I kept them separate on purpose. Perception finds the object. Planning computes a collision free path to it. The IK controller runs that path on the real joints. I can replace any stage without touching the others.
My main design choice was to keep planning separate from execution. When something breaks, I know exactly which stage to look at. On real hardware that matters a lot.
I chose HSV segmentation on purpose. It is simple and clear, and I can see every failure mode. I can look at the mask directly and know what went wrong. For this task it is the right tool.
The centroid computation uses image moments, which gives sub pixel accuracy. The depth reading at that pixel plus the camera intrinsics gives a 3D point in the camera frame. ROS 2 TF handles the rest.
The Franka Panda has 7 joints, so the configuration space is 7-dimensional. RRTConnect builds two trees at the same time, one from the current joint configuration and one from the goal. They grow toward each other with random samples until they meet.
The two way approach converges much faster than a single tree on high-DoF arms, which matters when the robot is waiting to execute. I then time parameterise the resulting path for smooth velocity profiles before it goes to the IK controller.
Forward kinematics gives you the end-effector pose from the joint angles. IK does the reverse. For a 7-DoF arm the problem is redundant. There are infinitely many joint configurations that reach the same pose, so I use the damped pseudoinverse Jacobian to find the minimum norm solution.
The damping factor λ keeps the solution stable near singularities, where the plain pseudoinverse would blow up. Pinocchio gives me the analytical Jacobian at each configuration, so the loop runs fast enough for real time control.
After the classical pipeline was working, I also trained a PPO policy in MuJoCo to see how a learned approach did on the same task. The classical system is easier to read and easier to debug on hardware. Once trained, the RL policy handles object position changes better. Both are useful. I just found the planning work more interesting to build.