Пример #1
0
    def post_update(self):
        self.t += self._sim_step

        if self.checkpoint:
            pose, vel = self.character.get_pose()
            self.recorder.append('character', pose)

        if self.checkpoint and self.t > self.cut_off:
            pose, vel = self.character.get_pose()
            pose, vel = self._skeleton.toLocalFrame(pose, vel)
            with open('data/states/%s.npy' % self.name, 'wb') as f:
                np.save(f, pose)
                np.save(f, vel)

            frames = self.recorder.get('character')
            last_frame = frames[-1]
            inv_ori_rot = self._skeleton.buildHeadingTrans(
                np.array(last_frame[3:7]))
            offset = np.array(last_frame[0:3])
            offset[1] = 0
            for frame in frames:
                pos = np.array(frame[0:3])
                rot = Quaternion.fromWXYZ(np.array(frame[3:7]))
                newpos = inv_ori_rot.rotate(pos - offset)
                newrot = inv_ori_rot.mul(rot)
                frame[0:3] = newpos.tolist()
                frame[3:7] = newrot.wxyz().tolist()

            self.recorder.save('data/records/%s.yaml' % self.name)

            print(self.t)
            print(pose)
            print(vel)
            print('finish data saving')
            input()
Пример #2
0
    def disturb_pose(self, pose, noise):
        """ uniform disturb pose

      pose
      noise  float, deviation angle in radius
    """
        new_pose = pose.copy()

        noise3d = noise / np.sqrt(3)
        new_pose[:3] += uniform(-noise3d, noise3d, 3)

        for jstar, jdof in zip(self.pos_start, self.joint_dof):
            if jdof == 1:
                new_pose[jstar] += uniform(-noise, noise)
            elif jdof == 4:
                noise_quat = Quaternion.fromExpMap(
                    uniform(-noise3d, noise3d, 3))
                ori_quat = Quaternion.fromWXYZ(pose[jstar:jstar + 4])
                new_quat = noise_quat.mul(ori_quat)
                new_pose[jstar:jstar + 4] = new_quat.wxyz()
            elif jdof == 0:
                pass
            else:
                assert (False and "not support jdof other than 1 and 4")

        return new_pose
Пример #3
0
    def targ_pose_to_exp(self, pose):
        """ Convert target pose to exponential map, used as initialization of
        Actor reference memory

      Inputs:
        pose        np.array of float, pose of character

      Outputs:
        exp         np.array of float, action represented in exponential map
    """
        assert (pose.size == self.dof)

        expmap = np.zeros(self.expdof)
        for i in range(1, self.num_joints):
            dof = self.joint_dof[i]
            p_off = self.pos_start[i]
            e_off = self.exp_start[i]
            if dof == 1:  # revolute
                expmap[e_off] = pose[p_off]
            elif dof == 4:  # spherical
                quata = Quaternion.fromWXYZ(pose[p_off:p_off + 4])
                expmap[e_off:e_off + 3] = quata.expmap()

        assert (np.isfinite(sum(expmap))), embed()  #(action, targ_pose)
        return expmap
Пример #4
0
    def computeVel(self, pose0, pose1, dt, padding=True):
        """ Compute velocity between two poses

      Inputs:
        pose0   np.array of float, start pose
        pose1   np.array of float, end pose
        dt      float, duraction between two poses

      Outputs:
        avg_vel np.array of float, vel (w/ or w/o padding)
    """
        assert (pose0.size == self.dof)
        assert (pose1.size == self.dof)

        avg_vel = np.zeros_like(pose0)

        root0 = pose0[:3]
        root1 = pose1[:3]
        avg_vel[:3] = (root1 - root0) / dt

        offset = 3

        # root angular velocity is in world coordinate
        dof = self.joint_dof[0]
        quat0 = Quaternion.fromWXYZ(pose0[offset:offset + dof])
        quat1 = Quaternion.fromWXYZ(pose1[offset:offset + dof])
        avg_vel[offset:offset + 3] = computeAngVel(quat0, quat1, dt)
        offset += dof

        # other joints
        for i in range(1, self.num_joints):
            dof = self.joint_dof[i]
            if dof == 1:  # revolute
                theta0 = pose0[offset]
                theta1 = pose1[offset]
                avg_vel[offset] = (theta1 - theta0) / dt
            elif dof == 4:  # spherical
                quat0 = Quaternion.fromWXYZ(pose0[offset:offset + dof])
                quat1 = Quaternion.fromWXYZ(pose1[offset:offset + dof])
                avg_vel[offset:offset + 3] = computeAngVelRel(quat0, quat1, dt)
            offset += dof

        if padding is False:
            avg_vel = avg_vel[self.comp2pad]

        return avg_vel
Пример #5
0
    def calc_reward(self):
        if self.is_fail:
            return 0
            
        count, pose, vel = self._mocap.slerp(self.t)

        vel[0] *= self.preset.speed_multiplier; vel[2] *= self.preset.speed_multiplier

        self._curr_kin_pose = pose
        self._curr_kin_vel = vel
        
        local_sim_pose, local_sim_vel = self._skeleton.toLocalFrame(self._curr_sim_pose, self._curr_sim_vel)
        local_kin_pose, local_kin_vel = self._skeleton.toLocalFrame(self._curr_kin_pose, self._curr_kin_vel)
        reward = self._skeleton.get_reward(local_sim_pose, local_sim_vel, local_kin_pose, local_kin_vel)

        if self.is_episode_end():
            pose, vel = self.character.get_pose()
            pose, vel = self._skeleton.toLocalFrame(pose, vel)

            bonus = 10.0*self._skeleton.get_reward2(local_sim_pose, local_sim_vel, local_kin_pose, local_kin_vel)
            bonus *= np.exp(-1.0 * np.mean(np.abs(vel[6:] - local_kin_vel[6:])))
            bonus *= np.exp(-1.0 * np.mean(np.abs(vel[3:6] - self.preset.angular_v)))

            bonus *= bell(vel[2], self.preset.linear_v_z, 1.0)

            if self.checkpoint:
                print('v[2]', vel[2])
                print(pose)
                print(vel)
                print('writing to %s ...' % (self.checkpoint + '.npy'))
                with open(self.checkpoint + '.npy', 'wb') as f:
                    np.save(f, pose)
                    np.save(f, vel)
                print('processing recording, please wait ...')
                frames = self.motion_recorder.get('character')
                last_frame = frames[-1]
                inv_ori_rot = self._skeleton.buildHeadingTrans(np.array(last_frame[3:7]))
                offset = np.array(last_frame[0:3])
                offset[1] = 0
                for frame in frames:
                    pos = np.array(frame[0:3])
                    rot = Quaternion.fromWXYZ(np.array(frame[3:7]))
                    newpos = inv_ori_rot.rotate(pos - offset)
                    newrot = inv_ori_rot.mul(rot)
                    frame[0:3] = newpos.tolist()
                    frame[3:7] = newrot.wxyz().tolist()
                self.motion_recorder.save(self.checkpoint + '.yaml')
                print('writing done')
            
            return bonus + reward

        return reward 
Пример #6
0
def change_dir(frames):
    # change direction to x+ axis, starting position at origin
    ori_pos = frames[0, 1:4].copy()
    ori_pos[1] = 0
    vel_dir = frames[-1, 1:4] - frames[0, 1:4]
    heading_theta = np.arctan2(-vel_dir[2], vel_dir[0])
    inv_rot = Quaternion.fromAngleAxis(-heading_theta, np.array([0, 1, 0]))
    for i in range(frames.shape[0]):
        frame = frames[i]
        frames[i, 1:4] = inv_rot.rotate(frame[1:4] - ori_pos)
        root_rot = Quaternion.fromWXYZ(frame[4:8])
        new_rot = inv_rot.mul(root_rot)
        frames[i, 4:8] = new_rot.pos_wxyz()

    return frames
Пример #7
0
    def disturb_root_pose(self, pose, pos_noise, ori_noise):
        """ uniform disturb pose root
    """
        new_pose = pose.copy()

        noise3d = pos_noise / np.sqrt(3)
        new_pose[:3] += uniform(-noise3d, noise3d, 3)

        noise3d = ori_noise / np.sqrt(3)
        noise_quat = Quaternion.fromExpMap(uniform(-noise3d, noise3d, 3))
        ori_quat = Quaternion.fromWXYZ(pose[3:7])
        new_quat = noise_quat.mul(ori_quat)
        new_pose[3:7] = new_quat.wxyz()

        return new_pose
Пример #8
0
    def normalize_target_pose(self, pose):
        """
      normalize given pose to make quaternions norm as 1
    """
        assert (pose.size == self.dof)
        norm_pose = pose.copy()
        for i in range(self.num_joints):
            dof = self.joint_dof[i]
            p_off = self.pos_start[i]
            if dof == 4:  # spherical
                quata = Quaternion.fromWXYZ(pose[p_off:p_off + 4])
                norm_pose[p_off:p_off + 4] = quata.pos_wxyz()

        assert (np.isfinite(sum(norm_pose))), embed()  #(action, targ_pose)
        return norm_pose
Пример #9
0
    def generalized_falling_rwd(self):
        avg_penalty = self.offset_penalty / self.num_step
        rwd = 1.0 - np.clip(
            np.power(avg_penalty / self.offset_penalty_coeff, 2), 0, 1)

        avg_ang_penalty = self.angv_penalty / self.num_step
        rwd *= np.exp(-self.angv_penalty_coeff * avg_ang_penalty)

        if rwd > 0:
            q = Quaternion.fromWXYZ(self.root_quat)
            min_angle = np.pi
            for qb in self.q_bases:
                q_base = Quaternion.fromWXYZ(np.array(qb))
                q_diff = q.mul(q_base.conjugate())
                angle = np.abs(q_diff.angle())
                min_angle = np.min([min_angle, angle])
            rwd *= np.clip(min_angle / (np.pi / 2), 0.01, 1)
            #print(min_angle)
            #print(self.root_quat)

            if self.head_contact:
                rwd *= 0.7

        return rwd
Пример #10
0
    def toLocalFrame(self, pose, vel, ori_pos=None, ori_rot=None):
        """ Convert pose and vel from world frame to local frame,
        the local frame heading direction is rotated x-axis

      Inputs:
        pose        np.array of float, character pose
        vel         np.array of float, character vel w/ padding
        ori_pos     np.array of float, 3 dim, position of local coordinate origin
        ori_rot     np.array of float, 4 dim, (w, x, y, z) quat of local coordinate orientation

      Outputs:
        local_pose
        local_vel
    """
        if ori_pos is None:
            ori_pos = pose[:3]
        if ori_rot is None:
            ori_rot = pose[3:7]

        # heading theta
        inv_ori_rot = self.buildHeadingTrans(ori_rot)

        local_pos = pose.copy()
        local_vel = vel.copy()

        # ignore y difference, because local cooridnate shares xoz plane with world
        local_pos[0] -= ori_pos[0]  # root x pos
        local_pos[2] -= ori_pos[2]  # root y pos

        ori_rot = Quaternion.fromWXYZ(ori_rot)
        ori_rot = inv_ori_rot.mul(ori_rot)
        local_pos[3:7] = ori_rot.pos_wxyz()  # root orientation

        local_vel[:3] = inv_ori_rot.rotate(vel[:3])  # root velocity
        local_vel[3:6] = inv_ori_rot.rotate(vel[3:6])  # root angular velocity

        return local_pos, local_vel
Пример #11
0
    def targ_pose_to_action(self, pose):
        """ Convert desired pose to action

      Inputs:
        pose        np.array of float, pose of character

      Outputs:
        action      np.array of float, action which DeepMimicSim can take in
    """
        assert (pose.size == self.dof)

        action = np.zeros(self.dof - 7)
        for i in range(1, self.num_joints):
            dof = self.joint_dof[i]
            p_off = self.pos_start[i]
            a_off = self.act_start[i]
            if dof == 1:  # revolute
                action[a_off] = pose[p_off]
            elif dof == 4:  # spherical
                quata = Quaternion.fromWXYZ(pose[p_off:p_off + 4])
                action[a_off:a_off + 4] = quata.angaxis()

        assert (np.isfinite(sum(action))), embed()  #(action, targ_pose)
        return action
Пример #12
0
    def __init__(self, skeleton, mocap_file, extend_none_wrap=True):

        self._skeleton = skeleton  # HumanoidSkeleton

        self._durations = None
        self._frames = None

        self._cycletime = None  # total time of mocap
        self._spf = None  # seconds per frame
        self._cyc_offset = None  # cycle offset of base
        self._is_wrap = None

        with open(mocap_file, 'r') as f:
            data = json.load(f)

        frame_data = np.array(data["Frames"])
        loop_type = data["Loop"]
        self._is_wrap = (loop_type == "wrap")

        # assert frame duration should be uniform
        self._durations = frame_data[:, 0]
        tmp = self._durations[:-1]
        assert (abs(tmp - tmp.mean()).max() < 1e-10), tmp
        self._spf = self._durations[0]

        # if is non-wrap motion, extend final frame 0.5 seconds
        if not self._is_wrap and extend_none_wrap:
            n_ext = int(0.5 / self._spf)
            frame_data[-1, 0] = self._spf
            repeated_frames = np.repeat([frame_data[-1]], n_ext, axis=0)
            frame_data = np.concatenate([frame_data, repeated_frames])
            frame_data[-1, 0] = 0
            self._durations = frame_data[:, 0]

        # calculate cycle time and other information
        self._cycletime = np.sum(self._durations)

        self._frames = frame_data[:, 1:]
        self.num_frames = frame_data.shape[0]
        self._cyc_offset = self._frames[-1][:3] - self._frames[0][:3]
        self._cyc_offset[1] = 0
        assert (self._frames.shape[1] == self._skeleton.dof)

        # normalize quaternions
        for offset, dof in zip(self._skeleton.pos_start,
                               self._skeleton.joint_dof):
            if dof == 4:
                for i in range(self.num_frames):
                    quat = Quaternion.fromWXYZ(self._frames[i,
                                                            offset:offset + 4])
                    self._frames[i, offset:offset + 4] = quat.wxyz()

        # precompute velocity
        self._vels_pad = np.zeros((self.num_frames, self._skeleton.dof))

        for i in range(self._vels_pad.shape[0] - 1):
            curr_frame = self._frames[i]
            next_frame = self._frames[i + 1]
            dt = self._durations[i]
            self._vels_pad[i] = self._skeleton.computeVel(
                curr_frame, next_frame, dt, True)
        self._vels_pad[-1] = self._vels_pad[-2]

        self._vels_pad_noise = self._vels_pad.copy()

        self._vels_pad = self._butterworth_filter(self._vels_pad)

        self._vels_comp_noise = self._vels_pad_noise[:,
                                                     self._skeleton.comp2pad]
        self._vels_comp = self._vels_pad[:, self._skeleton.comp2pad]
        assert (np.isfinite(
            self._vels_pad.sum())), print("infinite vels in mocap file")

        # precompute com pose and smooth
        self._com = []
        self._com_vel = []
        for p, v in zip(self._frames, self._vels_pad):
            self._skeleton.set_pose(p)
            self._skeleton.set_vel(v)
            self._com.append(self._skeleton.get_com_pos())
            self._com_vel.append(self._skeleton.get_com_vel())
        self._com = np.array(self._com)
        self._com_vel = np.array(self._com_vel)

        self._com_smooth = self._com.copy()
        self._com_smooth = self._butterworth_filter(self._com_smooth)