genesis.engine.entities.drone_entity 源代码

import os
import xml.etree.ElementTree as etxml

import numpy as np
import taichi as ti

import genesis as gs
import genesis.utils.misc as mu

from .rigid_entity import RigidEntity


[文档]@ti.data_oriented class DroneEntity(RigidEntity): def _load_URDF(self, morph, surface): super()._load_URDF(morph, surface) # additional drone specific attributes properties = etxml.parse(os.path.join(mu.get_assets_dir(), morph.file)).getroot()[0].attrib self._KF = float(properties["kf"]) self._KM = float(properties["km"]) self._n_propellers = len(morph.propellers_link_names) self._COM_link_idx = self.get_link(morph.COM_link_name).idx propellers_links = gs.List([self.get_link(name) for name in morph.propellers_link_names]) self._propellers_link_idxs = np.array([link.idx for link in propellers_links], dtype=gs.np_int) try: self._propellers_vgeom_idxs = np.array([link.vgeoms[0].idx for link in propellers_links], dtype=gs.np_int) self._animate_propellers = True except Exception: gs.logger.warning("No visual geometry found for propellers. Skipping propeller animation.") self._animate_propellers = False self._propellers_spin = np.array(morph.propellers_spin, dtype=gs.np_float) self._model = morph.model def _build(self): super()._build() self._propellers_revs = np.zeros(self._solver._batch_shape(self._n_propellers), dtype=gs.np_float) self._prev_prop_t = None
[文档] def set_propellels_rpm(self, propellels_rpm): if self._prev_prop_t == self.sim.cur_step_global: gs.raise_exception("`set_propellels_rpm` can only be called once per step.") self._prev_prop_t = self.sim.cur_step_global propellels_rpm = self.solver._process_dim(np.array(propellels_rpm, dtype=gs.np_float)).T if len(propellels_rpm) != len(self._propellers_link_idxs): gs.raise_exception("Last dimension of `propellels_rpm` does not match `entity.n_propellers`.") if np.any(propellels_rpm < 0): gs.raise_exception("`propellels_rpm` cannot be negative.") self._propellers_revs = (self._propellers_revs + propellels_rpm) % (60 / self.solver.dt) self.solver._kernel_set_drone_rpm( self._n_propellers, self._COM_link_idx, self._propellers_link_idxs, propellels_rpm, self._propellers_spin, self.KF, self.KM, self._model == "RACE", )
[文档] def update_propeller_vgeoms(self): if self._animate_propellers: self.solver._update_drone_propeller_vgeoms( self._n_propellers, self._propellers_vgeom_idxs, self._propellers_revs, self._propellers_spin )
@property def model(self): return self._model @property def KF(self): return self._KF @property def KM(self): return self._KM @property def n_propellers(self): return self._n_propellers @property def COM_link_idx(self): return self._COM_link_idx @property def propellers_idx(self): return self._propellers_link_idxs @property def propellers_spin(self): return self._propellers_spin