Source code for irsim.lib.handler.kinematics_handler

import numpy as np
from abc import ABC, abstractmethod
from irsim.lib.algorithm.kinematics import (
    differential_kinematics,
    ackermann_kinematics,
    omni_kinematics,
)


[docs] class KinematicsHandler(ABC): """ Abstract base class for handling robot kinematics. """ def __init__(self, name, noise: bool = False, alpha: list = None): """ Initialize the KinematicsHandler class. Args: noise (bool): Boolean indicating whether to add noise to the velocity (default False). alpha (list): List of noise parameters for the velocity model (default [0.03, 0, 0, 0.03]). """ self.name = name self.noise = noise self.alpha = alpha or [0.03, 0, 0, 0.03]
[docs] @abstractmethod def step( self, state: np.ndarray, velocity: np.ndarray, step_time: float ) -> np.ndarray: """ Calculate the next state using the kinematics model. Args: state (np.ndarray): Current state. velocity (np.ndarray): Velocity vector. step_time (float): Time step for simulation. Returns: np.ndarray: Next state. """ pass
[docs] class OmniKinematics(KinematicsHandler): def __init__(self, name, noise, alpha): super().__init__(name, noise, alpha)
[docs] def step( self, state: np.ndarray, velocity: np.ndarray, step_time: float ) -> np.ndarray: next_position = omni_kinematics( state[0:2], velocity, step_time, self.noise, self.alpha ) next_state = np.concatenate((next_position, state[2:])) return next_state
[docs] class DifferentialKinematics(KinematicsHandler): def __init__(self, name, noise, alpha): super(DifferentialKinematics, self).__init__(name, noise, alpha)
[docs] def step( self, state: np.ndarray, velocity: np.ndarray, step_time: float ) -> np.ndarray: next_state = differential_kinematics( state, velocity, step_time, self.noise, self.alpha ) return next_state
[docs] class AckermannKinematics(KinematicsHandler): def __init__( self, name, noise: bool = False, alpha: list = None, mode: str = "steer", wheelbase: float = 1.0, ): super().__init__(name, noise, alpha) self.mode = mode self.wheelbase = wheelbase
[docs] def step( self, state: np.ndarray, velocity: np.ndarray, step_time: float ) -> np.ndarray: next_state = ackermann_kinematics( state, velocity, step_time, self.noise, self.alpha, self.mode, self.wheelbase, ) return next_state
# class Rigid3DKinematics(KinematicsHandler): # def __init__(self, name, noise, alpha): # super().__init__(name, noise, alpha) # def step(self, state: np.ndarray, velocity: np.ndarray, step_time: float) -> np.ndarray: # next_state = rigid3d_kinematics(state, velocity, step_time, self.noise, self.alpha) # return next_state
[docs] class KinematicsFactory: """ Factory class to create kinematics handlers. """
[docs] @staticmethod def create_kinematics( name: str = None, noise: bool = False, alpha: list = None, mode: str = "steer", wheelbase: float = None, role: str = "robot", ) -> KinematicsHandler: name = name.lower() if name else None if name == "omni": return OmniKinematics(name, noise, alpha) elif name == "diff": return DifferentialKinematics(name, noise, alpha) elif name == "acker": return AckermannKinematics(name, noise, alpha, mode, wheelbase) # elif name == 'rigid3d': # return Rigid3DKinematics(name, noise, alpha) else: if role == "robot": print(f"Unknown kinematics type: {name}, the robot will be stationary.") else: pass return None