def _bg_loop_fn(self):
     if not self._running:
         # publish steady hold message when asking for zero motion
         motion = CFMotion()
         motion.is_flow_motion = True
         motion.stamp.stamp = rospy.Time.now()
         self._ros_motion_pub.publish(motion)
Example #2
0
    def get_action(self, step, current_episode_step, observation, goal,
                   explore):
        # chosen_actions, chosen_values, action_infos = self.get_actions([step], [current_episode_step] [observation],
        #                                                               [goal], explore=explore)
        # return chosen_actions[0], chosen_values[0], action_infos[0]
        motion = CFMotion()

        motion.yaw = 0

        # return motion
        print("TELEOP POLICY got action:",
              [motion.x, motion.y, motion.yaw, motion.dz])
        return [motion.yaw], None, dict()
Example #3
0
    def get_action(self, step, current_episode_step, observation, goal,
                   explore):
        # chosen_actions, chosen_values, action_infos = self.get_actions([step], [current_episode_step] [observation],
        #                                                               [goal], explore=explore)
        # return chosen_actions[0], chosen_values[0], action_infos[0]
        motion = CFMotion()

        motion.yaw = random.uniform(-120, 120)

        # return motion
        print("RANDOM POLICY chose action:",
              [motion.x, motion.y, motion.yaw, motion.dz])
        return [motion.yaw], None, dict()
Example #4
0
    def _reset():
        global _is_collision
        _is_collision = False

        global _joy_stop_trash_btn_pressed
        global _joy_stop_save_btn_pressed
        global _joy_estop_trash_btn_pressed
        global _joy_estop_pause_btn_pressed
        global _curr_motion

        _joy_stop_trash_btn_pressed = False
        _joy_stop_save_btn_pressed = False
        _joy_estop_trash_btn_pressed = False
        _joy_estop_pause_btn_pressed = False
    
        _curr_motion = CFMotion()
        _curr_motion.is_flow_motion = True
    def _set_motion(self, vx, vy, vz):
        motion = CFMotion()
        motion.x = vx
        motion.y = vy
        motion.yaw = 0  # yaw disabled for now
        motion.dz = vz  # convert velocity to a dt for this time step
        motion.is_flow_motion = True

        self._curr_motion = motion
    def _set_motion(self, vx, vy, vz):
        motion = CFMotion()
        motion.x = vx
        motion.y = vy
        motion.yaw = 0  # yaw disabled for now
        motion.dz = vz
        motion.is_flow_motion = True

        self._curr_motion = motion
Example #7
0
    def _background_thread():
        global _curr_motion

        rate = rospy.Rate(10)
        while not rospy.is_shutdown():

            if _rosbag.is_open:

                _curr_motion.stamp.stamp = rospy.Time.now()
                _motion_pub.publish(_curr_motion)

                # drop things into the rosbag
                # _queue_lock.acquire()
                # _rosbag.write_all(_ros_msg_queue)
                # _buffer_lock.acquire()
                # _swap()
                # _queue_lock.release()
                # _buffer_lock.release()

            else:

                temp_motion = CFMotion()
                temp_motion.stamp.stamp = rospy.Time.now()
                if _curr_joy.axes:
                    temp_motion.y = _curr_joy.axes[ROLL_AXIS] * VY_SCALE
                    temp_motion.x = _curr_joy.axes[PITCH_AXIS] * VX_SCALE
                    temp_motion.yaw = _curr_joy.axes[YAW_AXIS] * YAW_SCALE

                temp_motion.is_flow_motion = True
                _motion_pub.publish(temp_motion)

            rate.sleep()
Example #8
0
    def compute_motion(self):
        #pulls latest joystick data
        if not self.use_joy:
            # no motion input from controller
            return None

        motion = None

        self.access_lock.acquire()

        if self.cmd != -1:
            motion = CFCommand()
            if self.cmd == CFCommand.ESTOP:
                motion.cmd = CFCommand.ESTOP

            elif self.cmd == CFCommand.TAKEOFF:
                motion.cmd = CFCommand.TAKEOFF

            elif self.cmd == CFCommand.LAND:
                motion.cmd = CFCommand.LAND

            #reset
            self.cmd = -1

        #repeat send at 10Hz
        elif self.curr_joy:
            motion = CFMotion()

            motion.is_flow_motion = self.is_flow_motion
            # computing regular vx, vy, yaw, alt motion

            if self.is_flow_motion:
                motion.y = self.curr_joy.axes[ROLL_AXIS] * VY_SCALE
                motion.x = self.curr_joy.axes[PITCH_AXIS] * VX_SCALE
            else:
                motion.x = self.curr_joy.axes[ROLL_AXIS] * ROLL_SCALE
                motion.y = self.curr_joy.axes[PITCH_AXIS] * PITCH_SCALE

                motion.x = motion.x if abs(motion.x) > ROLL_CLIP else 0
                motion.y = motion.y if abs(motion.y) > PITCH_CLIP else 0

            #common
            motion.yaw = self.curr_joy.axes[YAW_AXIS] * YAW_SCALE

            # print(self.curr_joy.axes)
            motion.dz = self.curr_joy.axes[THROTTLE_AXIS] * THROTTLE_SCALE
            # print("ALT CHANGE: %.3f" % motion.dz)

        self.access_lock.release()

        return motion
    def reset(self, ret_latent=False):
        self._curr_motion = CFMotion()
        self._curr_motion.is_flow_motion = True

        vec, latent_idx = self._sim.reset(
            [random.random(),
             random.random(), 0.5 * random.random()],
            ret_latent=True)
        self._latent_idx = latent_idx

        self._obs[0] = vec.vector.x
        self._obs[1] = vec.vector.y
        self._obs[2] = vec.vector.z

        self.render_clear()

        obs, goal = self.reset_model()
        if ret_latent:
            return obs, goal, latent_idx
        else:
            return obs, goal
Example #10
0
class Controller:

    DO_NOTHING_CMD = CFMotion()

    COLLISION_THRESH = 0.5

    def __init__(self, ID):
        self.id = ID

        self.mat = None
        self.data = None

        #need to facilitate a set of publishers per cf node

        self.data_sub = rospy.Subscriber('cf/%d/data' % ID, CFData,
                                         self.data_cb)
        self.image_sub = rospy.Subscriber('cf/%d/image' % ID, CompressedImage,
                                          self.image_cb)

        self.cmd_pub = rospy.Publisher('cf/%d/command' % self.id,
                                       CFCommand,
                                       queue_size=10)
        self.motion_pub = rospy.Publisher('cf/%d/motion' % self.id,
                                          CFMotion,
                                          queue_size=10)
        self.coll_pub = rospy.Publisher('cf/%d/coll' % self.id,
                                        Bool,
                                        queue_size=10)

    def compute_motion(self):
        print("Doing nothing -- ")
        return None

    def observedCollision(self):
        # if not self.data:
        #     return False
        # xy_mag = math.sqrt(self.data.accel_x ** 2 + self.data.accel_y ** 2)
        # print("-- COLLIDED --") if xy_mag > self.COLLISION_THRESH else None
        # return xy_mag > self.COLLISION_THRESH
        return False

    ## CALLBACKS ##

    def image_cb(self, msg):
        pil_jpg = io.BytesIO(msg.data)
        pil_arr = Image.open(pil_jpg).convert('L')  #grayscale

        self.mat = np.array(pil_arr)
        pass

    def data_cb(self, msg):
        self.data = msg
        pass

    ## SETTERS ##

    ## THREADS ##
    def run(self):
        rate = rospy.Rate(10)  # 10Hz
        while not rospy.is_shutdown():
            action = self.compute_motion()

            if self.data and self.observedCollision():
                print("-- COLLISION : E-stopping --")
                action = CFCommand()
                action.cmd = CFCommand.ESTOP
                action.stamp.stamp = rospy.Time.now()
                self.cmd_pub.publish(action)
                self.coll_pub.publish(True)
                #sleep for 2 seconds
                rospy.Rate(1.0 / 2).sleep()
                print("Back Online")
            else:
                self.coll_pub.publish(False)

            if isinstance(action, CFMotion):
                # if action != Controller.DO_NOTHING_CMD:
                action.stamp.stamp = rospy.Time.now()
                self.motion_pub.publish(action)

                # else:
                #     print("--- DO NOTHING CMD SENT ---")
            elif isinstance(action, CFCommand):
                action.stamp.stamp = rospy.Time.now()
                self.cmd_pub.publish(action)
                print("CALLED COMMAND -> %s" % cmd_type[action.cmd])

            else:
                pass

            # rospy.spinOnce()
            rate.sleep()
    def __init__(self, params, env_spec):
        env_spec.assert_has_names(['obs', 'act', 'prev_obs', 'prev_act'])

        self._env_spec = env_spec

        self.x_dim = self._env_spec.names_to_shapes.obs[-1]  # dimension of obs
        self.u_dim = self._env_spec.names_to_shapes.act[-1]  # dimension of act

        self._obs_hist_len = self._env_spec.names_to_shapes.prev_obs[-2]
        self._act_hist_len = self._env_spec.names_to_shapes.prev_act[-2]

        # Setup the parameters
        self._dt = params.dt
        self._ros_prefix = params.ros_prefix

        self.offline = params.offline  # running offline means don't publish anything (e.g. from rosbag)
        self.horizon = int(params.horizon)

        self._normalize = params.normalize

        if self._normalize:
            logger.debug("Normalizing input ON")
            self._coef_cx = 1. / params.img_width
            self._coef_cy = 1. / params.img_height
            self._coef_area = 1. / (params.img_width * params.img_height)
        else:
            self._coef_cx = self._coef_cy = self._coef_area = 1.

        self.time_last_step = -1

        self._obs = np.zeros((self.x_dim,))
        self._next_obs = np.zeros((self.x_dim,))
        self._prev_obs = None
        self._prev_act = None
        self._ob_lb, self._ob_ub = self._env_spec.limits(['obs'])
        self._ob_lb, self._ob_ub = self._ob_lb[0], self._ob_ub[0]
        self.observation_space = spaces.Box(self._ob_lb, self._ob_ub)

        self._initial_goal_pos = params.initial_goal_pos
        self._curr_goal_pos = None

        self._cost = 0
        self._done = False  # indicates if the copter has completed/failed its rollout
        self._running = False  # indicates if a rollout is currently running

        # start with an assumption of collision to allow for takeoff
        self.collided = True

        self._prev_act = None
        self._ac_lb, self._ac_ub = self._env_spec.limits(['act'])
        self._ac_lb, self._ac_ub = self._ac_lb[0], self._ac_ub[0]
        self.action_space = spaces.Box(self._ac_lb, self._ac_ub)

        # ros callbacks
        self._curr_motion = CFMotion()

        self._ros_topics_and_types = {
            self._ros_prefix + 'coll': Bool,
            self._ros_prefix + 'data': CFData,
            'extcam/target_vector': Vector3Stamped,
        }

        self._ros_msgs = dict()
        self._ros_msg_times = dict()

        # ROS setup
        ru.setup_ros_node('MBRLNode', anonymous=True)
        for topic, type in self._ros_topics_and_types.items():
            ru.bind_subscriber(RosTopic(topic, type), self.ros_msg_update, callback_args=(topic,))

        # does not use these publishers if _offline
        _, self._ros_motion_pub = ru.get_publisher(RosTopic(self._ros_prefix + "motion", CFMotion), queue_size=10)
        _, self._ros_command_pub = ru.get_publisher(RosTopic(self._ros_prefix + "command", CFCommand), queue_size=10)
        _, self._ros_goal_pub = ru.get_publisher(RosTopic("/mpc/goal_vector", Vector3Stamped), queue_size=10)
        _, self._ros_action_pub = ru.get_publisher(RosTopic("/mpc/action_vector", Vector3Stamped), queue_size=10)
        _, self._ros_reward_pub = ru.get_publisher(RosTopic("/mpc/reward_vector", Vector3Stamped), queue_size=10)
        _, self._ros_latent_pub = ru.get_publisher(RosTopic("/mpc/latent_vector", Vector3Stamped), queue_size=10)

        _, self._ros_trajectory_marker_pub = ru.get_publisher(RosTopic("/mpc/trajectory_marker", Marker), queue_size=500)
        _, self._ros_ac_marker_pub = ru.get_publisher(RosTopic("/mpc/action_marker", Marker), queue_size=10)

        logger.info("[COPTER]: Initialized, waiting for topic streams before starting...")
        while not self.ros_is_good(display=False):
            pass
        logger.info("[COPTER]: Topics are active.")

        self._step_rate = rospy.Rate(1. / self._dt)  # used in step extra function
        self._rate = rospy.Rate(1. / self._dt)  # used only in background thread

        # this background publisher thread is only when we are online
        if not self.offline:
            ru.setup_background_thread(self._bg_loop_fn, self._rate)
            ru.start_background_thread()

        self.reset()
    def _step(self, u, no_rew_pub=False, step_extra_func=None, buffer_window_size=-1, **kwargs):
        self._running = True  # signifies that we are publishing actions now

        if not self.offline:
            assert self.ros_is_good(display=True)
        # else:
        #     u = self._latest_offline_ac.copy()

        obs = self._next_obs.copy()

        self._enforce_dimension(obs, u)

        # Limit the control inputs
        u0 = np.clip(u, self._ac_lb, self._ac_ub)

        # update vx, vy, dz (does NOT publish)
        self._set_motion(u0[0], u0[1], u0[2])

        self._done = np.all(obs == self._curr_goal_pos) or self.collided

        if np.any(np.isnan(obs)):
            logger.debug('[CF]: NAN POSITION')

        # publishing action messages happens only if we are fully online
        if not self.offline:
            if any((self._curr_motion.x, self._curr_motion.y, self._curr_motion.yaw,

                    self._curr_motion.dz)) or not self.collided:
                self._curr_motion.stamp.stamp = rospy.Time.now()
                self._ros_motion_pub.publish(self._curr_motion)
            else:
                # publish steady hold message when asking for zero motion
                motion = CFMotion()
                motion.is_flow_motion = True
                motion.stamp.stamp = rospy.Time.now()
                self._ros_motion_pub.publish(motion)
        else:
            # offline action publishing
            act_vec = Vector3Stamped()
            act_vec.header.stamp = rospy.Time.now()
            act_vec.vector.x = self._curr_motion.x
            act_vec.vector.y = self._curr_motion.y
            act_vec.vector.z = self._curr_motion.dz
            self._ros_action_pub.publish(act_vec)

        goal_vec = Vector3Stamped()
        goal_vec.header.stamp = rospy.Time.now()
        goal_vec.vector.x = self._curr_goal_pos[0]
        goal_vec.vector.y = self._curr_goal_pos[1]
        goal_vec.vector.z = self._curr_goal_pos[2]
        self._ros_goal_pub.publish(goal_vec)

        # TODO: set cost properly and in a single place
        if not no_rew_pub:
            self.pub_rew(-self._cost)

        ## EXTRA FUNCTIONALITY for inferring latent online
        ret = None
        if step_extra_func is not None:
            def exit_condition(iters): return self._step_rate.remaining().to_sec() < 1e-7 \
                                           and self._step_rate.sleep() is None
            ret = step_extra_func(exit_cond=exit_condition,
                                  buffer_window_size=buffer_window_size)  # returns at or before sleep_end_time
            mu = ret[0][0].item()
            sig = ret[1][0].exp().item()  # TODO do something with these
            latent_vec = Vector3Stamped()
            latent_vec.header.stamp = rospy.Time.now()
            latent_vec.vector.x = mu
            latent_vec.vector.y = sig
            self._ros_latent_pub.publish(latent_vec)
        else:
            self._step_rate.sleep()  # sleep until next iter

        # history update
        self._prev_obs = advance_history_np(self._prev_obs[None], obs[None])[0]
        self._prev_act = advance_history_np(self._prev_act[None], u0[None])[0]

        self._next_obs = self._obs.copy()  # the exact obs the policy sees
        return self.get_obs(), self.get_goal(), self._done
Example #13
0
    def joy_cb(msg):
        global _prev_joy
        global _curr_joy
        global _joy_stop_trash_btn_pressed
        global _joy_stop_save_btn_pressed
        global _joy_estop_trash_btn_pressed
        global _joy_estop_pause_btn_pressed
        global _curr_motion

        _prev_joy = _curr_joy
        _curr_joy = msg

        # print(_curr_joy.buttons)
        # print(_prev_joy.buttons)
        # print()

        if _is_btn(_joy_stop_trash_btn):
            _joy_stop_trash_btn_pressed = True
        if _is_btn(_joy_stop_save_btn):
            _joy_stop_save_btn_pressed = True
        if _is_btn(_joy_estop_trash_btn):
            _joy_estop_trash_btn_pressed = True
        if _is_btn(_joy_estop_pause_btn):
            _joy_estop_pause_btn_pressed = True

        # need to translate curr motion
        _curr_motion = CFMotion()
        _curr_motion.is_flow_motion = _is_flow_motion
        
        # computing regular vx, vy, yaw, alt motion

        if _is_flow_motion:
            _curr_motion.y = _curr_joy.axes[ROLL_AXIS] * VY_SCALE
            _curr_motion.x = _curr_joy.axes[PITCH_AXIS] * VX_SCALE
        else:
            _curr_motion.x = _curr_joy.axes[ROLL_AXIS] * ROLL_SCALE
            _curr_motion.y = _curr_joy.axes[PITCH_AXIS] * PITCH_SCALE

            _curr_motion.x = _curr_motion.x if abs(_curr_motion.x) > ROLL_CLIP else 0
            _curr_motion.y = _curr_motion.y if abs(_curr_motion.y) > PITCH_CLIP else 0

        #common
        _curr_motion.yaw = _curr_joy.axes[YAW_AXIS] * YAW_SCALE

        _curr_motion.dz = 0
Example #14
0
    # parser.add_argument('-logdir', type=str, required=True)
    args = parser.parse_args()

    # main(args.rosbag_dir, args.ros_prefix, args.is_flow, args.max_steps)

    rospy.init_node("DataCapture", anonymous=True)

    _rosbag_lock = threading.Lock()
    _queue_lock = threading.Lock()
    # _buffer_lock = threading.Lock()

    _ros_prefix =  args.ros_prefix
    _is_flow_motion = args.is_flow
    _rosbag = RolloutRosbag(args.rosbag_dir)
    _is_collision = False
    _curr_motion = CFMotion()
    _curr_joy = Joy()
    _prev_joy = Joy()

    _joy_start_btn = 1 # A
    _joy_stop_trash_btn = 3 # Y
    _joy_stop_save_btn = 0 # X
    _joy_estop_trash_btn = 2 # B
    _joy_estop_pause_btn = 5 # RB

    _joy_stop_trash_btn_pressed = False
    _joy_stop_save_btn_pressed = False
    _joy_estop_trash_btn_pressed = False
    _joy_estop_pause_btn_pressed = False

    _ros_msg_times = dict()