@@ -15,6 +15,7 @@ class MPCData(PyTreeNode):
1515 """Carry state for the pure functional MPC API."""
1616
1717 dt : float
18+ time : jnp .ndarray
1819 duty_factor : float
1920 step_freq : float
2021 step_height : float
@@ -24,6 +25,7 @@ class MPCData(PyTreeNode):
2425 U0 : jnp .ndarray
2526 V0 : jnp .ndarray
2627 W : jnp .ndarray
28+ extra_qref_data : object = None
2729
2830
2931mpx_data = MPCData
@@ -165,19 +167,27 @@ def __init__(self, config, limited_memory=False):
165167
166168 reference_generator = getattr (config , "reference_generator" , mpc_utils .reference_generator )
167169 clearance_speed = getattr (config , "clearance_speed" , getattr (config , "clearence_speed" , 0.2 ))
168- self ._ref_gen = jax .jit (
169- partial (
170- reference_generator ,
171- config .use_terrain_estimation ,
172- config .N ,
173- config .dt ,
174- config .n_joints ,
175- config .n_contact ,
176- robot_mass ,
177- foot0 = config .p_legs0 ,
178- q0 = config .q0 ,
179- clearence_speed = clearance_speed ,
180- )
170+
171+ ref_gen_kwargs = {
172+ "foot0" : config .p_legs0 ,
173+ "q0" : config .q0 ,
174+ "clearence_speed" : clearance_speed ,
175+ }
176+ if hasattr (config , "extra_qref_fn" ):
177+ ref_gen_kwargs ["extra_qref_fn" ] = config .extra_qref_fn
178+
179+ # `reference_generator` is already jitted in mpc_utils. Keep a single
180+ # binding layer here to avoid argument-position ambiguities when an
181+ # extra q-ref callback is provided from config.
182+ self ._ref_gen = partial (
183+ reference_generator ,
184+ config .use_terrain_estimation ,
185+ config .N ,
186+ config .dt ,
187+ config .n_joints ,
188+ config .n_contact ,
189+ robot_mass ,
190+ ** ref_gen_kwargs ,
181191 )
182192 self ._timer_run = jax .jit (mpc_utils .timer_run )
183193 self ._update_warm_start = partial (
@@ -193,6 +203,7 @@ def make_data(self):
193203
194204 return MPCData (
195205 dt = self .config .dt ,
206+ time = jnp .asarray (0.0 , dtype = jnp .float32 ),
196207 duty_factor = self .config .duty_factor ,
197208 step_freq = self .config .step_freq ,
198209 step_height = self .config .step_height ,
@@ -202,6 +213,7 @@ def make_data(self):
202213 U0 = self .initial_U0 ,
203214 V0 = self .initial_V0 ,
204215 W = self .config .W ,
216+ extra_qref_data = getattr (self .config , "extra_qref_data" , None ),
205217 )
206218
207219 def control_output (self , x0 , X , U , reference , parameter ):
@@ -226,6 +238,8 @@ def _run_impl(self, data, x0, input, contact):
226238 input = input ,
227239 liftoff = data .liftoff ,
228240 contact = contact ,
241+ current_time = data .time ,
242+ extra_qref_data = data .extra_qref_data ,
229243 )
230244
231245 # Reference generation and solver execution stay on the pure JAX path.
@@ -255,7 +269,9 @@ def _run_impl(self, data, x0, input, contact):
255269 V ,
256270 )
257271
272+ new_time = data .time + jnp .asarray (1 / self .mpc_frequency , dtype = data .time .dtype )
258273 data = data .replace (
274+ time = new_time ,
259275 X0 = X0 ,
260276 U0 = U0 ,
261277 V0 = V0 ,
@@ -286,6 +302,7 @@ def reset(self, data, qpos, qvel, foot):
286302 U0 = self .initial_U0 ,
287303 X0 = jnp .tile (initial_state , (self .config .N + 1 , 1 )),
288304 V0 = self .initial_V0 ,
305+ time = jnp .asarray (0.0 , dtype = jnp .float32 ),
289306 contact_time = self .config .timer_t ,
290307 liftoff = jnp .ravel (foot ),
291308 )
0 commit comments