First Commit
This commit is contained in:
121
Deploy_Tienkung/policy/beyondzero/fsm_beyondzero.py
Normal file
121
Deploy_Tienkung/policy/beyondzero/fsm_beyondzero.py
Normal file
@@ -0,0 +1,121 @@
|
||||
"""
|
||||
BeyondZero FSM state
|
||||
Moves the robot to the BeyondMimic default pose using smooth interpolation.
|
||||
"""
|
||||
import os
|
||||
from typing import List
|
||||
|
||||
import numpy as np
|
||||
import yaml
|
||||
|
||||
from FSM.fsm_base import FSMState, FSMStateName
|
||||
from common.joystick import ControlFlag
|
||||
from common.robot_data import RobotData
|
||||
|
||||
|
||||
class FSMStateBeyondZero(FSMState):
|
||||
"""Zero pose specifically aligned with the BeyondMimic policy, with explicitly specified 29-joint target positions."""
|
||||
|
||||
def __init__(self, robot_data: RobotData):
|
||||
super().__init__(robot_data)
|
||||
self.current_state_name = FSMStateName.BEYONDZERO
|
||||
self.q_factor = 0.0
|
||||
self.motor_nums = 29
|
||||
self.start_pose = np.zeros(self.motor_nums, dtype=np.float32)
|
||||
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
config_path = os.path.join(current_dir, "config", "beyondzero.yaml")
|
||||
with open(config_path, "r") as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
self.motor_nums: int = int(config["motor_nums"])
|
||||
self.locked_joint_map: List[int] = config["locked_joint_map"]
|
||||
self.kps = np.array(config["kps"], dtype=np.float32)
|
||||
self.kds = np.array(config["kds"], dtype=np.float32)
|
||||
self.interp_step = float(config.get("interp_step", 0.001))
|
||||
self.interp_max = float(config.get("interp_max", 1.0))
|
||||
|
||||
# Explicitly define the 29-joint zero target positions
|
||||
# These values are based on the default joint positions expanded to 29 elements.
|
||||
# Adjust the array below as needed to specify your desired initial target positions for all 29 joints.
|
||||
# For example, positions for controllable joints are set from defaults, others to 0.0.
|
||||
self.zero_target = np.array([
|
||||
-0.94777486, # hip_pitch_l_joint
|
||||
0.15228635, # hip_roll_l_joint
|
||||
-0.11064088, # hip_yaw_l_joint
|
||||
0.70493567, # knee_pitch_l_joint
|
||||
-0.07427792, # ankle_pitch_l_joint
|
||||
-0.08085743, # ankle_roll_l_joint
|
||||
-0.94510548, # hip_pitch_r_joint
|
||||
-0.19115149, # hip_roll_r_joint
|
||||
0.01340432, # hip_yaw_r_joint
|
||||
0.79190012, # knee_pitch_r_joint
|
||||
-0.19874191, # ankle_pitch_r_joint
|
||||
0.02820061, # ankle_roll_r_joint
|
||||
-0.0, # waist_yaw_joint
|
||||
-0.0, # waist_roll_joint
|
||||
0.17578462, # waist_pitch_joint
|
||||
-1.01426013, # shoulder_pitch_l_joint
|
||||
0.000, # shoulder_roll_l_joint (adjusted example)
|
||||
0.000, # shoulder_yaw_l_joint
|
||||
-1.78047789, # elbow_pitch_l_joint
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
-1.01426013, # shoulder_pitch_r_joint
|
||||
0.000, # shoulder_roll_r_joint
|
||||
0.000, # shoulder_yaw_r_joint
|
||||
-1.78047789, # elbow_pitch_r_joint
|
||||
0.000, # Additional joints (e.g., wrists or others, set to 0.0)
|
||||
0.000,
|
||||
0.000 # Last joint
|
||||
], dtype=np.float32)
|
||||
|
||||
# If preferred, load from config instead of hardcoding:
|
||||
# self.zero_target = np.array(config.get("zero_target", self.zero_target.tolist()), dtype=np.float32)
|
||||
|
||||
if len(self.zero_target) != self.motor_nums:
|
||||
raise ValueError(f"Specified zero_target length ({len(self.zero_target)}) does not match motor_nums ({self.motor_nums}).")
|
||||
|
||||
def on_enter(self):
|
||||
print("[FSMStateBeyondZero] Enter zero pose with specified 29-joint targets")
|
||||
self.q_factor = 0.0
|
||||
if self.robot_data_ is not None:
|
||||
self.start_pose = self.robot_data_.get_joint_pos().copy()
|
||||
else:
|
||||
self.start_pose = np.zeros(self.motor_nums, dtype=np.float32)
|
||||
|
||||
def run(self, flag: ControlFlag):
|
||||
if self.robot_data_ is None:
|
||||
return
|
||||
|
||||
target = self.zero_target
|
||||
if self.q_factor < self.interp_max:
|
||||
pos_cmd = (1.0 - self.q_factor) * self.start_pose + self.q_factor * target
|
||||
self.q_factor = min(self.q_factor + self.interp_step, self.interp_max)
|
||||
else:
|
||||
pos_cmd = target
|
||||
|
||||
joint_start_idx = 35 - self.motor_nums
|
||||
self.robot_data_.q_d_[joint_start_idx:] = pos_cmd
|
||||
self.robot_data_.q_dot_d_[joint_start_idx:] = 0.0
|
||||
self.robot_data_.tau_d_[joint_start_idx:] = 0.0
|
||||
|
||||
self.robot_data_.joint_kp_p_[:self.motor_nums] = self.kps
|
||||
self.robot_data_.joint_kd_p_[:self.motor_nums] = self.kds
|
||||
|
||||
def on_exit(self):
|
||||
print("[FSMStateBeyondZero] Exit BeyondZero state")
|
||||
|
||||
def check_transition(self, flag: ControlFlag) -> FSMStateName:
|
||||
"""Allow transitions to other FSM states."""
|
||||
if flag.fsm_state_command == "gotoSTOP":
|
||||
return FSMStateName.STOP
|
||||
elif flag.fsm_state_command == "gotoZERO":
|
||||
return FSMStateName.ZERO
|
||||
elif flag.fsm_state_command == "gotoBEYONDMIMIC":
|
||||
return FSMStateName.BEYONDMIMIC
|
||||
elif flag.fsm_state_command == "gotoBEYONDZERO":
|
||||
return FSMStateName.BEYONDZERO
|
||||
else:
|
||||
return None
|
||||
Reference in New Issue
Block a user