error: Failed to run uv compile × No solution found when resolving dependencies:
╰─▶ Because rvc3-python was not found in the package registry and you
require rvc3-python, we can conclude that your requirements are
unsatisfiable.
hint: An index URL (https://download.pytorch.org/whl/gpu) could not
be queried due to a lack of valid authentication credentials (403
Forbidden).
. uv exited with status: exit status: 1
import numpy as npimport matplotlib.pyplot as pltfrom spatialmath import SE3from spatialmath.base import rotz, trotyfrom roboticstoolbox import CentralCameranp.random.seed(42)
---------------------------------------------------------------------------ModuleNotFoundError Traceback (most recent call last)
CellIn[2], line 3 1importnumpyasnp 2importmatplotlib.pyplotasplt----> 3fromspatialmathimport SE3
4fromspatialmath.baseimport rotz, troty
5fromroboticstoolboximport CentralCamera
ModuleNotFoundError: No module named 'spatialmath'
Simulate trajectory, IMU, and landmarks with noise
# Camera intrinsicscam = CentralCamera(f=0.08, rho=1e-5, pp=[320, 240], name='SimCam')# Landmarksn_landmarks =50landmarks = np.random.uniform([-1, -1, 3], [1, 1, 5], (n_landmarks, 3)).T# Trajectoryn_steps =100dt =0.1trajectory = []imus = []for t inrange(n_steps): x =0.5* np.sin(t *0.1) y =0.5* np.cos(t *0.1) z =0.2* np.sin(t *0.05) +3.5 R = rotz(t *0.01) @ troty(0.1) T = SE3.Rt(R, [x, y, z]) trajectory.append(T)if t >0: dp = (T.t - trajectory[t-1].t) / dt omega = np.random.normal(0, 0.01, 3) acc = dp + np.random.normal(0, 0.01, 3) imus.append((acc, omega))else: imus.append((np.zeros(3), np.zeros(3)))
Project 3D landmarks to 2D with noise
measurements = []for T in trajectory: uv = cam.project(landmarks, T) uv += np.random.normal(0, 1.0, uv.shape) measurements.append(uv)
Simple EKF: Prediction + Visual Update
ekf_positions = []state = np.array([0.0, 0.0, 3.5])vel = np.zeros(3)P = np.eye(3) *0.1R_meas = np.eye(2) *1.0for t inrange(n_steps): acc, _ = imus[t] vel += acc * dt state += vel * dt P += np.eye(3) *0.01# Visual update with one landmark landmark = landmarks[:, 0] pred_uv = cam.project(landmark.reshape(3, 1), SE3.Tt(np.eye(3), state))[:, 0] meas_uv = measurements[t][:, 0] residual = meas_uv - pred_uv# Jacobian H (finite difference) eps =1e-5 H = np.zeros((2, 3))for i inrange(3): delta = np.zeros(3) delta[i] = eps pred_uv_perturbed = cam.project(landmark.reshape(3, 1), SE3.Tt(np.eye(3), state + delta))[:, 0] H[:, i] = (pred_uv_perturbed - pred_uv) / eps S = H @ P @ H.T + R_meas K = P @ H.T @ np.linalg.inv(S) state = state + K @ residual P = (np.eye(3) - K @ H) @ P ekf_positions.append(state.copy())
Plot Ground Truth vs EKF Trajectory
fig = plt.figure(figsize=(10, 6))ax = fig.add_subplot(111, projection='3d')traj_xyz = np.array([T.t for T in trajectory]).Tekf_xyz = np.array(ekf_positions).Tax.plot(*traj_xyz, label='Ground Truth Trajectory')ax.plot(*ekf_xyz, label='EKF Estimated Trajectory')ax.scatter(*landmarks, color='red', s=10, alpha=0.5, label='Landmarks')ax.set_title('VIO with Visual Update and Noise')ax.set_xlabel('X')ax.set_ylabel('Y')ax.set_zlabel('Z')ax.legend()plt.show()