Spaces:
Starting
on
T4
Starting
on
T4
import numpy as np | |
from scipy.spatial.transform import Rotation as SCR | |
import math | |
from scene.cameras import Camera | |
from sim.ilqr.lqr import plan2control | |
from omegaconf import OmegaConf | |
def rt2pose(r, t, degrees=False): | |
pose = np.eye(4) | |
pose[:3, :3] = SCR.from_euler('XYZ', r, degrees=degrees).as_matrix() | |
pose[:3, 3] = t | |
return pose | |
def pose2rt(pose, degrees=False): | |
r = SCR.from_matrix(pose[:3, :3]).as_euler('XYZ', degrees=degrees) | |
t = pose[:3, 3] | |
return r, t | |
def load_camera_cfg(cfg): | |
cam_params = {} | |
cams = OmegaConf.to_container(cfg.cams, resolve=True) | |
for cam_name, cam in cams.items(): | |
v2c = rt2pose(cam['extrinsics']['v2c_rot'], cam['extrinsics']['v2c_trans'], degrees=True) | |
l2c = rt2pose(cam['extrinsics']['l2c_rot'], cam['extrinsics']['l2c_trans'], degrees=True) | |
cam_intrin = cam['intrinsics'] | |
cam_intrin['fovx'] = cam_intrin['fovx'] / 180.0 * np.pi | |
cam_intrin['fovy'] = cam_intrin['fovy'] / 180.0 * np.pi | |
cam_params[cam_name] = {'intrinsic': cam_intrin, 'v2c': v2c, 'l2c': l2c} | |
rect_mat = np.eye(4) | |
if 'cam_rect' in cfg: | |
rect_mat[:3, :3] = SCR.from_euler('XYZ', cfg.cam_rect.rot, degrees=True).as_matrix() | |
rect_mat[:3, 3] = np.array(cfg.cam_rect.trans) | |
return cam_params, OmegaConf.to_container(cfg.cam_align, resolve=True), rect_mat | |
def fov2focal(fov, pixels): | |
return pixels / (2 * math.tan(fov / 2)) | |
def focal2fov(focal, pixels): | |
return 2*math.atan(pixels/(2*focal)) | |
def create_cam(intrinsic, c2w): | |
fovx, fovy = intrinsic['fovx'], intrinsic['fovy'] | |
h, w = intrinsic['H'], intrinsic['W'] | |
K = np.eye(4) | |
K[0, 0], K[1, 1] = fov2focal(fovx, w), fov2focal(fovy, h) | |
K[0, 2], K[1, 2] = intrinsic['cx'], intrinsic['cy'] | |
cam = Camera(K=K, c2w=c2w, width=w, height=h, | |
image=np.zeros((h, w, 3)), image_name='', dynamics={}) | |
return cam | |
def traj2control(plan_traj, info): | |
""" | |
The input plan trajectory is under lidar coordinates | |
x to right, y to forward and z to upward | |
""" | |
plan_traj_stats = np.zeros((plan_traj.shape[0]+1, 5)) | |
plan_traj_stats[1:, :2] = plan_traj[:, [1,0]] | |
prev_a, prev_b = 0, 0 | |
for i, (a, b) in enumerate(plan_traj): | |
rot = np.arctan((b - prev_b)/(a - prev_a)) | |
plan_traj_stats[i+1, 2] = rot | |
curr_stat = np.array( | |
[0, 0, 0, info['ego_velo'], info['ego_steer']] | |
) | |
acc, steer_rate = plan2control(plan_traj_stats, curr_stat) | |
return acc, steer_rate | |
def dense_cam_poses(cam_poses, cmds): | |
for i in range(5): | |
dense_poses = [] | |
dense_cmds = [] | |
for i in range(cam_poses.shape[0]-1): | |
cam1 = cam_poses[i] | |
cam2 = cam_poses[i+1] | |
dense_poses.append(cam1) | |
dense_cmds.append(cmds[i]) | |
if np.linalg.norm(cam1[:3, 3]-cam2[:3, 3]) > 0.1: | |
euler1 = SCR.from_matrix(cam1[:3, :3]).as_euler("XYZ") | |
euler2 = SCR.from_matrix(cam2[:3, :3]).as_euler("XYZ") | |
interp_euler = (euler1 + euler2) / 2 | |
interp_trans = (cam1[:3, 3] + cam2[:3, 3]) / 2 | |
interp_pose = np.eye(4) | |
interp_pose[:3, :3] = SCR.from_euler("XYZ", interp_euler).as_matrix() | |
interp_pose[:3, 3] = interp_trans | |
dense_poses.append(interp_pose) | |
dense_cmds.append(cmds[i]) | |
dense_poses.append(cam_poses[-1]) | |
dense_poses = np.stack(dense_poses) | |
cam_poses = dense_poses | |
cmds = dense_cmds | |
return cam_poses, cmds | |
def traj_transform_to_global(traj, ego_box): | |
""" | |
Transform trajectory from ego-centeric frame to global frame | |
""" | |
ego_x, ego_y, _, _, _, _, ego_yaw = ego_box | |
global_points = [ | |
( | |
ego_x | |
+ px * math.cos(ego_yaw) | |
- py * math.sin(ego_yaw), | |
ego_y | |
+ px * math.sin(ego_yaw) | |
+ py * math.cos(ego_yaw), | |
) | |
for px, py in traj | |
] | |
global_trajs = [] | |
for i in range(1, len(global_points)): | |
x1, y1 = global_points[i - 1] | |
x2, y2 = global_points[i] | |
dx, dy = x2 - x1, y2 - y1 | |
# distance = math.sqrt(dx**2 + dy**2) | |
yaw = math.atan2(dy, dx) | |
global_trajs.append((x1, y1, yaw)) | |
return global_trajs | |