-
Notifications
You must be signed in to change notification settings - Fork 1
/
megabot.py
125 lines (104 loc) · 3.88 KB
/
megabot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import time
import placo
import numpy as np
from ischedule import schedule, run_loop
from placo_utils.visualization import (
robot_viz,
robot_frame_viz,
frame_viz,
contacts_viz,
)
robot = placo.RobotWrapper("../models/megabot/", placo.Flags.ignore_collisions)
viz = robot_viz(robot)
# Updating joint limits and velocity limits
for leg in range(1, 5):
for r in range(1, 9):
# Passive joints have no limits and velocity limits
robot.set_joint_limits(f"l{leg}_r{r}", -2 * np.pi, 2 * np.pi)
robot.set_velocity_limit(f"l{leg}_r{r}", 1e8)
for c in range(1, 4):
# The cylinder has a stroke of 20 cm, we set a limit of 1kN and 0.2 m/s
security_margin = 0.02 # [m]
robot.set_joint_limits(f"l{leg}_c{c}", security_margin, 0.2 - security_margin)
robot.set_torque_limit(f"l{leg}_c{c}", 1000.0)
robot.set_velocity_limit(f"l{leg}_c{c}", 0.2)
# Initializing the dynamics solver
solver = placo.DynamicsSolver(robot)
# We reduce dramatically the cost of torque, since Megabot is involving huge forces
solver.torque_cost = 1e-6
# Adding hard closing loop constraints to match l*_cl*_1 and l*_cl*_2 in the XZ plane
for leg in range(1, 5):
for cl in range(1, 5):
closing_loop = solver.add_relative_position_task(
f"l{leg}_cl{cl}_1", f"l{leg}_cl{cl}_2", np.array([0.0, 0.0, 0.0])
)
closing_loop.configure(f"l{leg}_cl{cl}", "hard", 1.0)
closing_loop.mask.set_axises("xz")
contact = solver.add_task_contact(closing_loop)
# Enforcing passive DoFs to have zero torque
torque_task = solver.add_torque_task()
for leg in range(1, 5):
for r in range(1, 9):
torque_task.set_torque(f"l{leg}_r{r}", 0.0, 0.0, 1.0)
torque_task.configure("passive", "hard")
# Initializing T_world_base to identity
T_world_leg1 = robot.get_T_world_frame("leg_1")
z = T_world_leg1[2, 3]
T_world_base = robot.get_T_world_frame("base")
dz = T_world_base[2, 3] - T_world_leg1[2, 3]
T_world_base = np.eye(4)
T_world_base[2, 3] = 0.4
robot.set_T_world_frame("base", T_world_base)
robot.update_kinematics()
# We set the position of the base in the world
T_world_base = robot.get_T_world_frame("base")
base_task = solver.add_frame_task("base", T_world_base)
base_task.configure("base", "soft", 1.0, 10.0)
# We set the position of legs
legs_distance = 1.1
leg_targets = {
"leg_1": np.array([legs_distance, -legs_distance, 0]),
"leg_2": np.array([-legs_distance, -legs_distance, 0]),
"leg_3": np.array([-legs_distance, legs_distance, 0]),
"leg_4": np.array([legs_distance, legs_distance, 0]),
}
for leg in range(1, 5):
name = f"leg_{leg}"
T_world_leg = robot.get_T_world_frame(name)
leg_task = solver.add_position_task(name, leg_targets[name])
leg_task.configure(name, "hard", 1.0)
leg_contact = solver.add_point_contact(leg_task)
t = 0
solver.dt = 0.005
view_fps = 25 # FPS for viewer
steps_per_view = int((1 / view_fps) / solver.dt)
# Adding a puppet contact for initialization
puppet_contact = solver.add_puppet_contact()
for k in range(2000):
solver.solve(True)
robot.update_kinematics()
solver.remove_contact(puppet_contact)
solver.enable_torque_limits(True)
solver.enable_velocity_limits(True)
solver.enable_joint_limits(True)
@schedule(interval=(1 / view_fps))
def loop():
global t
for _ in range(steps_per_view):
t += solver.dt
# Update the body target frame
T = T_world_base.copy()
T[0, 3] = np.cos(t) * 0.15
T[1, 3] = np.sin(t) * 0.15
base_task.T_world_frame = T
base_task.position().dtarget_world = np.array(
[-np.sin(t) * 0.15, np.cos(t) * 0.15, 0.0]
)
solver.solve(True)
robot.update_kinematics()
# Displaying
viz.display(robot.state.q)
robot_frame_viz(robot, "base")
contacts_viz(solver, ratio=1e-3, radius=0.03)
frame_viz("target", base_task.T_world_frame, 0.5)
run_loop()