Skip to content

Commit 2e51ff6

Browse files
committed
Add docstrings
1 parent 2c516fd commit 2e51ff6

1 file changed

Lines changed: 116 additions & 6 deletions

File tree

biped_walking_controller/preview_control.py

Lines changed: 116 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -258,15 +258,33 @@ def update_control(ctrl_mat: PreviewControllerMatrices, current_zmp, zmp_ref, x,
258258

259259

260260
class WalkingState(Enum):
261-
INIT = 0
262-
DS = 1
263-
SS_LEFT = 2
264-
SS_RIGHT = 3
265-
END = 4
261+
"""Enumeration of the high-level walking phases."""
262+
263+
INIT = 0 # Initialization (pre-walk)
264+
DS = 1 # Double support phase
265+
SS_LEFT = 2 # Single support, left foot stance
266+
SS_RIGHT = 3 # Single support, right foot stance
267+
END = 4 # End of walking sequence
266268

267269

268270
@dataclass
269271
class WalkingStateMachineParams:
272+
"""Timing and contact parameters for the walking state machine.
273+
274+
Attributes
275+
----------
276+
t_init : float
277+
Duration of the initial phase before starting walking [s].
278+
t_end : float
279+
Duration of the final phase after the last step [s].
280+
t_ss : float
281+
Nominal duration of a single support phase [s].
282+
t_ds : float
283+
Nominal duration of a double support phase [s].
284+
force_threshold : float
285+
Contact force threshold used to detect foot contact [N].
286+
"""
287+
270288
t_init: float = 2.0 # [s]
271289
t_end: float = 2.0 # [s]
272290
t_ss: float = 0.8 # [s]
@@ -275,7 +293,26 @@ class WalkingStateMachineParams:
275293

276294

277295
class WalkingStateMachine:
278-
def __init__(self, params: WalkingStateMachineParams, initial_state=WalkingState.INIT):
296+
"""Finite state machine controlling walking phases.
297+
298+
The state machine advances through INIT, DS, SS_LEFT, SS_RIGHT, and END
299+
based on elapsed time and measured foot contact forces.
300+
"""
301+
302+
def __init__(
303+
self,
304+
params: WalkingStateMachineParams,
305+
initial_state: WalkingState = WalkingState.INIT,
306+
):
307+
"""Initialize the walking state machine.
308+
309+
Parameters
310+
----------
311+
params : WalkingStateMachineParams
312+
Timing and contact parameters for the state machine.
313+
initial_state : WalkingState, optional
314+
Initial state of the machine, by default WalkingState.INIT.
315+
"""
279316
self.params = params
280317
self.state = initial_state
281318
self.next_ss_state = WalkingState.SS_RIGHT
@@ -284,6 +321,14 @@ def __init__(self, params: WalkingStateMachineParams, initial_state=WalkingState
284321
self.step_idx = None
285322

286323
def update_steps(self, steps_pose):
324+
"""Set the planned sequence of steps.
325+
326+
Parameters
327+
----------
328+
steps_pose :
329+
Container describing the planned footsteps (e.g. list/array of poses).
330+
Only its length is used here to know when the last step is reached.
331+
"""
287332
self.steps = steps_pose
288333
self.step_idx = 0
289334

@@ -293,6 +338,22 @@ def update(
293338
rf_contact_force: float,
294339
lf_contact_force: float,
295340
):
341+
"""Update the state machine given time and contact forces.
342+
343+
Parameters
344+
----------
345+
t : float
346+
Current time [s].
347+
rf_contact_force : float
348+
Measured contact force under the right foot [N].
349+
lf_contact_force : float
350+
Measured contact force under the left foot [N].
351+
352+
Notes
353+
-----
354+
This method updates the internal state of the machine in-place.
355+
If no steps have been provided with `update_steps`, it returns immediately.
356+
"""
296357
if self.steps is None:
297358
return
298359

@@ -315,23 +376,72 @@ def update(
315376
self.steps = None
316377

317378
def get_current_state(self) -> WalkingState:
379+
"""Return the current walking state.
380+
381+
Returns
382+
-------
383+
WalkingState
384+
Current state of the finite state machine.
385+
"""
318386
return self.state
319387

320388
def _switch_single_support_leg(self, t: float):
389+
"""Switch to the next single-support state and reset the phase timer.
390+
391+
Parameters
392+
----------
393+
t : float
394+
Current time [s], used as the new phase start time.
395+
"""
321396
self.t_start = t
322397
self.state = self.next_ss_state
323398
self.next_ss_state = (
324399
WalkingState.SS_LEFT if self.state == WalkingState.SS_RIGHT else WalkingState.SS_RIGHT
325400
)
326401

327402
def _try_transition_to_single_support(self, t: float, duration: float):
403+
"""Transition from INIT/DS to the next single-support state if duration elapsed.
404+
405+
Parameters
406+
----------
407+
t : float
408+
Current time [s].
409+
duration : float
410+
Required time spent in the current phase before switching [s].
411+
"""
328412
if t - self.t_start > duration:
329413
self._switch_single_support_leg(t)
330414

331415
def _is_last_step(self) -> bool:
416+
"""Check whether the current step is the last one.
417+
418+
Returns
419+
-------
420+
bool
421+
True if the current step index corresponds to the last planned step,
422+
False otherwise.
423+
"""
332424
return self.step_idx == len(self.steps) - 2
333425

334426
def _try_transition_to_ds_or_end(self, t: float, contact_force: float):
427+
"""Transition from single support to double support or END.
428+
429+
Parameters
430+
----------
431+
t : float
432+
Current time [s].
433+
contact_force : float
434+
Measured contact force of the swing foot [N].
435+
436+
Notes
437+
-----
438+
The transition is triggered when:
439+
- at least half of `t_ss` has elapsed since `t_start`, and
440+
- the swing foot contact force exceeds `force_threshold`.
441+
442+
If the current step is the last one, the next state is END.
443+
Otherwise the state transitions to DS and the step index is incremented.
444+
"""
335445
if (
336446
t - self.t_start > 0.5 * self.params.t_ss
337447
and contact_force > self.params.force_threshold

0 commit comments

Comments
 (0)