Exemple #1
0
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__'])
Exemple #2
0
class Turbine:
    """ This class provides a configuration file loading for the whole turbine environment,
    plus manipulation of the active elements of the turbine (robot/rail)
    and their interacting (collision)

    Args:
        config: (TurbineConfig) configuration file object.
    """

    env = None
    config = None

    # std names for printing propouses
    std_name = {
        _PRIMARY_RAIL: "primary rail",
        _SECONDARY_RAIL: "secondary rail",
        _BLADE: "blade",
        _RUNNER_AREA: "runner area",
        _IRIS: "iris",
        _ROTOR: "rotor"
    }

    def __init__(self, config):
        self.config = config

        # Create OpenRave environment
        RaveInitialize(True, 0)
        self.env = Environment()
        self.env.Load(config.environment.load)
        self.robot = self.env.GetRobots()[0]
        self.manipulator = self.robot.GetActiveManipulator()

        ikmodel = databases.inversekinematics.InverseKinematicsModel(
            robot=self.robot, iktype=IkParameterization.Type.Transform6D)
        if not ikmodel.load():
            ikmodel.autogenerate()

        # Principal turbine elements linked to attributes
        self.bodies = self.env.GetBodies()

        try:
            self.rotor = next(body for body in self.bodies
                              if body.GetName() == _ROTOR)
        except StopIteration:
            raise XMLStructError(_ROTOR)

        try:
            self.iris = next(body for body in self.bodies
                             if body.GetName() == _IRIS)
        except StopIteration:
            raise XMLStructError(_IRIS)

        try:
            self.runner_area = next(body for body in self.bodies
                                    if body.GetName() == _RUNNER_AREA)
        except StopIteration:
            raise XMLStructError(_RUNNER_AREA)

        try:
            self.primary = next(body for body in self.bodies
                                if body.GetName() == _PRIMARY_RAIL)
        except StopIteration:
            raise XMLStructError(_PRIMARY_RAIL)

        try:
            self.secondary = next(body for body in self.bodies
                                  if body.GetName() == _SECONDARY_RAIL)
        except StopIteration:
            raise XMLStructError(_SECONDARY_RAIL)

        blade_number = 1
        try:
            self.blades = [
                next(body for body in self.bodies
                     if body.GetName() == _BLADE + str(blade_number))
            ]
        except StopIteration:
            raise XMLStructError(_BLADE + str(blade_number))

        blade_found = True
        while blade_found:
            blade_number += 1
            try:
                self.blades.append(
                    next(body for body in self.bodies
                         if body.GetName() == _BLADE + str(blade_number)))
            except StopIteration:
                blade_found = False

    def place_rail(self, rail_place):
        """ Place both rails in the environment
        Args:
            rail_place: (RailPlace) rail object.
        """

        # P - primary rail,
        # S - secondary rail,
        # alpha - angle from the perpendicular to the primary rail
        # Using camera standard axis and transformLookat for rails

        # Primary Rail

        primary_extent = self.primary.GetLinks()[0].GetGeometries(
        )[0].GetBoxExtents()
        primary_offset = array([
            0, -primary_extent[1], -primary_extent[2]
        ]) + array([0, 0, self.config.environment.primary_safe_margin])
        primary_offset_transform = eye(4)
        primary_offset_transform[0:3, 3] = primary_offset

        # Secondary Rail
        secondary_extent = self.secondary.GetLinks()[0].GetGeometries(
        )[0].GetBoxExtents()
        # Resizing
        secondary_extent[2] = abs(
            rail_place.s) / 2.0 + self.config.environment.secondary_safe_margin
        self.env.Remove(self.secondary)
        self.secondary.InitFromBoxes(
            array([concatenate([zeros(3), secondary_extent])]), True)
        self.env.AddKinBody(self.secondary)
        #
        secondary_offset = array(
            [0, -secondary_extent[1], secondary_extent[2]]) + array([
                0, self.config.environment.robot_level_difference,
                -self.config.environment.secondary_safe_margin
            ])
        secondary_offset_transform = eye(4)
        secondary_offset_transform[0:3, 3] = secondary_offset

        # Rails Traonsform and Placement
        primary_transform = transformLookat(
            array([0, 0, self.config.environment.z_floor_level]),
            array([rail_place.p, 0, self.config.environment.z_floor_level]),
            [0, 0, 1])
        self.primary.SetTransform(
            dot(primary_transform, primary_offset_transform))

        secondary_transform = transformLookat(
            rail_place.getXYZ(self.config),
            array([rail_place.p, 0, self.config.environment.z_floor_level]),
            [0, 0, 1])
        self.secondary.SetTransform(
            dot(secondary_transform, secondary_offset_transform))

    def check_rail_collision(self):
        """ Check rail <-> blades collision """
        with self.env:
            collisions = [
                self.env.CheckCollision(self.primary, blade)
                or self.env.CheckCollision(self.secondary, blade)
                for blade in self.blades
            ]
        return any(collisions)

    def place_robot(self, rail_place):
        """ Place robot on the end of the secondary rail """
        T = rail_place.getTransform(self.config)
        self.robot.SetTransform(T)

    def check_robotbase_collision(self):
        """ Check robot's base <-> environment collision """
        with self.robot:
            for link in self.robot.GetLinks():
                link.Enable(False)
            self.robot.GetLink('Base').Enable(True)
            self.robot.GetLink('Arm0').Enable(True)
            with self.env:
                collision_base = [(self.env.CheckCollision(self.robot, body)
                                   and not (body == self.robot))
                                  for body in self.bodies]

            collisions = collision_base

        return any(collisions)

    def check_robot_collision(self):
        """ Check robot <-> environment collision """
        collisions = [(self.env.CheckCollision(self.robot, body)
                       and not (body == self.robot)) for body in self.bodies]
        return any(collisions)