pyrcf.control_loop

Ctrl Loop runners for running the pyrcf components in a control loop.

Submodules

Classes

SimpleManagedCtrlLoop

A minimal control loop that takes in a controller manager instead of a single controller and

MinimalCtrlLoop

A minimal control loop with only 1 controller and 1 local planner.

Package Contents

class pyrcf.control_loop.SimpleManagedCtrlLoop(robot_interface: pyrcf.components.robot_interfaces.robot_interface_base.RobotInterface, state_estimator: pyrcf.components.state_estimators.state_estimator_base.StateEstimatorBase, controller_manager: pyrcf.components.controller_manager.controller_manager_base.ControllerManagerBase, global_planner: pyrcf.components.global_planners.global_planner_base.GlobalMotionPlannerBase, verbose: bool = True)

A minimal control loop that takes in a controller manager instead of a single controller and local planner.

The run method runs the following in a loop of specified frequency.

  1. read robot state from robot interface

  2. update robot state with state estimates from state estimator

  3. get global plan message from global planner / user interface

  4. for agent in controller_manager.agents:
    1. compute control command to track the global plan (agent may be a Planner+Controller

      agent)

  5. accumulate commands from accumulation policy used by controller manager

  6. write control command to robot

robot
state_estimator
controller_manager
global_planner
_true_dt_getter
_true_dt = 0.0
_loop_count = 0
run(loop_rate: float, clock: pyrcf.utils.time_utils.ClockBase = PythonPerfClock(), debuggers: List[pyrcf.components.ctrl_loop_debuggers.ctrl_loop_debugger_base.CtrlLoopDebuggerBase] = None, prestep_callbacks: List[pyrcf.components.callback_handlers.base_callbacks.CustomCallbackBase] = None, poststep_callbacks: List[pyrcf.components.callback_handlers.base_callbacks.CustomCallbackBase] = None)

The main control loop.

Parameters:
  • loop_rate (float) – loop rate in hz. This will always use the system clock to try and maintain the desired control loop rate.

  • clock (ClockBase, optional) – Defines the clock to use for querying time for the components in the control loop. Time will be queried once per loop and the same t and dt will be passed to all components in that iteration. The option to select the clock is so that sim time can be used if required.

  • debuggers (CtrlLoopDebuggerBase, optional) – List of CtrlLoopDebuggerBase objects that are to be run in the control loop.

  • prestep_callbacks (List[CustomCallbackBase], optional) – List of CustomCallbackBase objects to be run in the control loop. Not recommended to do this except for debugging. Defaults to None.

  • poststep_callbacks (List[CustomCallbackBase]. optional) – List of additional CustomCallbackBase objects to be run in the control loop. Not recommended to do this except for debugging. Defaults to None.

get_actual_loop_rate() Tuple[float, float]

Get the true loop rate and dt (using system clock).

Returns:

True dt (s), true loop rate (hz)

Return type:

Tuple[float, float]

get_loop_count() int

Get the current number of iterations of the control loop.

Returns:

current number of iterations of the control loop

Return type:

int

shutdown()

Cleanly shutdown all components in the control loop. Sequence of shutdown:

  • robot interface

  • controller manager

  • global planner

send_shutdown_signal()

Request clean shutdown of control loop and components.

class pyrcf.control_loop.MinimalCtrlLoop(robot_interface: pyrcf.components.robot_interfaces.robot_interface_base.RobotInterface, state_estimator: pyrcf.components.state_estimators.state_estimator_base.StateEstimatorBase, controller: pyrcf.components.controllers.controller_base.ControllerBase, local_planner: pyrcf.components.local_planners.LocalPlannerBase, global_planner: pyrcf.components.global_planners.global_planner_base.GlobalMotionPlannerBase, verbose: bool = True)

Bases: pyrcf.control_loop.simple_managed_ctrl_loop.SimpleManagedCtrlLoop

A minimal control loop with only 1 controller and 1 local planner.

The run method runs the following in a loop of specified frequency.

  1. read robot state from robot interface

  2. update robot state with state estimates from state estimator

  3. get global plan message from global planner / user interface

  4. generate local plan using the global plan message

  5. compute control command to track the local plan

  6. write control command to robot

controller_manager
classmethod useWithDefaults(robot_interface: pyrcf.components.robot_interfaces.robot_interface_base.RobotInterface, controller: pyrcf.components.controllers.controller_base.ControllerBase, global_planner: pyrcf.components.global_planners.global_planner_base.GlobalMotionPlannerBase = None, local_planner: pyrcf.components.local_planners.LocalPlannerBase = BlindForwardingPlanner(), state_estimator: pyrcf.components.state_estimators.state_estimator_base.StateEstimatorBase = DummyStateEstimator(squawk=False), verbose: bool = True) MinimalCtrlLoop

Create a control loop default values for planners and state estimators.

Default local planner: BlindForwardingPlanner Default global planner: Try JoystickGlobalPlannerInterface; fallback KeyboardGlobalPlannerInterface Default state estimator: DummyStateEstimator

Parameters:
  • robot_interface (RobotInterface) – The robot interface to use in the loop.

  • controller (ControllerBase) – The controller to be used.

  • global_planner (GlobalMotionPlannerBase, optional) – The global planner to use. If None provided, will try to first find a joystick, and then creates a keyboard interface if joystick is not found.

  • local_planner (LocalPlannerBase, optional) – Local planner to use. Defaults to BlindForwardingPlanner.

  • state_estimator (StateEstimatorBase, optional) – State estimator to use. Defaults to DummyStateEstimator(squawk=False).

Returns:

returns a valid control loop object with planners and state estimators

automatically defined.

Return type:

MinimalCtrlLoop