nova-sim / robots /spot /controllers /pd_standing.py
gpue's picture
Initial commit: Nova Sim unified robot simulation platform
ef118cf
"""PD Standing Controller for Spot robot."""
import numpy as np
import os
import importlib.util
# Import BaseController using importlib to work when loaded via importlib
_controllers_dir = os.path.dirname(os.path.abspath(__file__))
_base_path = os.path.join(_controllers_dir, "base.py")
_spec = importlib.util.spec_from_file_location("spot_base", _base_path)
_base_module = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(_base_module)
BaseController = _base_module.BaseController
class PDStandingController(BaseController):
"""Simple PD controller to hold standing pose for Spot."""
# Standing pose from the model's keyframe
# hx=0, hy=1.04, kn=-1.8 for all legs
STANDING_POSE = np.array([
0.0, 1.04, -1.8, # FL: hx, hy, kn
0.0, 1.04, -1.8, # FR
0.0, 1.04, -1.8, # HL
0.0, 1.04, -1.8, # HR
], dtype=np.float32)
def __init__(self, num_joints: int = 12):
super().__init__(num_joints)
self.target_pose = self.STANDING_POSE.copy()
# Velocity command (for compatibility with G1 interface)
self.cmd = np.array([0.0, 0.0, 0.0], dtype=np.float32)
def set_command(self, vx: float = 0.0, vy: float = 0.0, vyaw: float = 0.0):
"""Set velocity command (used for gait controller, ignored here)."""
self.cmd[0] = np.clip(vx, -1.0, 1.0)
self.cmd[1] = np.clip(vy, -0.5, 0.5)
self.cmd[2] = np.clip(vyaw, -1.5, 1.5)
def get_command(self):
"""Get current velocity command."""
return self.cmd.copy()
def compute_action(self, obs: np.ndarray, data) -> np.ndarray:
"""Compute target joint positions for position actuators.
Since Spot uses position actuators with built-in PD control,
we just return the target positions.
"""
# The model's position actuators handle PD control internally
# We just need to return target positions
return self.target_pose.copy()
def reset(self):
super().reset()
self.target_pose = self.STANDING_POSE.copy()
self.cmd = np.array([0.0, 0.0, 0.0], dtype=np.float32)
@property
def name(self) -> str:
return "PD Standing"