class ProblemEnvironment: def __init__(self, problem_idx): np.random.seed(problem_idx) random.seed(problem_idx) self.env = Environment() collisionChecker = openravepy.RaveCreateCollisionChecker( self.env, 'fcl_') self.env.SetCollisionChecker(collisionChecker) self.problem_idx = problem_idx self.initial_placements = [] self.placements = [] self.robot = None self.objects = None self.curr_state = None self.curr_obj = None self.init_saver = None self.init_which_opreator = None self.v = False self.robot_region = None self.obj_region = None self.objs_to_move = None self.problem_config = None self.init_objs_to_move = None self.optimal_score = None self.name = None self.is_solving_packing = False self.is_solving_namo = False self.is_solving_fetching = False self.high_level_planner = None self.namo_planner = None self.fetch_planner = None self.env.StopSimulation() # openrave crashes with physics engine on self.motion_planner = None def set_body_poses(self, poses): for body_name, body_pose in zip(poses.keys(), poses.values()): utils.set_obj_xytheta(body_pose, self.env.GetKinBody(body_name)) def set_motion_planner(self, motion_planner): self.motion_planner = motion_planner def make_config_from_op_instance(self, op_instance): if op_instance['operator'].find('one_arm') != -1: g_config = op_instance['action']['g_config'] base_pose = op_instance['action']['base_pose'] config = np.hstack([g_config, base_pose.squeeze()]) else: config = op_instance['action']['base_pose'] return config.squeeze() def reset_to_init_state_stripstream(self): # todo check if this works self.init_saver.Restore() self.robot.SetActiveDOFs([], DOFAffine.X | DOFAffine.Y | DOFAffine.RotationAxis, [0, 0, 1]) def enable_movable_objects(self): for obj in self.objects: obj.Enable(True) def disable_movable_objects(self): if len(self.robot.GetGrabbed()) > 0: held_obj = self.robot.GetGrabbed()[0] else: held_obj = None for obj in self.objects: if obj == held_obj: continue obj.Enable(False) def get_curr_object(self): return self.curr_obj def get_placements(self): return copy.deepcopy(self.placements) def get_state(self): return 1 def is_pick_time(self): return len(self.robot.GetGrabbed()) == 0 def check_action_feasible(self, action, do_check_reachability=True, region_name=None): action = action.reshape((1, action.shape[-1])) place_robot_pose = action[0, 0:3] if not self.is_collision_at_base_pose(place_robot_pose): if do_check_reachability: # define the region to stay in? path, status = self.check_reachability(place_robot_pose, region_name) if status == "HasSolution": return path, True else: return None, False else: return None, True else: return None, False def is_collision_at_base_pose(self, base_pose, obj=None): robot = self.robot env = self.env if obj is None: obj_holding = self.curr_obj else: obj_holding = obj with robot: set_robot_config(base_pose, robot) in_collision = check_collision_except(obj_holding, env) if in_collision: return True return False def is_in_region_at_base_pose(self, base_pose, obj, robot_region, obj_region): robot = self.robot if obj is None: obj_holding = self.curr_obj else: obj_holding = obj with robot: set_robot_config(base_pose, robot) in_region = (robot_region.contains(robot.ComputeAABB())) and \ (obj_region.contains(obj_holding.ComputeAABB())) return in_region def apply_operator_instance(self, plan, check_feasibility=True): raise NotImplementedError def get_region_containing(self, obj): containing_regions = [] for r in self.regions.values(): if r.name == 'entire_region': continue if r.contains(obj.ComputeAABB()): containing_regions.append(r) if len(containing_regions) == 0: return None elif len(containing_regions) == 1: return containing_regions[0] else: region_with_smallest_area = containing_regions[0] for r in containing_regions: if r.area() < region_with_smallest_area.area(): region_with_smallest_area = r return region_with_smallest_area def apply_pick_constraint(self, obj_name, pick_config, pick_base_pose=None): # todo I think this function can be removed? obj = self.env.GetKinBody(obj_name) if pick_base_pose is not None: set_robot_config(pick_base_pose, self.robot) self.robot.SetDOFValues(pick_config) grab_obj(self.robot, obj) def is_region_contains_all_objects(self, region, objects): return np.all([region.contains(obj.ComputeAABB()) for obj in objects]) def get_objs_in_collision(self, path, region_name): if path is None: return [] if len(path) == 0: return [] if not isinstance(path, list): path = [path] if len(path[0]) == 3: self.robot.SetActiveDOFs([], DOFAffine.X | DOFAffine.Y | DOFAffine.RotationAxis, [0, 0, 1]) elif len(path[0]) == 11: manip = self.robot.GetManipulator('rightarm_torso') self.robot.SetActiveDOFs( manip.GetArmIndices(), DOFAffine.X | DOFAffine.Y | DOFAffine.RotationAxis, [0, 0, 1]) assert len(path[0]) == self.robot.GetActiveDOF( ), 'Robot active dof should match the path' objs = self.get_objs_in_region(region_name) in_collision = [] with self.robot: for conf in path: set_active_config(conf, self.robot) if self.env.CheckCollision(self.robot): for obj in objs: if self.env.CheckCollision( self.robot, obj) and obj not in in_collision: in_collision.append(obj) return in_collision def disable_objects_in_region(self, region_name): raise NotImplementedError def enable_objects_in_region(self, region_name): raise NotImplementedError def get_applicable_ops(self): raise NotImplementedError def apply_pick_action(self, action, obj=None): raise NotImplementedError def update_next_obj_to_pick(self, place_action): raise NotImplementedError def apply_place_action(self, action, do_check_reachability=True): raise NotImplementedError def remove_all_obstacles(self): raise NotImplementedError def is_goal_reached(self): raise NotImplementedError def set_init_state(self, saver): raise NotImplementedError def replay_plan(self, plan): raise NotImplementedError def which_operator(self, obj): raise NotImplementedError def restore(self, state_saver): raise NotImplementedError
class DistanceFieldManagerTest(TestCase): def setUp(self): from prpy.planning.chomp import DistanceFieldManager from openravepy import Environment self.env = Environment() self.env.Load('data/wamtest2.env.xml') self.robot = self.env.GetRobot('BarrettWAM') self.body = self.env.GetKinBody('mug-table') self.bodies = set(self.env.GetBodies()) self.module = CHOMPModuleMock(self.env) self.manager = DistanceFieldManager(self.module) def test_GetGeometricState_ChangeEnabledStatusChangesState(self): with self.env: link = self.robot.GetLinks()[0] link.Enable(True) state_before = self.manager.get_geometric_state(self.robot) link.Enable(False) state_after = self.manager.get_geometric_state(self.robot) self.assertNotEquals(state_after, state_before) def test_GetGeometricState_ChangeInDOFValuesChangesState(self): with self.env: lower_limits, upper_limits = self.robot.GetDOFLimits() self.robot.SetDOFValues(lower_limits) state_before = self.manager.get_geometric_state(self.robot) self.robot.SetDOFValues(upper_limits) state_after = self.manager.get_geometric_state(self.robot) self.assertNotEquals(state_after, state_before) def test_GetGeometricState_ChangeInKinematicsGeometryHashChangesState(self): self.robot.GetKinematicsGeometryHash = lambda: 'mock_before' state_before = self.manager.get_geometric_state(self.robot) self.robot.GetKinematicsGeometryHash = lambda: 'mock_after' state_after = self.manager.get_geometric_state(self.robot) self.assertNotEquals(state_after, state_before) def test_GetCachePath_DifferentStatesProduceDifferentPaths(self): self.robot.GetKinematicsGeometryHash = lambda: 'mock_before' state_before = self.manager.get_geometric_state(self.robot) path_before = self.manager.get_cache_path(state_before) self.robot.GetKinematicsGeometryHash = lambda: 'mock_after' state_after = self.manager.get_geometric_state(self.robot) path_after = self.manager.get_cache_path(state_after) self.assertNotEquals(path_after, path_before) def test_Sync_InitiallyCreatesAllDistanceFields(self): self.manager.sync(self.robot) computed_bodies = [ args['kinbody'] for args in self.module.computedistancefield_args ] self.assertItemsEqual(self.bodies, computed_bodies) self.assertEqual(len(self.module.removefield_args), 0) def test_Sync_SyncTwiceDoesNothing(self): self.manager.sync(self.robot) del self.module.computedistancefield_args[:] del self.module.removefield_args[:] self.manager.sync(self.robot) self.assertEqual(len(self.module.computedistancefield_args), 0) self.assertEqual(len(self.module.removefield_args), 0) def test_Sync_IgnoresActiveRobotLinks(self): self.is_processed = False def computedistancefield(kinbody=None, cube_extent=None, aabb_padding=None, cache_filename=None, releasegil=False, **kw_args): if kinbody.GetName() == self.robot.GetName(): self.assertTrue(self.robot.GetLink('segway').IsEnabled()) self.assertTrue(self.robot.GetLink('wam0').IsEnabled()) self.assertTrue(self.robot.GetLink('wam1').IsEnabled()) self.assertTrue(self.robot.GetLink('wam2').IsEnabled()) self.assertTrue(self.robot.GetLink('wam3').IsEnabled()) self.assertFalse(self.robot.GetLink('wam4').IsEnabled()) self.assertFalse(self.robot.GetLink('wam5').IsEnabled()) self.assertFalse(self.robot.GetLink('wam6').IsEnabled()) self.assertFalse(self.robot.GetLink('wam7').IsEnabled()) self.assertFalse(self.robot.GetLink('handbase').IsEnabled()) self.assertFalse(self.robot.GetLink('Finger0-0').IsEnabled()) self.assertFalse(self.robot.GetLink('Finger0-1').IsEnabled()) self.assertFalse(self.robot.GetLink('Finger0-2').IsEnabled()) self.assertFalse(self.robot.GetLink('Finger1-0').IsEnabled()) self.assertFalse(self.robot.GetLink('Finger1-1').IsEnabled()) self.assertFalse(self.robot.GetLink('Finger1-2').IsEnabled()) self.assertFalse(self.robot.GetLink('Finger2-1').IsEnabled()) self.assertFalse(self.robot.GetLink('Finger2-2').IsEnabled()) self.is_processed = True dof_index = self.robot.GetJoint('Elbow').GetDOFIndex() self.robot.SetActiveDOFs([ dof_index ]) self.robot.Enable(True) self.module.computedistancefield = computedistancefield self.manager.sync(self.robot) self.assertTrue(self.is_processed) def test_Sync_RecomputesDistanceFieldIfStateChanges(self): self.manager.sync(self.robot) del self.module.computedistancefield_args[:] del self.module.removefield_args[:] # Change the geometry to invalidate the key. link = self.robot.GetLink('segway') link.SetGroupGeometries('test', []) link.SetGeometriesFromGroup('test') self.manager.sync(self.robot) self.assertEqual(len(self.module.computedistancefield_args), 1) self.assertEqual(self.module.computedistancefield_args[0]['kinbody'], self.robot) self.assertEqual(len(self.module.removefield_args), 1) self.assertEqual(self.module.removefield_args[0]['kinbody'], self.robot) self.assertLess(self.module.removefield_args[0]['__sequence__'], self.module.computedistancefield_args[0]['__sequence__'])