Skip to content

Commit

Permalink
Add activation by event
Browse files Browse the repository at this point in the history
  • Loading branch information
Huowl committed Nov 13, 2023
1 parent 383811f commit ccf5732
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 20 deletions.
4 changes: 3 additions & 1 deletion app/mcts_run_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from rostok.criterion.simulation_flags import (EventContactBuilder, EventContactTimeOutBuilder,
EventFlyingApartBuilder, EventGraspBuilder,
EventSlipOutBuilder, EventStopExternalForceBuilder)
from rostok.criterion.simulation_flags import EventContact
from rostok.simulation_chrono.simulation_scenario import GraspScenario
from rostok.trajectory_optimizer.control_optimizer import BruteForceOptimisation1D, ConstTorqueOptiVar, GlobalOptimisationEachSim, TendonForceOptiVar
from rostok.utils.numeric_utils import Offset
Expand Down Expand Up @@ -92,7 +93,8 @@ def config_independent_torque(grasp_object_blueprint):

def config_tendon(grasp_object_blueprint):
obj_forces = []
obj_forces.append(f_ext.RandomForces(1e6, 100, 20))
obj_forces.append(f_ext.RandomForces(1e6, 100, 0))
obj_forces[-1].set_activation_by_event(EventContact)
obj_forces.append(f_ext.NullGravity(0))
obj_forces = f_ext.ExternalForces(obj_forces)
simulation_manager = GraspScenario(hp.TIME_STEP_SIMULATION, hp.TIME_SIMULATION, TendonController_2p, obj_external_forces=obj_forces)
Expand Down
49 changes: 33 additions & 16 deletions rostok/control_chrono/external_force.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from abc import ABC, abstractmethod
from dataclasses import dataclass
import numpy as np
from typing import Any, Callable, List
from typing import Any, Callable, List, Optional

import pychrono.core as chrono

from rostok.criterion.simulation_flags import SimulationSingleEvent


def random_3d_vector(amp):
"""Sample random 3d vector with given amplitude (uniform distribution on sphere)
Expand Down Expand Up @@ -73,10 +75,24 @@ def __init__(self,
self.name = name
self.pos = pos
self.start_time = start_time
self.start_event = None

@abstractmethod
def calculate_spatial_force(self, time, data) -> np.ndarray:
def calculate_spatial_force(self, time, data, events) -> np.ndarray:
return np.zeros(6)

def set_activation_by_event(self, event: type[SimulationSingleEvent], use_time: bool = False):
self.start_event = event
self.start_time = self.start_time if use_time else np.inf

def check_activation_force(self, time, events) -> bool:
time_activation = time >= self.start_time
event_activation = False
for ev in events:
if self.start_event is not None and isinstance(ev, self.start_event):
event_activation = ev.state

return time_activation or event_activation

def enable_data_dump(self, path):
self.path = path
Expand All @@ -92,7 +108,7 @@ class ForceChronoWrapper():
which determines the force and torque at time t.
"""

def __init__(self, force: ABCForceCalculator, is_local: bool = False) -> None:
def __init__(self, force: ABCForceCalculator, events: Optional[list[SimulationSingleEvent]] = None, is_local: bool = False) -> None:
self.path = None
self.force = force

Expand All @@ -116,11 +132,12 @@ def __init__(self, force: ABCForceCalculator, is_local: bool = False) -> None:
self.torque_maker_chrono.SetNameString(name + "_torque")
self.is_bound = False
self.is_local = is_local
self.events = events
self.setup_makers()

def get_force_torque(self, time: float, data) -> ForceTorque:
impact = ForceTorque()
spatial_force = self.force.calculate_spatial_force(time, data)
spatial_force = self.force.calculate_spatial_force(time, data, self.events)
impact.force = tuple(spatial_force[3:])
impact.torque = tuple(spatial_force[:3])
return impact
Expand Down Expand Up @@ -188,7 +205,7 @@ def __init__(self,
super().__init__(name, start_time, pos)
self.callback = callback

def calculate_spatial_force(self, time, data) -> np.ndarray:
def calculate_spatial_force(self, time, data, events) -> np.ndarray:
return self.callback(time, data)


Expand All @@ -213,9 +230,9 @@ def __init__(self,
self.amp_offset = amp_offset
self.freq = freq

def calculate_spatial_force(self, time, data) -> np.ndarray:
def calculate_spatial_force(self, time, data, events) -> np.ndarray:
spatial_force = np.zeros(6)
if time >= self.start_time:
if self.check_activation_force(time, events):
spatial_force[4] = self.amp * np.sin(self.freq *
(time - self.start_time)) + self.amp_offset
return spatial_force
Expand All @@ -232,9 +249,9 @@ def __init__(self, start_time: float = 0.0) -> None:
"""
super().__init__(name="null_gravity_force", start_time=start_time, pos=np.zeros(3))

def calculate_spatial_force(self, time: float, data) -> np.ndarray:
def calculate_spatial_force(self, time: float, data, events) -> np.ndarray:
spatial_force = np.zeros(6)
if time >= self.start_time:
if self.check_activation_force(time, events):
mass = data.body_map_ordered[0].body.GetMass()
g = data.grav_acc
spatial_force[3:] = -mass * g
Expand Down Expand Up @@ -266,9 +283,9 @@ def __init__(self,
self.counter = 0
self.spatial_force = np.zeros(6)

def calculate_spatial_force(self, time: float, data) -> np.ndarray:
def calculate_spatial_force(self, time: float, data, events) -> np.ndarray:

if time >= self.start_time:
if self.check_activation_force(time, events):
if self.counter % self.width_step == 0:
if self.dim == '2d':
self.spatial_force[3:] = random_plane_vector(self.amp, *self.angle)
Expand Down Expand Up @@ -303,9 +320,9 @@ def __init__(self,
self.angle: float = 0.0
self.angle_step: float = angle_step

def calculate_spatial_force(self, time: float, data) -> np.ndarray:
def calculate_spatial_force(self, time: float, data, events) -> np.ndarray:
spatial_force = np.zeros(6)
if time >= self.start_time:
if self.check_activation_force(time, events):
if self.counter % self.width_step == 0:
self.angle += self.angle_step
self.counter += 1
Expand Down Expand Up @@ -337,12 +354,12 @@ def add_force(self, force: ABCForceCalculator):
else:
self.force_controller = [self.force_controller, force]

def calculate_spatial_force(self, time: float, data) -> ForceTorque:
def calculate_spatial_force(self, time: float, data, events) -> ForceTorque:
if isinstance(self.force_controller, list):
v_forces = np.zeros(6)
for controller in self.force_controller:
v_forces += np.array(controller.calculate_spatial_force(time, data))
v_forces += np.array(controller.calculate_spatial_force(time, data, events))
self.data_forces.append(v_forces)
return v_forces
else:
return self.force_controller.calculate_spatial_force(time, data)
return self.force_controller.calculate_spatial_force(time, data, events)
4 changes: 2 additions & 2 deletions rostok/control_chrono/tendon_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ForceType(Enum):

class PulleyForce(ABCForceCalculator):

def calculate_spatial_force(self, time: float, data) -> np.ndarray:
def calculate_spatial_force(self, time: float, data, events) -> np.ndarray:
spatial_force = np.zeros(6)
pre_point = data[0]
point = data[1]
Expand All @@ -43,7 +43,7 @@ def calculate_spatial_force(self, time: float, data) -> np.ndarray:

class TipForce(ABCForceCalculator):

def calculate_spatial_force(self, time: float, data) -> np.ndarray:
def calculate_spatial_force(self, time: float, data, events) -> np.ndarray:
spatial_force = np.zeros(6)
pre_point = data[0]
point = data[1]
Expand Down
2 changes: 1 addition & 1 deletion rostok/simulation_chrono/simulation_scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def run_simulation(self,
set_covering_ellipsoid_based_position(grasp_object,
reference_point=chrono.ChVectorD(0, 0.1, 0))
if self.obj_external_forces:
chrono_forces = ForceChronoWrapper(deepcopy(self.obj_external_forces))
chrono_forces = ForceChronoWrapper(deepcopy(self.obj_external_forces), event_list)
else:
chrono_forces = None
simulation.env_creator.add_object(grasp_object,
Expand Down

0 comments on commit ccf5732

Please sign in to comment.