Contact#
- class genesis_forge.managers.ContactManager(env: GenesisEnv, link_names: list[str], entity_attr: RigidEntity = 'robot', with_entity_attr: RigidEntity = None, with_links_names: list[int] = None, track_air_time: bool = False, air_time_contact_threshold: float = 1.0, debug_visualizer: bool = False, debug_visualizer_cfg: ContactDebugVisualizerConfig = {'color': (0.5, 0.0, 0.0, 1.0), 'envs_idx': None, 'force_threshold': 1.0, 'size': 0.03})[source]#
Bases:
BaseManagerTracks the contact forces between entity links in the environment.
- Parameters:
env – The environment to track the contact forces for.
link_names – The names, or name regex patterns, of the entity links to track the contact forces for.
entity_attr – The environment attribute which contains the entity with the links we’re tracking. Defaults to robot.
with_entity_attr – Filter the contact forces to only include contacts with the entity assigned to this environment attribute.
with_links_names – Filter the contact forces to only include contacts with these links.
track_air_time – Whether to track the air time of the entity link contacts.
air_time_contact_threshold – When track_air_time is True, this is the threshold for the contact forces to be considered.
debug_visualizer – Whether to visualize the contact points.
debug_visualizer_cfg – The configuration for the contact debug visualizer.
Example with ManagedEnvironment:
class MyEnv(ManagedEnvironment): # ... Construct scene and other env setup ... def config(self): # Define contact manager self.foot_contact_manager = ContactManager( self, link_names=[".*_Foot"], ) # Use contact manager in rewards self.reward_manager = RewardManager( self, term_cfg={ "Foot contact": { "weight": 5.0, "fn": rewards.has_contact, "params": { "contact_manager": self.foot_contact_manager, "min_contacts": 4, }, }, }, ) # ... other managers here ...
Example using the contact manager directly:
class MyEnv(GenesisEnv): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.contact_manager = ContactManager( self, link_names=[".*_Foot"], ) def build(self): super().build() self.contact_manager.build() def step(self, actions: torch.Tensor): super().step(actions) self.contact_manager.step() return obs, rewards, terminations, timeouts, info def reset(self, envs_idx: list[int] | None = None): super().reset(envs_idx) self.contact_manager.reset(envs_idx) return obs, info def calculate_rewards(): # Reward for each foot in contact with something with at least 1.0N force CONTACT_THRESHOLD = 1.0 CONTACT_WEIGHT = 0.005 has_contact = self.contact_manager.contacts[:,:].norm(dim=-1) > CONTACT_THRESHOLD contact_reward = has_contact.sum(dim=1).float() * CONTACT_WEIGHT # Access contact positions for debugging or additional analysis contact_positions = self.contact_manager.contact_positions # contact_positions shape: (n_envs, n_target_links, 3) # Positions are automatically averaged when multiple contacts occur # ...additional reward calculations here...
Filtering:
class MyEnv(ManagedEnvironment): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.scene = gs.Scene() # Add terrain self.terrain = self.scene.add_entity(gs.morphs.Plane()) # add robot self.robot = self.scene.add_entity( gs.morphs.URDF(file="urdf/go2/urdf/go2.urdf"), ) def config(self): # Track all contacts between the robot's feet and the terrain self.contact_manager = ContactManager( self, entity_attr="robot", link_names=[".*_foot"], with_entity_attr="terrain", ) # ...other managers here... # ...other operations here...
- get_contact_forces(link_idx: int | list[int]) torch.Tensor[source]#
Get the contact forces for one or more links
- Parameters:
link_idx – The link index or list of link indices to get the contact forces for.
- Returns:
The contact forces for the target links. Shape is (n_envs, n_target_links, 3)
- has_broken_contact(dt: float, time_margin: float = 1e-08) torch.Tensor[source]#
Checks links that have broken contact within the last
dtseconds.This function checks if the links have broken contact within the last
dtseconds by comparing the current air time with the given time period. If the air time is less than the given time period, then the links are considered to not be in contact.- Parameters:
dt – The time period since the contact was broken.
time_margin – Adds a little error margin to the dt time period.
- Returns:
A boolean tensor indicating the links that have broken contact within the last
dtseconds. Shape is (n_envs, n_target_links)- Raises:
RuntimeError – If the manager is not configured to track air time.
- has_made_contact(dt: float, time_margin: float = 1e-08) torch.Tensor[source]#
Checks if links that have established contact within the last
dtseconds.This function checks if the links have established contact within the last
dtseconds by comparing the current contact time with the given time period. If the contact time is less than the given time period, then the links are considered to be in contact.- Parameters:
dt – The time period since the contact was established.
time_margin – Adds a little error margin to the dt time period.
- Returns:
A boolean tensor indicating the links that have established contact within the last
dtseconds. Shape is (n_envs, n_target_links)- Raises:
RuntimeError – If the manager is not configured to track air time.
- contact_positions: torch.Tensor | None#
Contact positions for each target link.
- contacts: torch.Tensor | None#
Contact forces experienced by the entity links.
- current_air_time: torch.Tensor | None#
Time spent (in s) in the air since the last detach.
- current_contact_time: torch.Tensor | None#
Time spent (in s) in contact since the last contact.
- last_air_time: torch.Tensor | None#
Time spent (in s) in the air before the last contact.
- last_contact_time: torch.Tensor | None#
Time spent (in s) in contact before the last detach.
- property link_ids: torch.Tensor#
The global link indices for the target links.
- property local_link_ids: torch.Tensor#
The local link indices for the target links.