:py:mod:`multirotor.helpers` ============================ .. py:module:: multirotor.helpers Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: multirotor.helpers.DataLog Functions ~~~~~~~~~ .. autoapisummary:: multirotor.helpers.moment_of_inertia_tensor_from_cooords multirotor.helpers.vehicle_params_factory multirotor.helpers.find_nominal_speed multirotor.helpers.learn_thrust_coefficient multirotor.helpers.learn_speed_voltage_scaling multirotor.helpers.moment_of_inertia_disk multirotor.helpers.control_allocation_matrix multirotor.helpers.get_vehicle_ability .. py:function:: moment_of_inertia_tensor_from_cooords(point_masses: Iterable[float], coords: Iterable[numpy.ndarray]) -> numpy.ndarray Calculate the inertial matrix given a distribution of point masses. Parameters ---------- point_masses : Iterable[float] A list of masses. coords : Iterable[np.ndarray] The corresponding coordinates of those masses about the center of rotation. Ideally, this would be the center of mass of the object. Returns ------- np.ndarray The 3x3 inertial matrix. .. py:function:: vehicle_params_factory(n: int, m_prop: float, d_prop: float, params: multirotor.vehicle.PropellerParams, m_body: float, body_shape: str = 'sphere_solid', body_size: float = 0.1) -> multirotor.vehicle.VehicleParams Create a simple multirotor vehicle parameters object. The multirotor has evenly spaced propellers and a simple core shape (shell, cube etc.) Parameters ---------- n : int The number of arms/propellers. m_prop : float The mass of each propeller. d_prop : float The distance of each propeller from the center of the multirotor. params : PropellerParams The parameters describing a propeller. m_body : float The mass of the central body. body_shape : str, optional The shape of the core, by default 'sphere_solid' body_size : float, optional The dimension of the core (m), by default 0.1 Returns ------- VehicleParams The parameters object. .. py:function:: find_nominal_speed(thrust_fn: Callable[[float], float], weight: float) -> float Calculate the speed a propeller must spin to balance the weight. Parameters ---------- thrust_fn : Callable[[float], float] A function taking the speed as input and outputting thrust (N). weight : float The weight to balance. Returns ------- float The speed to balance the weight. .. py:function:: learn_thrust_coefficient(thrust_fn: Callable[[float], float], domain: Tuple = (1, 10000)) -> float Assuming a quadratic relationship between thrust and propeller speed, estimate the coefficient of proportionality k_thrust, where thrust = k_thrust . speed^2 Parameters ---------- thrust_fn : Callable[[float], float] The function accepting speed and returning thrust. domain : Tuple, optional The range of speeds to try, by default (1, 10000) Returns ------- float The thrust coefficient. .. py:function:: learn_speed_voltage_scaling(speed_fn: Callable[[float], float], domain: Tuple = (0, 20)) -> float Assuming a linear relationship between voltage and motor speed, learn the scaling coefficient, k_scaling, where: voltage = k_scaling * speed This can be put in `MotorParams.speed_voltage_scaling` so the speeds generated by the control allocation matrix are converted to corresponding voltages. Parameters ---------- speed_fn : Callable[[float], float] A function accepting voltage and returning speed. This should be the nominal case for a `Motor` class which has `speed_voltage_scaling==1`. domain : Tuple, optional The range of voltages to try to learn the coefficient, by default (0,20) Returns ------- float The scaling coefficient. .. py:function:: moment_of_inertia_disk(m: float, r: float) -> float .. py:function:: control_allocation_matrix(params: multirotor.vehicle.VehicleParams) -> Tuple[numpy.ndarray, numpy.ndarray] Calculate the control allocation matrix such that: action = matrix @ [thrust, torque_x, torque_y, torque_z] Parameters ---------- params : VehicleParams The vehicle parameters for which to compute the matrix Returns ------- Tuple[np.ndarray, np.ndarray] The allocation matrix and its inverse. If no inverse exists, returns the Moore-Penrose Pseudo-inverse. .. py:function:: get_vehicle_ability(vp: multirotor.vehicle.VehicleParams, sp: multirotor.vehicle.SimulationParams, max_tilt: float = np.pi / 12, max_rads: float = 600) .. py:class:: DataLog(vehicle: Multirotor = None, controller: Controller = None, other_vars=None) Records state and action variables for a multirotor and controller for each simulation step. .. py:property:: t .. py:property:: position .. py:property:: x .. py:property:: y .. py:property:: z .. py:property:: velocity .. py:property:: orientation .. py:property:: roll .. py:property:: pitch .. py:property:: yaw .. py:property:: angular_rate .. py:method:: __bool__() .. py:method:: track(vehicle, controller, other_vars=None) Register Multirotor and Controller instances to track, along with names of any other variables to be manually added. >>> DataLog.track(Multirotor(), Controller(), other_vars=('error',)) Parameters ---------- vehicle : Multirotor The vehicle to track. controller : Controller The controller to track. .. py:method:: __getitem__(item) .. py:method:: log(**kwargs) Add the state and action variables from the Multirotor and Controller. Any keyword arguments should already have been registered in `track()` and their values are now appended to the list. >>> DataLog.log(error=5) .. py:method:: done_logging() Indicate that no more logs are going to be put so the python lists are converted to numpy arrays and discarded. .. py:method:: append(log: DataLog, relative=True) .. py:method:: _make_arrays(relative_to=None) Convert python list to array and put up a flag that all arrays are up to date. If there was no controller, then `actions` remains `None`. .. py:method:: __len__()