@@ -88,6 +88,41 @@ def compute_zmp_ref(
8888 return zmp_ref
8989
9090
91+ def build_zmp_horizon (
92+ t , com_initial_pose , steps , ss_t , ds_t , t_init , t_final , interp_fn = cubic_spline_interpolation
93+ ):
94+ T = len (t )
95+ zmp_ref = np .zeros ([T , 2 ])
96+
97+ # Step on the first foot
98+ mask = t < t_init
99+ alpha = t [mask ] / t_init
100+ zmp_ref [mask , :] = interp_fn (alpha , com_initial_pose , steps [0 ])
101+
102+ # Alternate between foot
103+ for idx , (current_step , next_step ) in enumerate (zip (steps [:- 2 ], steps [1 :- 1 ])):
104+ # Compute current time range
105+ t_start = t_init + idx * (ss_t + ds_t )
106+
107+ # Add single support phase
108+ zmp_ref [(t >= t_start ) & (t < t_start + ss_t )] = current_step
109+
110+ # Add double support phase
111+ mask = (t >= t_start + ss_t ) & (t < t_start + ss_t + ds_t + t [1 ])
112+ alpha = (t [mask ] - (t_start + ss_t )) / ds_t
113+ zmp_ref [mask , :] = interp_fn (alpha , current_step , next_step )
114+
115+ # Last phase: SS on last-but-one, then blend to midpoint of last two
116+ t_start = t_init + (len (steps ) - 2 ) * (ss_t + ds_t )
117+ zmp_ref [(t >= t_start ) & (t < t_start + ss_t )] = steps [- 2 ]
118+
119+ mask = (t >= t_start + ss_t ) & (t < t_start + ss_t + t_final )
120+ alpha = (t [mask ] - (t_start + ss_t )) / t_final
121+ zmp_ref [mask , :] = interp_fn (alpha , steps [- 2 ], (steps [- 1 ] + steps [- 2 ]) / 2.0 )
122+
123+ return zmp_ref
124+
125+
91126@dataclass
92127class PreviewControllerParams :
93128 """
0 commit comments