Skip to content

Commit d02db79

Browse files
committed
walk to trot transition mathematics
1 parent f436411 commit d02db79

File tree

2 files changed

+189
-0
lines changed

2 files changed

+189
-0
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
###
2+
# Quadruped Robot gait transitions between walk and trot
3+
# CPG controller is based on 4 HOPF Oscillators (Read cpg fold to known more)
4+
#
5+
# For Walk:
6+
# beta = 0.75
7+
# phi_LF = 0
8+
# phi_RF = 0.5
9+
# phi_LH = 0.75
10+
# phi_RH = 0.25
11+
#
12+
# For Trot:
13+
# beta = 0.5
14+
# phi_LF = 0
15+
# phi_RF = 0.5
16+
# phi_LH = 0
17+
# phi_RH = 0.5
18+
#
19+
# Then:
20+
# Phi3 = 0.25 or 0
21+
# Phi1 = 0, Phi2 = 0.5, Phi4 = 0.5 + Phi3
22+
# Beta = 0.5 + Phi3
23+
# theta21 = - pi
24+
# theta31 = - Phi3 * 2 * pi
25+
# theta41 = - (0.5 + Phi3) * 2 * pi
26+
# theta12 = pi
27+
# theta32 = (0.5 - Phi3) * 2 * pi
28+
# theta42 = - Phi3 * 2 * pi
29+
# theta13 = Phi3 * 2 * pi
30+
# theta23 = (Phi3 - 0.5) * 2 * pi
31+
# theta43 = - pi
32+
# theta14 = (0.5 + Phi3) * 2 * pi
33+
# theta24 = Phi3 * 2 * pi
34+
# theta34 = pi
35+
#
36+
###
37+
38+
import matplotlib.pyplot as plt
39+
import numpy as np
40+
41+
alpha = 1000
42+
Ah = 1
43+
Ak = 0.5
44+
omega_sw = 5 * np.pi
45+
a = 10
46+
mu = Ah ** 2
47+
48+
phi3 = 0.25
49+
50+
# phase config
51+
phi = [0, 0.5, phi3, 0.5 + phi3]
52+
beta = 0.5 + phi3
53+
omega_st = omega_sw * (1 - beta) / beta
54+
55+
# 5 seconds
56+
sim_duration = 10
57+
dt = 0.01
58+
iteration = 100
59+
60+
x1, y1, x2, y2, x3, y3, x4, y4 = (1, 0, 0, 0, 0, 0, 0, 0)
61+
Q1 = np.matrix([x1, y1]).T
62+
Q2 = np.matrix([x2, y2]).T
63+
Q3 = np.matrix([x3, y3]).T
64+
Q4 = np.matrix([x4, y4]).T
65+
Q = np.vstack([Q1, Q2, Q3, Q4])
66+
67+
# result collection
68+
theta_h1_t = []
69+
theta_h2_t = []
70+
theta_h3_t = []
71+
theta_h4_t = []
72+
theta_k1_t = []
73+
theta_k2_t = []
74+
theta_k3_t = []
75+
theta_k4_t = []
76+
77+
t_t = np.arange(0, sim_duration, dt)
78+
79+
for t in t_t:
80+
for _ in np.arange(iteration):
81+
# change the phi3 to 0 from 2s
82+
if t >= 4 and phi3 > 0:
83+
phi3 -= 0.01
84+
phi = [0, 0.5, phi3, 0.5 + phi3]
85+
beta = 0.5 + phi3
86+
omega_st = omega_sw * (1 - beta) / beta
87+
88+
r1_square = x1 ** 2 + y1 ** 2
89+
r2_square = x2 ** 2 + y2 ** 2
90+
r3_square = x3 ** 2 + y3 ** 2
91+
r4_square = x4 ** 2 + y4 ** 2
92+
93+
# Frequency of the Oscillator
94+
omega1 = omega_st / (np.exp(- a * y1) + 1) + omega_sw / (np.exp(a * y1) + 1)
95+
omega2 = omega_st / (np.exp(- a * y2) + 1) + omega_sw / (np.exp(a * y2) + 1)
96+
omega3 = omega_st / (np.exp(- a * y3) + 1) + omega_sw / (np.exp(a * y3) + 1)
97+
omega4 = omega_st / (np.exp(- a * y4) + 1) + omega_sw / (np.exp(a * y4) + 1)
98+
99+
FQ = np.matrix([
100+
alpha * (mu - r1_square) * x1 - omega1 * y1,
101+
alpha * (mu - r1_square) * y1 + omega1 * x1,
102+
alpha * (mu - r2_square) * x2 - omega2 * y2,
103+
alpha * (mu - r2_square) * y2 + omega2 * x2,
104+
alpha * (mu - r3_square) * x3 - omega3 * y3,
105+
alpha * (mu - r3_square) * y3 + omega3 * x3,
106+
alpha * (mu - r4_square) * x4 - omega4 * y4,
107+
alpha * (mu - r4_square) * y4 + omega4 * x4
108+
]).T
109+
110+
"""
111+
Coupling Matrix of 4 Oscillators
112+
R = [
113+
R11, R21, R31, R41;
114+
R12, R22, R32, R42;
115+
R13, R23, R33, R43;
116+
R14, R24, R34, R44
117+
]
118+
119+
Rji = [
120+
cos(theta_ji), -sin(theta_ji);
121+
sin(theta_ji), cos(theta_ji)
122+
]
123+
124+
theta_ji = phi_j - phi_i
125+
"""
126+
R = np.asmatrix(np.full((8, 8), None))
127+
for i in range(0, 4):
128+
for j in range(0, 4):
129+
theta_ji = 2 * np.pi * (phi[j] - phi[i])
130+
R[i * 2, j * 2] = np.cos(theta_ji)
131+
R[i * 2, j * 2 + 1] = - np.sin(theta_ji)
132+
R[i * 2 + 1, j * 2] = np.sin(theta_ji)
133+
R[i * 2 + 1, j * 2 + 1] = R[i * 2, j * 2]
134+
135+
# Q_dot = F(Q) + RQ
136+
Q_dot = FQ + np.dot(R, Q)
137+
138+
Q = Q + Q_dot * dt / iteration
139+
x1 = Q[0, 0]
140+
y1 = Q[1, 0]
141+
x2 = Q[2, 0]
142+
y2 = Q[3, 0]
143+
x3 = Q[4, 0]
144+
y3 = Q[5, 0]
145+
x4 = Q[6, 0]
146+
y4 = Q[7, 0]
147+
148+
# Signal Data Collection
149+
theta_h1_t.append(x1)
150+
theta_h2_t.append(x2)
151+
theta_h3_t.append(x3)
152+
theta_h4_t.append(x4)
153+
#
154+
# if y1 > 0:
155+
# theta_k1 = 0
156+
# else:
157+
# theta_k1 = - Ak / Ah * y1
158+
#
159+
# if y2 > 0:
160+
# theta_k2 = 0
161+
# else:
162+
# theta_k2 = - Ak / Ah * y2
163+
#
164+
# if y3 > 0:
165+
# theta_k3 = 0
166+
# else:
167+
# theta_k3 = Ak / Ah * y3
168+
#
169+
# if y4 > 0:
170+
# theta_k4 = 0
171+
# else:
172+
# theta_k4 = Ak / Ah * y4
173+
#
174+
# theta_k1_t.append(theta_k1)
175+
# theta_k2_t.append(theta_k2)
176+
# theta_k3_t.append(theta_k3)
177+
# theta_k4_t.append(theta_k4)
178+
179+
plt.figure()
180+
plt.subplot()
181+
plt.plot(t_t, theta_h1_t, '-', label='limb1')
182+
plt.plot(t_t, theta_h2_t, '--', label='limb2')
183+
plt.plot(t_t, theta_h3_t, '-.', label='limb3')
184+
plt.plot(t_t, theta_h4_t, ':', label='limb4')
185+
plt.ylabel('joint angle/rad')
186+
plt.xlabel('time/s')
187+
plt.grid()
188+
plt.legend()
189+
plt.show()
Loading

0 commit comments

Comments
 (0)