| name | robotics |
| description | Robotics fundamentals including kinematics, dynamics, motion planning, perception, control, and human-robot interaction |
| license | MIT |
| compatibility | opencode |
| metadata | {"audience":"engineers","category":"engineering"} |
What I do
- Model robot kinematics and dynamics
- Design motion planning algorithms
- Implement perception and computer vision systems
- Develop robot control systems
- Design end-effectors and grippers
- Integrate sensors and actuators
- Plan human-robot interaction interfaces
- Simulate and test robotic systems
When to use me
When designing robotic systems, implementing kinematics, developing motion planning algorithms, or integrating perception systems for automation.
Core Concepts
- Forward and inverse kinematics
- Robot dynamics (Lagrangian, Newton-Euler)
- Trajectory planning and path optimization
- Sensor integration (LiDAR, cameras, IMUs)
- Computer vision for robotics
- Motion control (PID, MPC, adaptive control)
- Force/torque control and impedance control
- Grip design and grasping
- ROS/ROS2 development
- Swarm robotics and multi-agent systems
Code Examples
Forward Kinematics
import numpy as np
from dataclasses import dataclass
from typing import List, Tuple
import math
@dataclass
class DHParameter:
a: float
alpha: float
d: float
theta: float
def transformation_matrix(
a: float,
alpha: float,
d: float,
theta: float
) -> np.ndarray:
"""Create DH transformation matrix."""
c = math.cos(theta)
s = math.sin(theta)
ca = math.cos(alpha)
sa = math.sin(alpha)
return np.array([
[c, -s * ca, s * sa, a * c],
[s, c * ca, -c * sa, a * s],
[0, sa, ca, d],
[0, 0, 0, 1]
])
def forward_kinematics(
dh_params: List[DHParameter]
) -> np.ndarray:
"""Calculate forward kinematics for robot arm."""
T = np.eye(4)
for params in dh_params:
T = T @ transformation_matrix(
params.a, params.alpha, params.d, params.theta
)
return T
dh_3dof = [
DHParameter(a=0.5, alpha=, d=, theta=),
DHParameter(a=, alpha=, d=, theta=),
DHParameter(a=, alpha=, d=, theta=-)
]
T_ee = forward_kinematics(dh_3dof)
()
Inverse Kinematics
def planar_ik(
x: float,
y: float,
L1: float,
L2: float
) -> Tuple[float, float, float, float]:
"""Analytical inverse kinematics for 2-link planar arm."""
D = (x**2 + y**2 - L1**2 - L2**2) / (2 * L1 * L2)
if abs(D) > 1:
return None
theta2 = math.atan2(math.sqrt(1 - D**2), D)
theta1 = math.atan2(y, x) - math.atan2(
L2 * math.sin(theta2), L1 + L2 * math.cos(theta2)
)
return theta1, theta2, -theta2, theta1
def jacobian_ik(
target_pose: np.ndarray,
current_joints: np.ndarray,
T_base: np.ndarray,
link_lengths: List[float],
iterations: int = 100,
alpha: float = 0.1
) -> np.ndarray:
"""Iterative inverse kinematics using Jacobian."""
joints = current_joints.copy()
for _ in range(iterations):
T_current = forward_kinematics([
DHParameter(a=link_lengths[i], alpha=0, d=0, theta=joints[i])
for i in range(len(joints))
])
error = np.zeros(6)
error[:] = target_pose[:, ] - T_current[:, ]
np.linalg.norm(error) < :
J = numerical_jacobian(joints, link_lengths)
:
joints += alpha * np.linalg.lstsq(J, error, rcond=)[]
:
joints
solution = planar_ik(, , , )
solution:
()
()
Trajectory Planning
def cubic_polynomial(
t: float,
t0: float,
tf: float,
p0: float,
pf: float,
v0: float = 0,
vf: float = 0
) -> Tuple[float, float]:
"""Generate cubic polynomial trajectory."""
T = tf - t0
a0 = p0
a1 = v0
a2 = 3 * (pf - p0) / T**2 - 2 * v0 / T - vf / T
a3 = -2 * (pf - p0) / T**3 + (v0 + vf) / T**2
if t < t0:
tau = 0
elif t > tf:
tau = T
else:
tau = t - t0
p = a0 + a1 * tau + a2 * tau**2 + a3 * tau**3
v = a1 + 2 * a2 * tau + 3 * a3 * tau**2
return p, v
def quintic_polynomial(
t: float,
t0: float, tf: float,
p0: float, pf: float,
v0: float = 0, vf: float = 0,
a0: float = 0, af: float = 0
) -> Tuple[float, float, ]:
T = tf - t0
a0 = p0
a1 = v0
a2 = a0 /
a3 = ( * (pf - p0) - ( * vf + * v0) - ( * af - a0) * T) / ( * T**)
a4 = ( * (p0 - pf) + ( * vf + * v0) + (af - * a0) * T) / ( * T**)
a5 = ( * (pf - p0) - * (vf + v0) - (af - a0) * T) / ( * T**)
t < t0:
p0, v0, a0
t > tf:
pf, vf, af
tau = t - t0
p = a0 + a1 * tau + a2 * tau** + a3 * tau** + a4 * tau** + a5 * tau**
v = a1 + * a2 * tau + * a3 * tau** + * a4 * tau** + * a5 * tau**
a = * a2 + * a3 * tau + * a4 * tau** + * a5 * tau**
p, v, a
() -> [[, ]]:
scipy.spatial.distance cdist
nodes = [start]
parents = []
costs = []
_ (max_iter):
np.random.random() < :
rand = goal
:
rand = (np.random.uniform(bounds[], bounds[]),
np.random.uniform(bounds[], bounds[]))
nearest_idx = (((nodes)),
key= i: np.linalg.norm(
np.array(nodes[i]) - np.array(rand)))
direction = np.array(rand) - np.array(nodes[nearest_idx])
dist = np.linalg.norm(direction)
dist > step_size:
direction = direction / dist * step_size
new_node = (np.array(nodes[nearest_idx]) + direction)
collision_check(new_node, obstacles):
near_idx = [i i ((nodes))
np.linalg.norm(np.array(nodes[i]) - np.array(new_node)) < step_size * ]
best_idx = nearest_idx
best_cost = costs[nearest_idx] + step_size
idx near_idx:
cost = costs[idx] + np.linalg.norm(
np.array(nodes[idx]) - np.array(new_node))
cost < best_cost:
best_cost = cost
best_idx = idx
nodes.append(new_node)
parents.append(best_idx)
costs.append(best_cost)
idx near_idx:
idx == best_idx:
new_cost = costs[best_idx] + np.linalg.norm(
np.array(new_node) - np.array(nodes[idx]))
new_cost < costs[idx]:
costs[idx] = new_cost
parents[idx] = best_idx
path = [goal]
current = goal
current != start:
idx = nodes.index(current)
current = nodes[parents[idx]]
path.append(current)
path.reverse()
path
trajectory = []
t np.linspace(, , ):
p, v = cubic_polynomial(t, , , , )
trajectory.append((p, v))
()
Computer Vision for Robotics
def camera_calibration(
image_points: np.ndarray,
object_points: np.ndarray
) -> Tuple[np.ndarray, np.ndarray]:
"""Perform camera calibration using Zhang's method."""
return cv.calibrateCamera(object_points, image_points, (640, 480))
def aruco_detection(
image: np.ndarray,
marker_dict: cv.aruco.Dictionary_get(cv.aruco.DICT_6X6_250)
) -> List[dict]:
"""Detect ArUco markers for robot localization."""
corners, ids, rejected = cv.aruco.detectMarkers(
image, marker_dict)
return [{"id": i[0] if i is not None else None,
"corners": c} for i, c in zip(ids, corners)]
def depth_from_stereo(
disparity: np.ndarray,
focal_length: float,
baseline: float
) -> np.ndarray:
"""Calculate depth from stereo disparity."""
depth = focal_length * baseline / (disparity + 1e-6)
depth[depth < 0] = 0
return depth
def point_cloud_from_depth(
depth: np.ndarray,
fx: float,
fy: float,
cx: float,
cy: float
) -> np.ndarray:
x, y = np.meshgrid(np.arange(depth.shape[]), np.arange(depth.shape[]))
X = (x - cx) * depth / fx
Y = (y - cy) * depth / fy
Z = depth
np.stack([X, Y, Z], axis=-)
Robot Control
def jacobian_derivative(
q: np.ndarray,
dq: np.ndarray,
link_lengths: List[float]
) -> np.ndarray:
"""Calculate time derivative of Jacobian."""
n = len(q)
J = np.zeros((6, n))
for i in range(n):
J[0, i] = -sum(link_lengths[k] * math.sin(sum(q[:k+1]))
for k in range(i, n)) if i < n - 1 else 0
J[1, i] = sum(link_lengths[k] * math.cos(sum(q[:k+1]))
for k in range(i, n)) if i < n - 1 else link_lengths[-1]
return J
def computed_torque_control(
q_des: np.ndarray,
dq_des: np.ndarray,
ddq_des: np.ndarray,
q: np.ndarray,
dq: np.ndarray,
M: np.ndarray,
C: np.ndarray,
G: np.ndarray,
Kp: np.ndarray,
Kd: np.ndarray
) -> np.ndarray:
"""Computed torque control with PD feedback."""
e = q_des - q
de = dq_des - dq
tau_feedforward = M @ ddq_des + C @ dq_des + G
tau_feedback = Kp @ e + Kd @ de
return tau_feedforward + tau_feedback
def impedance_control(
x: np.ndarray,
dx: np.ndarray,
xd: np.ndarray,
dxd: np.ndarray,
M_d: np.ndarray,
B_d: np.ndarray,
K_d: np.ndarray,
F_ext: np.ndarray
) -> np.ndarray:
e = x - xd
de = dx - dxd
F_desired = M_d @ (-ddx_des np.zeros()) + B_d @ de + K_d @ e
F_desired + F_ext
Kp = * np.eye()
Kd = * np.eye()
q_des = np.array([, , -, , , ])
dq_des = np.zeros()
ddq_des = np.zeros()
q_current = np.array([, , -, , , ])
dq_current = np.array([, , -, , , ])
Best Practices
- Use simulation (Gazebo, Webots) before hardware deployment
- Implement safety stops and limit switches in hardware
- Consider workspace constraints and singularities in motion planning
- Use proper coordinate frames (world, base, tool, camera)
- Account for calibration errors and thermal drift
- Implement smooth trajectory generation with velocity/acceleration limits
- Use redundancy resolution for obstacle avoidance
- Consider sensor fusion for improved state estimation
- Implement graceful degradation for sensor failures
- Document robot configuration and calibration parameters