Skip to content

Commit 21e44b7

Browse files
committed
update h1_2 and g1 low_level example
1 parent 86755a4 commit 21e44b7

2 files changed

Lines changed: 212 additions & 4 deletions

File tree

example/g1/low_level/g1_ankle_swing_example.py renamed to example/g1/low_level/g1_low_level_example.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ def Init(self):
102102
self.lowcmd_publisher_.Init()
103103

104104
# create subscriber #
105-
self.__lowstate_subscriber = ChannelSubscriber("rt/lowstate", LowState_)
106-
self.__lowstate_subscriber.Init(self.LowStateHandler, 10)
105+
self.lowstate_subscriber = ChannelSubscriber("rt/lowstate", LowState_)
106+
self.lowstate_subscriber.Init(self.LowStateHandler, 10)
107107

108108
def Start(self):
109109
self.lowCmdWriteThreadPtr = RecurrentThread(
110-
interval=self.control_dt_, target=self.__LowCmdWrite, name="control"
110+
interval=self.control_dt_, target=self.LowCmdWrite, name="control"
111111
)
112112
while self.update_mode_machine_ == False:
113113
time.sleep(1)
@@ -127,7 +127,7 @@ def LowStateHandler(self, msg: LowState_):
127127
self.counter_ = 0
128128
print(self.low_state.imu_state.rpy)
129129

130-
def __LowCmdWrite(self):
130+
def LowCmdWrite(self):
131131
self.time_ += self.control_dt_
132132

133133
if self.time_ < self.duration_ :
@@ -176,6 +176,13 @@ def __LowCmdWrite(self):
176176
self.low_cmd.motor_cmd[G1JointIndex.LeftAnkleB].q = L_B_des
177177
self.low_cmd.motor_cmd[G1JointIndex.RightAnkleA].q = R_A_des
178178
self.low_cmd.motor_cmd[G1JointIndex.RightAnkleB].q = R_B_des
179+
180+
max_WristYaw = np.pi * 30.0 / 180.0
181+
L_WristYaw_des = max_WristYaw * np.sin(2.0 * np.pi * t)
182+
R_WristYaw_des = max_WristYaw * np.sin(2.0 * np.pi * t)
183+
self.low_cmd.motor_cmd[G1JointIndex.LeftWristRoll].q = L_WristYaw_des
184+
self.low_cmd.motor_cmd[G1JointIndex.RightWristRoll].q = R_WristYaw_des
185+
179186

180187
self.low_cmd.crc = self.crc.Crc(self.low_cmd)
181188
self.lowcmd_publisher_.Write(self.low_cmd)
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
import time
2+
import sys
3+
4+
from unitree_sdk2py.core.channel import ChannelPublisher, ChannelFactoryInitialize
5+
from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize
6+
from unitree_sdk2py.idl.default import unitree_hg_msg_dds__LowCmd_
7+
from unitree_sdk2py.idl.default import unitree_hg_msg_dds__LowState_
8+
from unitree_sdk2py.idl.unitree_hg.msg.dds_ import LowCmd_
9+
from unitree_sdk2py.idl.unitree_hg.msg.dds_ import LowState_
10+
from unitree_sdk2py.utils.crc import CRC
11+
from unitree_sdk2py.utils.thread import RecurrentThread
12+
from unitree_sdk2py.comm.motion_switcher.motion_switcher_client import MotionSwitcherClient
13+
14+
import numpy as np
15+
16+
H1_2_NUM_MOTOR = 27
17+
18+
class H1_2_JointIndex:
19+
# legs
20+
LeftHipYaw = 0
21+
LeftHipPitch = 1
22+
LeftHipRoll = 2
23+
LeftKnee = 3
24+
LeftAnklePitch = 4
25+
LeftAnkleB = 4
26+
LeftAnkleRoll = 5
27+
LeftAnkleA = 5
28+
RightHipYaw = 6
29+
RightHipPitch = 7
30+
RightHipRoll = 8
31+
RightKnee = 9
32+
RightAnklePitch = 10
33+
RightAnkleB = 10
34+
RightAnkleRoll = 11
35+
RightAnkleA = 11
36+
# torso
37+
WaistYaw = 12
38+
# arms
39+
LeftShoulderPitch = 13
40+
LeftShoulderRoll = 14
41+
LeftShoulderYaw = 15
42+
LeftElbow = 16
43+
LeftWristRoll = 17
44+
LeftWristPitch = 18
45+
LeftWristYaw = 19
46+
RightShoulderPitch = 20
47+
RightShoulderRoll = 21
48+
RightShoulderYaw = 22
49+
RightElbow = 23
50+
RightWristRoll = 24
51+
RightWristPitch = 25
52+
RightWristYaw = 26
53+
54+
55+
class Mode:
56+
PR = 0 # Series Control for Pitch/Roll Joints
57+
AB = 1 # Parallel Control for A/B Joints
58+
59+
class Custom:
60+
def __init__(self):
61+
self.time_ = 0.0
62+
self.control_dt_ = 0.002 # [2ms]
63+
self.duration_ = 3.0 # [3 s]
64+
self.counter_ = 0
65+
self.mode_pr_ = Mode.PR
66+
self.mode_machine_ = 0
67+
self.low_cmd = unitree_hg_msg_dds__LowCmd_()
68+
self.low_state = None
69+
self.update_mode_machine_ = False
70+
self.crc = CRC()
71+
72+
def Init(self):
73+
self.msc = MotionSwitcherClient()
74+
self.msc.SetTimeout(5.0)
75+
self.msc.Init()
76+
77+
status, result = self.msc.CheckMode()
78+
while result['name']:
79+
self.msc.ReleaseMode()
80+
status, result = self.msc.CheckMode()
81+
time.sleep(1)
82+
83+
# create publisher #
84+
self.lowcmd_publisher_ = ChannelPublisher("rt/lowcmd", LowCmd_)
85+
self.lowcmd_publisher_.Init()
86+
87+
# create subscriber #
88+
self.lowstate_subscriber = ChannelSubscriber("rt/lowstate", LowState_)
89+
self.lowstate_subscriber.Init(self.LowStateHandler, 10)
90+
91+
def Start(self):
92+
self.lowCmdWriteThreadPtr = RecurrentThread(
93+
interval=self.control_dt_, target=self.LowCmdWrite, name="control"
94+
)
95+
while self.update_mode_machine_ == False:
96+
time.sleep(1)
97+
98+
if self.update_mode_machine_ == True:
99+
self.lowCmdWriteThreadPtr.Start()
100+
101+
def LowStateHandler(self, msg: LowState_):
102+
self.low_state = msg
103+
104+
if self.update_mode_machine_ == False:
105+
self.mode_machine_ = self.low_state.mode_machine
106+
self.update_mode_machine_ = True
107+
108+
self.counter_ +=1
109+
if (self.counter_ % 500 == 0) :
110+
self.counter_ = 0
111+
print(self.low_state.imu_state.rpy)
112+
113+
def LowCmdWrite(self):
114+
self.time_ += self.control_dt_
115+
self.low_cmd.mode_pr = Mode.PR
116+
self.low_cmd.mode_machine = self.mode_machine_
117+
for i in range(H1_2_NUM_MOTOR):
118+
ratio = np.clip(self.time_ / self.duration_, 0.0, 1.0)
119+
self.low_cmd.motor_cmd[i].mode = 1 # 1:Enable, 0:Disable
120+
self.low_cmd.motor_cmd[i].tau = 0.0
121+
self.low_cmd.motor_cmd[i].q = 0.0
122+
self.low_cmd.motor_cmd[i].dq = 0.0
123+
self.low_cmd.motor_cmd[i].kp = 100.0 if i < 13 else 50.0
124+
self.low_cmd.motor_cmd[i].kd = 1.0
125+
126+
if self.time_ < self.duration_ :
127+
# [Stage 1]: set robot to zero posture
128+
for i in range(H1_2_NUM_MOTOR):
129+
ratio = np.clip(self.time_ / self.duration_, 0.0, 1.0)
130+
self.low_cmd.mode_pr = Mode.PR
131+
self.low_cmd.mode_machine = self.mode_machine_
132+
self.low_cmd.motor_cmd[i].mode = 1 # 1:Enable, 0:Disable
133+
self.low_cmd.motor_cmd[i].tau = 0.
134+
self.low_cmd.motor_cmd[i].q = (1.0 - ratio) * self.low_state.motor_state[i].q
135+
self.low_cmd.motor_cmd[i].dq = 0.
136+
self.low_cmd.motor_cmd[i].kp = 100.0 if i < 13 else 50.0
137+
self.low_cmd.motor_cmd[i].kd = 1.0
138+
else :
139+
# [Stage 2]: swing ankle using PR mode
140+
max_P = 0.25
141+
max_R = 0.25
142+
t = self.time_ - self.duration_
143+
L_P_des = max_P * np.cos(2.0 * np.pi * t)
144+
L_R_des = max_R * np.sin(2.0 * np.pi * t)
145+
R_P_des = max_P * np.cos(2.0 * np.pi * t)
146+
R_R_des = -max_R * np.sin(2.0 * np.pi * t)
147+
148+
Kp_Pitch = 80
149+
Kd_Pitch = 1
150+
Kp_Roll = 80
151+
Kd_Roll = 1
152+
153+
self.low_cmd.mode_pr = Mode.PR
154+
self.low_cmd.mode_machine = self.mode_machine_
155+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftAnklePitch].q = L_P_des
156+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftAnklePitch].dq = 0
157+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftAnklePitch].kp = Kp_Pitch
158+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftAnklePitch].kd = Kd_Pitch
159+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftAnkleRoll].q = L_R_des
160+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftAnkleRoll].dq = 0
161+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftAnkleRoll].kp = Kp_Roll
162+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftAnkleRoll].kd = Kd_Roll
163+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightAnklePitch].q = R_P_des
164+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightAnklePitch].dq = 0
165+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightAnklePitch].kp = Kp_Pitch
166+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightAnklePitch].kd = Kd_Pitch
167+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightAnkleRoll].q = R_R_des
168+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightAnkleRoll].dq = 0
169+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightAnkleRoll].kp = Kp_Roll
170+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightAnkleRoll].kd = Kd_Roll
171+
172+
max_wrist_roll_angle = 0.5; # [rad]
173+
WristRoll_des = max_wrist_roll_angle * np.sin(2.0 * np.pi * t)
174+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftWristRoll].q = WristRoll_des
175+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftWristRoll].dq = 0
176+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftWristRoll].kp = 50
177+
self.low_cmd.motor_cmd[H1_2_JointIndex.LeftWristRoll].kd = 1
178+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightWristRoll].q = WristRoll_des
179+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightWristRoll].dq = 0
180+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightWristRoll].kp = 50
181+
self.low_cmd.motor_cmd[H1_2_JointIndex.RightWristRoll].kd = 1
182+
183+
self.low_cmd.crc = self.crc.Crc(self.low_cmd)
184+
self.lowcmd_publisher_.Write(self.low_cmd)
185+
186+
if __name__ == '__main__':
187+
188+
print("WARNING: Please ensure there are no obstacles around the robot while running this example.")
189+
input("Press Enter to continue...")
190+
191+
if len(sys.argv)>1:
192+
ChannelFactoryInitialize(0, sys.argv[1])
193+
else:
194+
ChannelFactoryInitialize(0)
195+
196+
custom = Custom()
197+
custom.Init()
198+
custom.Start()
199+
200+
while True:
201+
time.sleep(1)

0 commit comments

Comments
 (0)