def quat_from_azimuth_elevation(azimuth, elevation, angle_z=0.):
    """
    Get numpy quaternion from azimuth and elevation.
    Angle_z is rotation about z axis of the rotated gripper.
    """
    return quat_from_euler("yz", [np.math.pi / 2. + elevation, azimuth
                                  ]) * quat_from_euler("z", angle_z)
Example #2
0
 def move_target(self, d):
     target = self._target
     eye = self._pose[:3, 3].flatten()
     _, a, _ = self.cartesian_to_spherical(eye, target)
     v = npq.rotate_vectors(quat_from_euler('z', a), d)
     self._n_target += v
     self._n_pose[:3, 3] += v
Example #3
0
        def sample(env: GripperCylinderEnv):
            hpos_std = shared_sampler_dict['hpos_std']
            sa = shared_sampler_dict['angle_bound_scale']
            q = quat_from_azimuth_elevation(
                np.random.uniform(hazi_min * sa, hazi_max * sa) + np.pi / 2,
                np.random.uniform(hele_min * sa, hele_max * sa))

            ohei = np.random.uniform(ohei_min, ohei_max)
            orad = np.random.uniform(orad_min, orad_max)
            tip_pos = np.zeros(3)
            tip_pos[:2] = np.random.normal(0., hpos_std, size=2)
            tip_pos[2] = ohei / 2. + np.random.normal(0., hpos_std, size=1)
            obj_pos = np.array([0., 0., ohei / 2.])
            obj_pos[:2] += np.random.normal(0., 1e-3, size=2)
            if not env.two_objects:
                return (tip_pos, q), GripperCylinderEnv.FINGER_OPEN_POS, (
                    obj_pos, npq.one), ohei, orad

            tind = np.random.randint(0, env.demo_opos2.shape[1])
            tip_pos += env.demo_opos2[0, tind, :]
            o2pose = multiply_transformations(
                (tip_pos, q), (np.zeros(3), quat_from_euler('y', np.pi / 2)))
            o2h = np.random.uniform(ohei_min, ohei_max)
            o2rad = np.random.uniform(orad_min, orad_max)
            return (tip_pos,
                    q), o2rad, (obj_pos,
                                npq.one), ohei, orad, o2pose, o2h, o2rad
Example #4
0
    def create_hand_actors(self, use_mesh_base=True, use_mesh_fingers=True):
        panda_dir = os.path.dirname(
            os.path.abspath(__file__)) + '/franka_panda/meshes/collision'
        hand_mat = Material(static_friction=1.,
                            dynamic_friction=1.,
                            restitution=0)

        trimesh_kwargs = dict(split_object=False, group_material=False)
        convex_kwargs = dict(material=hand_mat,
                             quantized_count=64,
                             vertex_limit=64)
        if use_mesh_base:
            mesh_hand: trimesh.Trimesh = trimesh.load(
                '{}/hand.obj'.format(panda_dir), **trimesh_kwargs)
            hand_shape = Shape.create_convex_mesh_from_points(
                points=mesh_hand.vertices, **convex_kwargs)
        else:
            minp, maxp = np.array([-0.0316359, -0.10399,
                                   -0.0259248]), np.array(
                                       [0.0316158, 0.100426, 0.0659622])
            hand_shape = Shape.create_box(size=maxp - minp, material=hand_mat)
            hand_shape.set_local_pose((minp + maxp) / 2)
        if use_mesh_fingers:
            mesh_finger: trimesh.Trimesh = trimesh.load(
                '{}/finger.obj'.format(panda_dir), **trimesh_kwargs)
            finger1_shape = Shape.create_convex_mesh_from_points(
                points=mesh_finger.vertices, **convex_kwargs)
            finger2_shape = Shape.create_convex_mesh_from_points(
                points=mesh_finger.vertices, **convex_kwargs)
            finger2_shape.set_local_pose(
                (np.zeros(3), quat_from_euler('z', np.pi)))
        else:
            finger1_shape = Shape.create_box(size=[0.02, 0.02, 0.12],
                                             material=hand_mat)
            finger2_shape = Shape.create_box(size=[0.02, 0.02, 0.12],
                                             material=hand_mat)
            finger1_shape.set_local_pose([0., 0.01, 0.07])
            finger2_shape.set_local_pose([0., -0.01, 0.07])

        for s in [hand_shape, finger1_shape, finger2_shape]:
            s.set_local_pose(
                multiply_transformations((0, 0, -0.15), s.get_local_pose()))

        actors = [RigidDynamic() for _ in range(3)]
        actors[0].attach_shape(hand_shape)
        actors[1].attach_shape(finger1_shape)
        actors[2].attach_shape(finger2_shape)
        actors[0].set_mass(1000 + 0.81)
        actors[1].set_mass(0.1 + 5.)
        actors[2].set_mass(0.1 + 5.)

        actors[0].set_rigid_body_flag(RigidBodyFlag.KINEMATIC, True)

        for a in actors:
            a.disable_gravity()
            a.set_angular_damping(0.5)
            a.set_linear_damping(0.5)
            self.scene.add_actor(a)
        return actors
Example #5
0
 def set_joint_position(self, value):
     """ Set desired position of the joint. """
     value = value if value is not None else self.null_value
     if self.is_prismatic:
         self.physx_joint.set_drive_position((value, 0, 0))
     elif self.is_revolute:
         self.physx_joint.set_drive_position(
             (np.zeros(3), quat_from_euler('x', value)))
     self.commanded_joint_position = value
Example #6
0
 def joint_transformation(self, joint_position=None):
     """ Get transformation of joint. For prismatic, this is defined as translation in x-axis.
         For revolute it is rotation about x-axis. """
     if self.joint_type == 'fixed':
         return unit_pose()
     if joint_position is None:
         joint_position = self.null_value
     if self.joint_type == 'prismatic':
         return np.array([joint_position, 0, 0]), npq.one
     elif self.joint_type == 'revolute':
         return np.zeros(3), quat_from_euler('x', [joint_position])
     else:
         raise NotImplementedError(
             'Only fixed, prismatic and revolute joints are supported.')
Example #7
0
 def reset(self):
     self.iter = 0
     if self.reset_state_sampler is None:
         self.reset_hand_pose(
             pose=((0, 0, 0.05),
                   quat_from_euler('yz', [-np.pi / 2, -np.pi / 2])))
         self.obj.set_global_pose([0.0, 0.0, 0.05])
     else:
         while True:
             if self.two_objects:
                 hand_pose, grip, obj_pose, self.obj_height, self.obj_radius, obj2_pose, self.obj2_height, self.obj2_radius = self.reset_state_sampler(
                     self)
                 for s in self.obj2.get_atached_shapes():
                     self.obj2.detach_shape(s)
                 self.obj2.attach_shape(
                     self.create_cylinder(self.obj2_height,
                                          self.obj2_radius))
                 self.obj2.set_global_pose(obj2_pose)
             else:
                 hand_pose, grip, obj_pose, self.obj_height, self.obj_radius = self.reset_state_sampler(
                     self)
             [
                 self.obj.detach_shape(s)
                 for s in self.obj.get_atached_shapes()
             ]
             self.obj.attach_shape(
                 self.create_cylinder(self.obj_height, self.obj_radius))
             self.reset_hand_pose(hand_pose, grip)
             self.obj.set_global_pose(obj_pose)
             if not self.hand_plane_hit() and not self.hand_obj_hit():
                 break
             # else:
             #     print('reset collision detected: hand/plane: {},  hand/obj: {}'.format(self.hand_plane_hit(),
             #                                                                            self.hand_obj_hit()))
             #     print('Sample:', hand_pose, grip, obj_pose, self.obj_height, self.obj_radius)
     self.plane_mat.set_static_friction(np.random.uniform(0., 0.05))
     self.plane_mat.set_dynamic_friction(np.random.uniform(0., 0.05))
     self.scene.simulation_time = 0.
     return self.get_obs()
    env.obj_height = data[i, 8]
    env.obj_radius = data[i, 9]
    [env.obj.detach_shape(s) for s in env.obj.get_atached_shapes()]
    env.obj.attach_shape(env.create_cylinder(env.obj_height, env.obj_radius))
    env.reset_hand_pose((hpos, hq), env.FINGER_OPEN_POS)
    env.obj.set_global_pose(obj_pose)

    env.obj2_height = data[i, 10]
    env.obj2_radius = data[i, 11]
    [env.obj2.detach_shape(s) for s in env.obj2.get_atached_shapes()]
    env.obj2.attach_shape(env.create_cylinder(env.obj2_height,
                                              env.obj2_radius))
    env.obj.set_global_pose(obj_pose)
    o1pose = multiply_transformations(
        (hpos, hq), (np.zeros(3), quat_from_euler('y', np.pi / 2)))
    env.obj2.set_global_pose(o1pose)

    valid[i] = not env.hand_plane_hit() and not env.hand_obj_hit(
    ) and not env.obj2_plane_hit()
    env.reset_hand_pose((hpos, hq), env.obj2_radius)
    valid[i] &= not env.hand_plane_hit() and not env.hand_obj_hit()

    print(sum(valid))
    if int(sum(valid)) == 1000:
        break

print(sum(valid))

df = pd.DataFrame(data=data[valid],
                  columns=[
Example #9
0
    def step(self, action):
        self.iter += 1
        """ Step in pyphysx. """
        dt = self.control_frequency.period() / self.num_sub_steps
        dpose = (0.3 * np.tanh(action[:3]) * dt,
                 quat_from_euler('xyz',
                                 np.pi * np.tanh(action[3:6]) * dt))
        if self.open_gripper_on_leave and self.scene.simulation_time > self.action_end_time:
            self.set_grip(self.FINGER_OPEN_POS)
        elif self.close_gripper_on_leave and self.scene.simulation_time > self.action_end_time:
            self.set_grip(0.)
        else:
            grip = np.tanh(action[
                6]) * self.FINGER_OPEN_POS / 2 + self.FINGER_OPEN_POS / 2
            # grip = 0.04 if grip < 0.05 else self.FINGER_OPEN_POS
            self.set_grip(grip)
        pose = self.hand_actors[0].get_global_pose()
        for _ in range(self.num_sub_steps):
            pose = multiply_transformations(dpose, pose)
            self.hand_actors[0].set_kinematic_target(pose)
            self.scene.simulate(dt)

        if self.render:
            if self.iter == 1:
                self.renderer.clear_physx_scenes()
                self.renderer.add_physx_scene(self.scene)
            self.renderer.update()
            # self.renderer.render_scene(self.scene, recompute_actors=self.iter == 1)

        if self.realtime:
            self.control_frequency.sleep()
        """ Compute rewards """
        hp, hq = self.hand_actors[0].get_global_pose()
        op, oq = self.obj.get_global_pose()
        grip = self.get_grip()
        hrot = azimuth_elevation_from_quat(hq)

        hp[2] -= 0.5 * self.obj_height
        op[2] -= 0.5 * self.obj_height

        traj_rewards = np.zeros(self.demo_hpos.shape[1])
        b, s = self.reward_params['demo_hand_pos']['b'], self.reward_params[
            'demo_hand_pos']['scale']
        traj_rewards += s * np.exp(-0.5 * np.sum(
            (self.demo_hpos[self.iter] - hp)**2, axis=-1) * b)
        b, s = self.reward_params['demo_obj_pos']['b'], self.reward_params[
            'demo_obj_pos']['scale']
        traj_rewards += s * np.exp(-0.5 * np.sum(
            (self.demo_opos[self.iter] - op)**2, axis=-1) * b)
        b, s = self.reward_params['demo_hand_azi_ele'][
            'b'], self.reward_params['demo_hand_azi_ele']['scale']
        traj_rewards += s * np.exp(-0.5 * np.sum(
            (self.demo_hrot[self.iter] - hrot)**2, axis=-1) * b)
        b, s = self.reward_params['demo_obj_rot']['b'], self.reward_params[
            'demo_obj_rot']['scale']
        traj_rewards += s * np.exp(-0.5 * npq.rotation_intrinsic_distance(
            self.demo_orot[self.iter], oq) * b)
        b, s = self.reward_params['demo_touch']['b'], self.reward_params[
            'demo_touch']['scale']
        traj_rewards += s * self.demo_grip_weak_closed[self.iter] * np.exp(
            -0.5 * b * (grip - (self.obj_radius - 0.005))**2)

        if self.two_objects:
            op2, oq2 = self.obj2.get_global_pose()
            op2[2] -= 0.5 * self.obj2_height
            b, s = self.reward_params['demo_obj_pos']['b'], self.reward_params[
                'demo_obj_pos']['scale']
            traj_rewards += s * np.exp(-0.5 * np.sum(
                (self.demo_opos2[self.iter] - op2)**2, axis=-1) * b)
            b, s = self.reward_params['demo_obj_rot']['b'], self.reward_params[
                'demo_obj_rot']['scale']
            traj_rewards += s * np.exp(-0.5 * npq.rotation_intrinsic_distance(
                self.demo_orot2[self.iter], oq2) * b)
            b, s = self.reward_params['demo_touch']['b'], self.reward_params[
                'demo_touch']['scale']
            traj_rewards += s * self.demo_grip_weak_closed[self.iter] * np.exp(
                -0.5 * b * (grip - (self.obj2_radius - 0.005))**2)
        if traj_rewards.size == 0:
            reward = 0.
        else:
            reward = np.max(traj_rewards) if self.use_max_reward else np.mean(
                traj_rewards)
        """ Resolve singularities and collisions that we don't want. """
        if self.hand_plane_hit():
            if self.reset_on_plane_hit:
                return EnvStep(self.get_obs(), 0., True, EnvInfo())
            reward = 0.

        if np.abs(hrot[1]) > np.deg2rad(
                85):  # do not allow motion close to singularity
            if self.reset_on_singularity:
                return EnvStep(self.get_obs(), 0., True, EnvInfo())
            reward = 0.

        return EnvStep(self.get_obs(), reward / self.horizon,
                       self.iter == self.horizon, EnvInfo())
    def transform_to_object_frame(self, object_id=0, xyz_scale=1.):
        """
        First, compensate azimuth angle s.t. camera is always looking towards negative x-axis. It is achieved by
        computing objects and hand position in camera coordinate frame. The azimuth rotation of hand is adjusted by
        substraction.

        Second, all positions are updated s.t. obj is always located at [0,0] x,y position.

        Third, orientation of object is updated s.t. first rotation is always identity.
        """
        oid = 'o{}'.format(object_id)
        opos = self.df[[oid + 'posx', oid + 'posy', oid + 'posz'
                        ]].to_numpy() * [1, 1, 0]
        hpos = self.df[['hposx', 'hposy', 'hposz']].to_numpy() * [1, 1, 0]

        yaw = self.df['cazi'].mean()
        t_cam = (self.get_camera_position() * [1, 1, 0],
                 quat_from_euler('z', yaw))
        t_cam_inv = inverse_transform(t_cam)
        """ Positions in camera frame. """
        opos = npq.rotate_vectors(t_cam_inv[1], opos)
        hpos = npq.rotate_vectors(t_cam_inv[1], hpos)
        """ Offset zero object position """
        pos_offset = opos[0].copy() if self.single_object() else opos.copy()
        opos = opos - pos_offset
        hpos = hpos - pos_offset
        """ Compensate rotation of the object """
        orot = self.df[[oid + 'rot0', oid + 'rot1', oid + 'rot2']].to_numpy()
        orot0: npq.quaternion = npq.from_rotation_vector(orot[0])
        for rot in orot:
            rot[:] = npq.as_rotation_vector(orot0.inverse() *
                                            npq.from_rotation_vector(rot))

        self.camera_transformed_pos = -pos_offset
        self.df[oid + 'posx'] = xyz_scale * opos[:, 0]
        self.df[oid + 'posy'] = xyz_scale * opos[:, 1]
        for i in range(3):
            self.df[oid + 'rot{}'.format(i)] = orot[:, i]
        self.df['hposx'] = xyz_scale * hpos[:, 0]
        self.df['hposy'] = xyz_scale * hpos[:, 1]
        self.df['hazi'] = self.df['hazi'].to_numpy() - yaw
        self.df['cazi'] = 0
        self.df['cdis'] = 0
        self.df['cele'] = 0

        self.df[oid + 'posz'] = xyz_scale * self.df[oid + 'posz']
        self.df[oid + 'szz'] = xyz_scale * self.df[oid + 'szz']
        self.df['hposz'] = xyz_scale * self.df['hposz']

        if not self.single_object():
            oid = 'o1'
            orot = self.df[[oid + 'rot0', oid + 'rot1',
                            oid + 'rot2']].to_numpy()

            opos = self.df[[oid + 'posx', oid + 'posy', oid + 'posz'
                            ]].to_numpy() * [1, 1, 0]
            opos = npq.rotate_vectors(t_cam_inv[1], opos)
            opos = opos - pos_offset
            self.df[oid + 'posx'] = xyz_scale * opos[:, 0]
            self.df[oid + 'posy'] = xyz_scale * opos[:, 1]
            self.df[oid + 'posz'] = xyz_scale * self.df[oid + 'posz']
            self.df[oid + 'szz'] = xyz_scale * self.df[oid + 'szz']

            orot0: npq.quaternion = npq.from_rotation_vector(orot[0])
            for rot in orot:
                rot[:] = npq.as_rotation_vector(orot0.inverse() *
                                                npq.from_rotation_vector(rot))
            for i in range(3):
                self.df[oid + 'rot{}'.format(i)] = orot[:, i]