Source code for concepts.simulator.sapien2.controllers.base_cartesian_line_controller
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# File : base_cartesian_line_controller.py
# Author : Jiayuan Mao
# Email : maojiayuan@gmail.com
# Date : 07/29/2024
#
# This file is part of Project Concepts.
# Distributed under terms of the MIT license.
"""Control the base of an object following a straight line in the Cartesian space. The object will maintain its orientation during the movement."""
import numpy as np
from sapien.core import Actor
from concepts.math.rotationlib_wxyz import quat_diff_in_axis_angle
[docs]
class BaseCartesianLineProportionalController(object):
[docs]
def __init__(
self,
actor: Actor,
initial_position: np.ndarray,
target_position: np.ndarray,
num_steps: int,
gain: float,
):
self.actor = actor
self.initial_position = initial_position
self.target_position = target_position
self.num_steps = num_steps
self.gain = gain
self.velocity_by_step = (self.target_position - self.initial_position) / self.num_steps
self.target_quat_wxyz = actor.get_pose().q
[docs]
def get_projection_t(self, position: np.ndarray) -> float:
return np.dot((position - self.initial_position), self.velocity_by_step) / np.sum(self.velocity_by_step**2)
[docs]
def get_desired_velocity(self) -> np.ndarray:
position = self.actor.get_pose().p
t = self.get_projection_t(position)
target_t = np.maximum(0, np.minimum(t + 1, self.num_steps))
current_target_position = self.initial_position + target_t * self.velocity_by_step
velocity = self.gain * (current_target_position - position)
return velocity
[docs]
def get_desired_angular_velocity(self) -> np.ndarray:
current_quat_wxyz = self.actor.get_pose().q
return self.gain * quat_diff_in_axis_angle(self.target_quat_wxyz, current_quat_wxyz)
[docs]
def set_velocities(self):
self.actor.set_velocity(self.get_desired_velocity())
self.actor.set_angular_velocity(self.get_desired_angular_velocity())
[docs]
def get_current_t(self) -> float:
return self.get_projection_t(self.actor.get_pose().p)