pyrcf.components.agents ======================= .. py:module:: pyrcf.components.agents .. autoapi-nested-parse:: Defines agents that can be used to compute control commands to be sent to a robot given a global plan (target/task). When using 'classical' methods, an agent may just be a local planner + a controller (use the PlannerControllerAgent in this case). When using machine-learned controller, this could be a policy that direcly uses the global plan and outputs a robot command (implement an agent from MLAgentBase). Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/pyrcf/components/agents/agent_base/index /autoapi/pyrcf/components/agents/ml_agent_base/index /autoapi/pyrcf/components/agents/planner_controller_agent/index /autoapi/pyrcf/components/agents/torchscript_agent_base/index Classes ------- .. autoapisummary:: pyrcf.components.agents.AgentBase pyrcf.components.agents.DummyAgent pyrcf.components.agents.PlannerControllerAgent pyrcf.components.agents.MLAgentBase pyrcf.components.agents.TorchScriptAgentBase Package Contents ---------------- .. py:class:: AgentBase Bases: :py:obj:`pyrcf.components.pyrcf_component.PyRCFComponent` An agent is an entity that observes the state of the robot and responds with a control action. With this in mind, an agent for classical control cases would be an entity that combines the functions of a 'local planner' and 'controller' into a single entity called 'Agent', which observes the state of the robot interface and responds by sending commands to the robot, so as to follow the objective of following the 'global plan' from the global planner. .. py:method:: get_action(robot_state: pyrcf.core.types.RobotState, global_plan: pyrcf.core.types.GlobalMotionPlan, t: float, dt: float) -> pyrcf.core.types.RobotCmd :abstractmethod: Compute the control command to be executed given the current state and the global plan. :param robot_state: Current robot state. This is equivalent to 'observation' in standard learning-based agents. :type robot_state: RobotState :param global_plan: The reference global plan to follow. :type global_plan: GlobalMotionPlan :param t: the current time signature of the control loop. Defaults to None (controllers may or may not need this). :type t: float, optional :param dt: the time since the last control loop. Defaults to None (controllers may or may not need this). :type dt: float, optional :returns: The output control command (action) to be sent to the robot. :rtype: RobotCmd :raises NotImplementedError: Raised if this method is not implemented by the child class. .. py:method:: get_last_output() -> Tuple[pyrcf.core.types.LocalMotionPlan, pyrcf.core.types.RobotCmd] :abstractmethod: Should return the last computed outputs by this agent. :returns: Output local plan and control command from this agent. NOTE: Either of these can be None, if the agent does not compute them. :rtype: Tuple[LocalMotionPlan, RobotCmd] .. py:class:: DummyAgent(squawk: bool = True) Bases: :py:obj:`AgentBase` Dummy Agent for testing pipeline. .. py:attribute:: _squawk :value: True .. py:method:: get_action(robot_state: pyrcf.core.types.RobotState, global_plan: pyrcf.core.types.GlobalMotionPlan, t: float, dt: float) -> pyrcf.core.types.RobotCmd This is a dummy method for sanity checking the control loop. .. py:method:: get_last_output() -> Tuple[pyrcf.core.types.LocalMotionPlan | pyrcf.core.types.RobotCmd] Should return the last computed outputs by this agent. :returns: Output local plan and control command from this agent. NOTE: Either of these can be None, if the agent does not compute them. :rtype: Tuple[LocalMotionPlan, RobotCmd] .. py:class:: PlannerControllerAgent(local_planner: pyrcf.components.local_planners.LocalPlannerBase, controller: pyrcf.components.controllers.ControllerBase) Bases: :py:obj:`pyrcf.components.agents.agent_base.AgentBase` A simple implementation of Agent using a local planner object and controller. This agent simply calls the local planner update and controller update steps in sequence. .. py:attribute:: local_planner .. py:attribute:: controller .. py:attribute:: _latest_local_plan :value: None .. py:attribute:: _latest_ctrl_cmd :value: None .. py:method:: get_action(robot_state: pyrcf.core.types.RobotState, global_plan: pyrcf.core.types.GlobalMotionPlan, t: float = None, dt: float = None) -> pyrcf.core.types.RobotCmd Compute the control command to be executed given the current state and the global plan. :param robot_state: Current robot state. This is equivalent to 'observation' in standard learning-based agents. :type robot_state: RobotState :param global_plan: The reference global plan to follow. :type global_plan: GlobalMotionPlan :param t: the current time signature of the control loop. Defaults to None (controllers may or may not need this). :type t: float, optional :param dt: the time since the last control loop. Defaults to None (controllers may or may not need this). :type dt: float, optional :returns: The output control command (action) to be sent to the robot. :rtype: RobotCmd :raises NotImplementedError: Raised if this method is not implemented by the child class. .. py:method:: get_latest_local_plan() -> pyrcf.core.types.LocalMotionPlan .. py:method:: get_latest_ctrl_cmd() -> pyrcf.core.types.RobotCmd .. py:method:: get_last_output() -> Tuple[pyrcf.core.types.LocalMotionPlan, pyrcf.core.types.RobotCmd] Should return the last computed outputs by this agent. :returns: Output local plan and control command from this agent. NOTE: Either of these can be None, if the agent does not compute them. :rtype: Tuple[LocalMotionPlan, RobotCmd] .. py:method:: shutdown() Cleanly shutdown the PyRCF component. Override in child class if required. The base class implements an empty function. .. py:method:: get_class_info() -> str Override with custom string if needed. .. py:class:: MLAgentBase Bases: :py:obj:`pyrcf.components.agents.agent_base.AgentBase`, :py:obj:`abc.ABC` An abstract base class machine-learned controller agents. See docstrings for each method to be implemented. .. py:method:: initialise_robot_cmd(joint_states: pyrcf.core.types.JointStates) :abstractmethod: Override this method in child class if custom initilisation is required (e.g. joint name order). By default, this method sets the joint name and position values to be equal to the input joint states object, with kp and kd set to be the default (in constructor). .. py:method:: update_input_to_model(robot_state: pyrcf.core.types.RobotState, global_plan: pyrcf.core.types.GlobalMotionPlan, t: float, dt: float) -> numpy.ndarray :abstractmethod: Should update (`self._input_ndarray`) using appropriate values (input to model). This method has access to `self._latest_ctrl_cmd` (type `RobotCmd`) as well if needed. (NOTE: `self._latest_ctrl_cmd` is set to be the initial robot joint positions (zero velocities and efforts commands) with `default_kp` and `default_kd` at start). .. py:method:: update_cmd_from_model_output(model_output: numpy.ndarray, robot_state: pyrcf.core.types.RobotState, global_plan: pyrcf.core.types.GlobalMotionPlan, t: float, dt: float) -> None :abstractmethod: Should update `self._latest_robot_cmd` (type `RobotCmd`) using the output from the NN model. :param model_output: the numpy array created from the output tensor from the model after the inference query was done. This is the output of the neural network. This method should use this object to update `self._latest_robot_cmd` to be sent to the robot. :type model_output: np.ndarray .. py:method:: get_action(robot_state: pyrcf.core.types.RobotState, global_plan: pyrcf.core.types.GlobalMotionPlan, t: float = None, dt: float = None) -> pyrcf.core.types.RobotCmd :abstractmethod: Should return the control command given the current robot state and global plan. :param robot_state: The current state information from the robot. :type robot_state: RobotState :param global_plan: the latest global plan generated by the global planner used in the loop. :type global_plan: GlobalMotionPlan :param t: the current time signature of the control loop. Defaults to None (controllers may or may not need this). :type t: float, optional :param dt: the time since the last control loop. Defaults to None (controllers may or may not need this). :type dt: float, optional :returns: The output control command to be sent to the robot. :rtype: RobotCmd .. py:class:: TorchScriptAgentBase(model_file: str, input_dims: int, device: Literal['cpu', 0] = 'cpu', warmup_iterations: int = 10, default_kp: numpy.ndarray | float = 20, default_kd: numpy.ndarray | float = 1.0, update_rate: float = None, clock: pyrcf.utils.time_utils.ClockBase = PythonPerfClock(), dtype: torch.dtype = None) Bases: :py:obj:`pyrcf.components.agents.ml_agent_base.MLAgentBase` A (abstract) base class that provides functionalities to use a torchscript model file and use it's inference mode to perform control update. Child class has to override two methods: - update_input_to_model - update_cmd_from_model_output See docstrings for each method in MLAgentBase class. .. py:attribute:: _torch_device .. py:attribute:: _model .. py:attribute:: _device :value: 'cpu' .. py:attribute:: _dtype :value: None .. py:attribute:: _dims .. py:attribute:: _tensor_inp .. py:attribute:: _input_ndarray The input array to be updated by the child class using the current robot state and global plan commands. This will be passed to the model as input during inference .. py:attribute:: _latest_ctrl_cmd :type: pyrcf.core.types.RobotCmd :value: None The RobotCmd object that can be use in the `update_input_to_model` method (if required) as the last sent command to the robot. This object has to be updated by the child class's `update_cmd_from_model_output` using the output from the model inference step. .. py:attribute:: _default_kp :value: 20 .. py:attribute:: _default_kd :value: 1.0 .. py:attribute:: _rate :value: None .. py:method:: _should_run() .. py:method:: initialise_robot_cmd(joint_states: pyrcf.core.types.JointStates) Override this method in child class if custom initilisation is required (e.g. joint name order). By default, this method sets the joint name and position values to be equal to the input joint states object, with kp and kd set to be the default (in constructor). .. py:method:: update_input_to_model(robot_state: pyrcf.core.types.RobotState, global_plan: pyrcf.core.types.GlobalMotionPlan, t: float, dt: float) -> numpy.ndarray :abstractmethod: Should update (`self._input_ndarray`) using appropriate values (input to model). This method has access to `self._latest_ctrl_cmd` (type `RobotCmd`) as well if needed. (NOTE: `self._latest_ctrl_cmd` is set to be the initial robot joint positions (zero velocities and efforts commands) with `default_kp` and `default_kd` at start). .. py:method:: update_cmd_from_model_output(model_output: numpy.ndarray, robot_state: pyrcf.core.types.RobotState, global_plan: pyrcf.core.types.GlobalMotionPlan, t: float, dt: float) -> None :abstractmethod: Should update `self._latest_robot_cmd` (type `RobotCmd`) using the output from the NN model. :param model_output: the numpy array created from the output tensor from the model after the inference query was done. This is the output of the neural network. This method should use this object to update `self._latest_robot_cmd` to be sent to the robot. :type model_output: np.ndarray .. py:method:: get_action(robot_state: pyrcf.core.types.RobotState, global_plan: pyrcf.core.types.GlobalMotionPlan, t: float = None, dt: float = None) -> pyrcf.core.types.RobotCmd Should return the control command given the current robot state and global plan. :param robot_state: The current state information from the robot. :type robot_state: RobotState :param global_plan: the latest global plan generated by the global planner used in the loop. :type global_plan: GlobalMotionPlan :param t: the current time signature of the control loop. Defaults to None (controllers may or may not need this). :type t: float, optional :param dt: the time since the last control loop. Defaults to None (controllers may or may not need this). :type dt: float, optional :returns: The output control command to be sent to the robot. :rtype: RobotCmd .. py:method:: get_last_output() -> Tuple[pyrcf.core.types.LocalMotionPlan, pyrcf.core.types.RobotCmd] Should return the last computed outputs by this agent. :returns: Output local plan and control command from this agent. NOTE: Either of these can be None, if the agent does not compute them. :rtype: Tuple[LocalMotionPlan, RobotCmd]