예제 #1
0
def main():
    rospy.init_node("pub_pose_array")
    publisher = rospy.Publisher("pose_array", PoseArray, queue_size=1)

    center = (1, 0)
    radius = 2
    pose = Pose2D(center[0] + radius * np.cos(0),
                  center[1] + radius * np.sin(0), np.pi / 2)
    angle = np.pi / 18.
    moved = Pose2D(center[0] + radius * np.cos(angle),
                   center[1] + radius * np.sin(angle), np.pi / 2 + angle)
    motion = pose.motion_to(moved)
    rate = rospy.Rate(2)
    pose_arr = []
    count = 0
    while not rospy.is_shutdown():
        pose3d = pose2d_to_3d(pose)
        count += 1
        pose3d.position.z = count * 0.01
        header = Header(stamp=rospy.get_rostime(), frame_id="map")
        pose_arr.append(pose3d)
        message = PoseArray(header=header, poses=pose_arr)
        publisher.publish(message)
        pose = pose.move(motion)
        rate.sleep()
 def tracked_persons_callback(self, msg):
     if self.refmap_manager.tf_frame_in_refmap is None:
         # localization not available yet
         return
     if self.goal_xy_in_refmap is None:
         # goal not available yet
         return
     pose2d_tracksframe_in_refmap = None
     if msg.header.frame_id != self.refmap_manager.kRefMapFrame:
         # get tf
         try:
             tf_frame_in_refmap = self.tf_listener.lookupTransform(
                 self.refmap_manager.kRefMapFrame, msg.header.frame_id,
                 rospy.Time(0))
         except (tf.LookupException, tf.ConnectivityException,
                 tf.ExtrapolationException) as e:
             rospy.logwarn_throttle(10., e)
             raise ValueError(e)
         # set for future use
         pose2d_tracksframe_in_refmap = Pose2D(tf_frame_in_refmap)
     robot_pos_in_refmap = Pose2D(self.refmap_manager.tf_frame_in_refmap)
     robot_radius = self.kRobotRadius
     robot_goal_xy_in_refmap = self.goal_xy_in_refmap
     # state update
     self.state_estimator_node.tracked_persons_update(
         msg,
         pose2d_tracksframe_in_refmap,
         self.refmap_manager.map_8ds,
         robot_pos_in_refmap,
         robot_radius,
         robot_goal_xy_in_refmap,
     )
예제 #3
0
    def visuals_loop(self):
        while True:
            xx, yy, clusters, is_legs, cogs, radii = self.clusters_data
            # past positions
            tf_past_in_rob = []
            if self.tf_pastrobs_in_fix:
                tf_rob_in_fix = self.tf_pastrobs_in_fix[-1]
                for i, tf_a in enumerate(self.tf_pastrobs_in_fix[::-1]):
                    tf_b = apply_tf_to_pose(
                        Pose2D(tf_a), inverse_pose2d(Pose2D(tf_rob_in_fix)))
                    tf_past_in_rob.append(tf_b)
            # Plotting
            plt.figure("clusters")
            plt.cla()
            plt.scatter(xx,
                        yy,
                        zorder=1,
                        facecolor=(1, 1, 1, 1),
                        edgecolor=(0, 0, 0, 1),
                        color='k',
                        marker='.')
            #         for x, y in zip(xx, yy):
            #             plt.plot([0, x], [0, y], linewidth=0.01, color='red' , zorder=2)
            plt.scatter([0], [0], marker='+', color='k', s=1000)
            for c in clusters:
                plt.plot(xx[c], yy[c], zorder=2)
            for l, cog, r in zip(is_legs, cogs, radii):
                if l:
                    patch = patches.Circle(cog,
                                           r,
                                           facecolor=(0, 0, 0, 0),
                                           edgecolor=(0, 0, 0, 1),
                                           linewidth=3)
                else:
                    patch = patches.Circle(cog,
                                           r,
                                           facecolor=(0, 0, 0, 0),
                                           edgecolor=(0, 0, 0, 1),
                                           linestyle='--')
                plt.gca().add_artist(patch)
            if tf_past_in_rob:
                xy_past = np.array(tf_past_in_rob)
                plt.plot(xy_past[:, 0], xy_past[:, 1], color='red')

            plt.gca().set_aspect('equal', adjustable='box')
            LIM = 10
            plt.ylim([-LIM, LIM])
            plt.xlim([-LIM, LIM])
            # pause
            plt.pause(0.1)
            rospy.timer.sleep(0.01)
예제 #4
0
    def visuals_loop(self):
        while True:
            with self.lock:
                if self.transport_data is None:
                    plt.pause(0.1)
                    rospy.timer.sleep(0.01)
                    continue
                _, xx, yy, clusters, is_legs, cogs, radii, tf_rob_in_fix = self.transport_data
                # transform data to fixed frame
                pose2d_rob_in_fix = Pose2D(tf_rob_in_fix)
                xy_f = apply_tf(np.vstack([xx, yy]).T, pose2d_rob_in_fix)
                cogs_f = apply_tf(np.array(cogs), pose2d_rob_in_fix)
                # past positions
                pose2d_past_in_fix = []
                if self.tf_pastrobs_in_fix:
                    for tf_a in self.tf_pastrobs_in_fix[::-1]:
                        pose2d_past_in_fix.append(Pose2D(tf_a))
            # Plotting
            plt.figure("clusters")
            plt.cla()
            #   Robot
            plt.scatter([pose2d_rob_in_fix[0]],[pose2d_rob_in_fix[1]],marker='+', color='k',s=1000)
            #   Lidar
#             plt.scatter(xy_f[:,0], xy_f[:,1], zorder=1, facecolor=(1,1,1,1), edgecolor=(0,0,0,1), color='k', marker='.')
#             for x, y in zip(xx, yy):
#                 plt.plot([0, x], [0, y], linewidth=0.01, color='red' , zorder=2)
            #   clusters
#             for c in clusters:
#                 plt.plot(xx[c], yy[c], zorder=2)
            for l, cog, r in zip(is_legs,cogs_f, radii):
                if l:
#                     patch = patches.Circle(cog, r, facecolor=(0,0,0,0), edgecolor=(0,0,0,1), linewidth=3)
#                     plt.gca().add_artist(patch)
                    plt.scatter([cog[0]], [cog[1]], marker='+', color='green', s=500)
                else:
                    patch = patches.Circle(cog, r, facecolor=(0,0,0,0), edgecolor=(0,0,0,1), linestyle='--')
                    plt.gca().add_artist(patch)
            if pose2d_past_in_fix:
                xy_past = np.array(pose2d_past_in_fix)
                plt.plot(xy_past[:,0], xy_past[:,1], color='red')
            # Tracks
            with self.lock:
                self.tracker.vizualize_tracks()
            # Display options
            plt.gca().set_aspect('equal',adjustable='box')
#             LIM = 10
#             plt.ylim([-LIM, LIM])
#             plt.xlim([-LIM, LIM])
            # pause
            plt.pause(0.1)
            rospy.timer.sleep(0.01)
예제 #5
0
 def global_waypoint_callback(self, msg):
     """ If a global path is received (in map frame), try to track it """
     with self.lock:
         waypoint_in_msg = np.array([
             msg.pose.position.x,
             msg.pose.position.y,
         ])
         ## msg frame to fixed frame
         if self.kFixedFrame != msg.header.frame_id:
             try:
                 tf_msg_in_fix = self.tf_listener.lookupTransform(
                     self.kFixedFrame, msg.header.frame_id,
                     msg.header.stamp - rospy.Duration(0.1))
             except (tf.LookupException, tf.ConnectivityException,
                     tf.ExtrapolationException) as e:
                 print(
                     "Could not find transform from waypoint frame to fixed."
                 )
                 print(e)
                 return
             waypoint_in_fix = apply_tf(waypoint_in_msg,
                                        Pose2D(tf_msg_in_fix))
         else:
             waypoint_in_fix = waypoint_in_msg
         self.tf_goal_in_fix = (
             np.array([waypoint_in_fix[0], waypoint_in_fix[1],
                       0.]),  # trans
             tf.transformations.quaternion_from_euler(0, 0, 0))  # quat
 def set_goal_routine(self, event=None):
     if self.latest_goal_msg is None:
         return
     if self.refmap_manager.tf_frame_in_refmap is None:
         rospy.logwarn_throttle(
             1.,
             "IA: Reference map transform ({} -> {}) not available yet.".
             format(
                 self.refmap_manager.kRefMapFrame,
                 self.refmap_manager.kFrame,
             ))
         return
     # goal might not be in reference map frame. find goal_xy in refmap frame
     try:
         time = rospy.Time.now()
         tf_info = [
             self.refmap_manager.kRefMapFrame,
             self.latest_goal_msg.header.frame_id, time
         ]
         self.tf_listener.waitForTransform(*(tf_info + [self.tf_timeout]))
         tf_msg_in_refmap = self.tf_listener.lookupTransform(*tf_info)
     except (tf.LookupException, tf.ConnectivityException,
             tf.ExtrapolationException, TransformException) as e:
         rospy.logwarn(
             "[{}.{}] tf to refmap frame for time {}.{} not found: {}".
             format(rospy.Time.now().secs,
                    rospy.Time.now().nsecs, time.secs, time.nsecs, e))
         return
     pose2d_msg_in_refmap = Pose2D(tf_msg_in_refmap)
     goal_xy = apply_tf(
         np.array([
             self.latest_goal_msg.pose.position.x,
             self.latest_goal_msg.pose.position.y
         ]), pose2d_msg_in_refmap)
     # goal ij
     goal_ij = self.refmap_manager.map_8ds.xy_to_ij(
         [goal_xy[:2]], clip_if_outside=False)[0]
     if not self.refmap_manager.map_8ds.is_inside_ij(
             np.array([goal_ij], dtype=np.float32)):
         rospy.logwarn(
             "Goal (i,j : {}, {}) is outside of reference map (size: {}, {})"
             .format(goal_ij[0], goal_ij[1],
                     *self.refmap_manager.map_8ds.occupancy().shape))
         return
     if self.goal_xy_in_refmap is not None:
         if not np.allclose(self.goal_ij_in_refmap, goal_ij):
             self.replan_due_to_new_goal_flag[0] = True
             rospy.loginfo("Global goal has changed.")
     self.goal_xy_in_refmap = goal_xy
     self.goal_ij_in_refmap = goal_ij
     # Goal as marker
     marker = self.goal_as_marker(goal_xy)
     goal_pub = rospy.Publisher("/ia_planner/goal", Marker, queue_size=1)
     goal_pub.publish(marker)
     self.goal_is_reached = False
     rospy.loginfo("New global goal: {}[meters], {}[ij]".format(
         goal_xy, goal_ij))
     self.latest_goal_msg = None
예제 #7
0
def main():
    rospy.init_node("pub_moving_pose")
    publisher = rospy.Publisher("moving_pose", PoseStamped, queue_size=1)

    center = (1, 0)
    radius = 2
    pose = Pose2D(center[0] + radius * np.cos(0), center[1] + radius * np.sin(0), np.pi / 2)
    angle = np.pi / 18.
    moved = Pose2D(center[0] + radius * np.cos(angle), center[1] + radius * np.sin(angle), np.pi / 2 + angle)
    motion = pose.motion_to(moved)
    rate = rospy.Rate(2)
    while not rospy.is_shutdown():
        pose3d = pose2d_to_3d(pose)
        header = Header(stamp=rospy.get_rostime(), frame_id="map")
        message = PoseStamped(header=header, pose=pose3d)
        publisher.publish(message)
        pose = pose.move(motion)
        rate.sleep()
 def turn_to_face_goal_callback(self, event=None):
     with self.lock:
         if self.plan_executor_node.task_being_executed is not None:
             return
         if self.refmap_manager.tf_frame_in_refmap is None:
             return
         if self.goal_xy_in_refmap is None:
             return
         p2_refmap_in_robot = inverse_pose2d(
             Pose2D(self.refmap_manager.tf_frame_in_refmap))
         goal_xy_in_robot = apply_tf(self.goal_xy_in_refmap,
                                     p2_refmap_in_robot)
     rospy.loginfo_throttle(5., "turning to face goal")
     gx, gy = goal_xy_in_robot
     angle_to_goal = np.arctan2(gy, gx)  # [-pi, pi]
     w = 0
     if np.abs(angle_to_goal) > ((np.pi / 4) / 10):  # deadzone
         w = 0.3 * np.sign(angle_to_goal)
     if not self.STOP:
         cmd_vel_msg = Twist()
         cmd_vel_msg.angular.z = w
         self.cmd_vel_pub.publish(cmd_vel_msg)
예제 #9
0
 def waypoint_callback(self, msg):
     self.tf_timeout = rospy.Duration(0.1)
     """ If a global path is received (in map frame), try to track it """
     with self.lock:
         ref_frame = msg.header.frame_id
         wpt_ref_xy = [msg.pose.position.x, msg.pose.position.y]
         try:
             time = rospy.Time.now()
             tf_info = [self.kFixedFrame, msg.header.frame_id, time]
             self.tf_listener.waitForTransform(*(tf_info +
                                                 [self.tf_timeout]))
             tf_ref_in_fix = self.tf_listener.lookupTransform(*tf_info)
         except (tf.LookupException, tf.ConnectivityException,
                 tf.ExtrapolationException, TransformException) as e:
             rospy.logwarn(
                 "[{}.{}] tf to refmap frame for time {}.{} not found: {}".
                 format(rospy.Time.now().secs,
                        rospy.Time.now().nsecs, time.secs, time.nsecs, e))
             return
         wpt_fix_xy = apply_tf(np.array(wpt_ref_xy), Pose2D(tf_ref_in_fix))
         self.tf_wpt_in_fix = (
             np.array([wpt_fix_xy[0], wpt_fix_xy[1], 0.]),  # trans
             tf.transformations.quaternion_from_euler(0, 0, 0))  # quat
예제 #10
0
    def planner_routine(self, event=None):
        nowstamp = rospy.Time.now()
        if self.tf_wpt_in_fix is None:
            rospy.logwarn_throttle(10., "Global path not available yet")
            return
        if self.tf_rob_in_fix is None:
            rospy.logwarn_throttle(10., "tf_rob_in_fix not available yet")
            return
        if self.odom is None:
            rospy.logwarn_throttle(10., "odom not available yet")
            return
        # remove old obstacles from buffer
        k2s = 2.
        with self.lock:
            tic = timer()
            dynamic_obstacles = []
            self.obstacles_buffer = [
                obst_msg for obst_msg in self.obstacles_buffer
                if nowstamp - obst_msg.header.stamp < rospy.Duration(k2s)
            ]
            # DEBUG remove
            #             for obst_msg in self.obstacles_buffer:
            for obst_msg in self.obstacles_buffer[-1:]:
                dynamic_obstacles.extend(obst_msg.obstacles)
            # take into account static obstacles if not old
            static_obstacles = []
            if self.static_obstacles_buffer is not None:
                if (nowstamp - self.static_obstacles_buffer.header.stamp
                    ) < rospy.Duration(k2s):
                    static_obstacles = self.static_obstacles_buffer.obstacles
            # vel to goal in fix
            goal_in_fix = np.array(Pose2D(self.tf_wpt_in_fix)[:2])
            toc = timer()
            print("Lock preproc {:.1f} ms".format((toc - tic) * 1000.))
            # robot position
            tf_rob_in_fix = self.tf_rob_in_fix

        tic = timer()

        # RVO set up
        positions = []
        radii = []
        velocities = []
        obstacles = []
        metadata = []  # agent metadata

        # create agents for RVO
        # first agent is the robot
        positions.append(Pose2D(tf_rob_in_fix)[:2])
        radii.append(self.kRadius)
        velocities.append(
            [self.odom.twist.twist.linear.x, self.odom.twist.twist.linear.y])
        metadata.append({'source': 'robot'})
        # create agent for every dynamic obstacle
        for obst in dynamic_obstacles:
            positions.append(
                [obst.polygon.points[0].x, obst.polygon.points[0].y])
            radii.append(obst.radius)
            velocities.append([
                obst.velocities.twist.linear.x, obst.velocities.twist.linear.y
            ])
            metadata.append({'source': 'dynamic'})
        # create agents for local static obstacles (table leg, chair, etc)
        for obst in static_obstacles:
            if obst.radius > 0.5:
                continue  # TODO big walls make big circles : but dangerous to do this!
            positions.append(
                [obst.polygon.points[0].x, obst.polygon.points[0].y])
            radii.append(obst.radius)
            velocities.append([
                obst.velocities.twist.linear.x, obst.velocities.twist.linear.y
            ])
            metadata.append({'source': 'nonleg'})

        # create static obstacle vertices from refmap if available (walls, etc)
        if self.refmap_manager.tf_frame_in_refmap is not None:
            kMapObstMaxDist = 3.
            obstacles_in_ref = self.refmap_manager.map_as_closed_obstacles
            pose2d_ref_in_fix = inverse_pose2d(
                Pose2D(self.refmap_manager.tf_frame_in_refmap))
            near_obstacles = [
                apply_tf(vertices, pose2d_ref_in_fix)
                for vertices in obstacles_in_ref if len(vertices) > 1
            ]
            near_obstacles = [
                vertices for vertices in near_obstacles if np.mean(
                    np.linalg.norm(vertices - np.array(positions[0]), axis=1))
                < kMapObstMaxDist
            ]
            obstacles = near_obstacles

        toc = timer()
        print("Pre-RVO {:.1f} ms".format((toc - tic) * 1000.))
        tic = timer()

        # RVO ----------------
        import rvo2
        t_horizon = 10.
        DT = 1 / 10.
        #RVOSimulator(timeStep, neighborDist, maxNeighbors, timeHorizon, timeHorizonObst, radius, maxSpeed, velocity = [0,0]);
        sim = rvo2.PyRVOSimulator(DT, 1.5, 5, 1.5, 2, 0.4, 2)

        # Pass either just the position (the other parameters then use
        # the default values passed to the PyRVOSimulator constructor),
        # or pass all available parameters.
        agents = []
        for p, v, r, m in zip(positions, velocities, radii, metadata):
            #addAgent(posxy, neighborDist, maxNeighbors, timeHorizon, timeHorizonObst, radius, maxSpeed, velocity = [0,0]);
            a = sim.addAgent(tuple(p), radius=r, velocity=tuple(v))
            agents.append(a)
            # static agents can't move
            if m['source'] != 'robot' and np.linalg.norm(v) == 0:
                sim.setAgentMaxSpeed(a, 0)

        # Obstacle(list of vertices), anticlockwise (clockwise for bounding obstacle)
        for vert in obstacles:
            o1 = sim.addObstacle(list(vert))
        sim.processObstacles()

        toc = timer()
        print("RVO init {:.1f} ms".format((toc - tic) * 1000.))
        tic = timer()

        n_steps = int(t_horizon / DT)
        pred_tracks = [[] for a in agents]
        pred_vels = [[] for a in agents]
        pred_t = []
        for step in range(n_steps):
            for i in range(len(agents)):
                # TODO: early stop if agent 0 reaches goal
                a = agents[i]
                pref_vel = velocities[
                    i]  # assume agents want to keep initial vel
                if i == 0:
                    vector_to_goal = goal_in_fix - np.array(
                        sim.getAgentPosition(a))
                    pref_vel = self.kIdealVelocity * vector_to_goal / np.linalg.norm(
                        vector_to_goal)
                sim.setAgentPrefVelocity(a, tuple(pref_vel))
                pred_tracks[i].append(sim.getAgentPosition(a))
                pred_vels[i].append(sim.getAgentVelocity(a))
            pred_t.append(1. * step * DT)
            sim.doStep()
        # -------------------------
        toc = timer()
        print("RVO steps {} - {} agents - {} obstacles".format(
            step, len(agents), len(obstacles)))
        print("RVO sim {:.1f} ms".format((toc - tic) * 1000.))

        # PLOT ---------------------------
        #         self.transport_data = (sim, agents, metadata, radii, obstacles, pred_tracks)
        # -----------------------------

        # publish predicted tracks as paths
        rob_track = pred_tracks[0]
        pub = rospy.Publisher("/rvo_robot_plan", Path, queue_size=1)
        path_msg = Path()
        path_msg.header.stamp = nowstamp
        path_msg.header.frame_id = self.kFixedFrame
        for pose, t in zip(rob_track, pred_t):
            pose_msg = PoseStamped()
            pose_msg.header.stamp = nowstamp + rospy.Duration(t)
            pose_msg.header.frame_id = path_msg.header.frame_id
            pose_msg.pose.position.x = pose[0]
            pose_msg.pose.position.y = pose[1]
            path_msg.poses.append(pose_msg)
        pub.publish(path_msg)

        # publish tracks
        pub = rospy.Publisher("/rvo_simulated_tracks",
                              MarkerArray,
                              queue_size=1)
        ma = MarkerArray()
        id_ = 0
        end_x = [sim.getAgentPosition(agent_no)[0] for agent_no in agents]
        end_y = [sim.getAgentPosition(agent_no)[1] for agent_no in agents]
        end_t = pred_t[-1]
        for i in range(len(agents)):
            color = (0, 0, 0, 1)  # black
            color = (1, .8, 0,
                     1) if metadata[i]['source'] == 'robot' else color  # green
            color = (1, 0, 0,
                     1) if metadata[i]['source'] == 'dynamic' else color  # red
            color = (0, 0, 1,
                     1) if metadata[i]['source'] == 'nonleg' else color  # blue
            # track line
            mk = Marker()
            mk.lifetime = rospy.Duration(0.1)
            mk.header.frame_id = self.kFixedFrame
            mk.ns = "tracks"
            mk.id = i
            mk.type = 4  # LINE_STRIP
            mk.action = 0
            mk.scale.x = 0.02
            mk.color.r = color[0]
            mk.color.g = color[1]
            mk.color.b = color[2]
            mk.color.a = color[3]
            mk.frame_locked = True
            xx = np.array(pred_tracks[i])[:, 0]
            yy = np.array(pred_tracks[i])[:, 1]
            for x, y, t in zip(xx, yy, pred_t):
                pt = Point()
                pt.x = x
                pt.y = y
                pt.z = t / t_horizon
                mk.points.append(pt)
            ma.markers.append(mk)
            # endpoint
            r = radii[i]
            mk = Marker()
            mk.lifetime = rospy.Duration(0.1)
            mk.header.frame_id = self.kFixedFrame
            mk.ns = "endpoints"
            mk.id = i
            mk.type = 3  # CYLINDER
            mk.action = 0
            mk.scale.x = r * 2.
            mk.scale.y = r * 2.
            mk.scale.z = 0.1
            mk.color.r = color[0]
            mk.color.g = color[1]
            mk.color.b = color[2]
            mk.color.a = color[3]
            mk.frame_locked = True
            mk.pose.position.x = end_x[i]
            mk.pose.position.y = end_y[i]
            mk.pose.position.z = end_t / t_horizon
            ma.markers.append(mk)
        pub.publish(ma)

        pred_rob_vel_in_fix = np.array(
            pred_vels[0]
            [1])  # 2 is a cheat because 0 is usually the current speed
        pred_end_in_fix = np.array([end_x[0], end_y[0]])
        # in robot frame
        pose2d_fix_in_rob = inverse_pose2d(Pose2D(tf_rob_in_fix))
        pred_rob_vel_in_rob = apply_tf_to_vel(
            np.array(list(pred_rob_vel_in_fix) + [0]), pose2d_fix_in_rob)[:2]
        pred_end_in_rob = apply_tf(pred_end_in_fix, pose2d_fix_in_rob)
        # resulting command vel, and path
        best_u, best_v = pred_rob_vel_in_rob
        # check if goal is reached
        if np.linalg.norm(pred_end_in_rob) < 0.1:
            best_u, best_v = (0, 0)

        # Slow turn towards goal
        # TODO
        best_w = 0
        WMAX = 0.5
        gx, gy = pred_end_in_rob
        angle_to_goal = np.arctan2(gy, gx)  # [-pi, pi]
        if np.sqrt(gx * gx + gy * gy) > 0.5:  # turn only if goal is far away
            if np.abs(angle_to_goal) > (np.pi / 4 / 10):  # deadzone
                best_w = np.clip(angle_to_goal, -WMAX, WMAX)  # linear ramp

        cmd_vel_pub = rospy.Publisher("/cmd_vel", Twist, queue_size=1)
        if not self.STOP:
            # publish cmd_vel
            cmd_vel_msg = Twist()
            cmd_vel_msg.linear.x = best_u
            cmd_vel_msg.linear.y = best_v
            cmd_vel_msg.angular.z = best_w
            cmd_vel_pub.publish(cmd_vel_msg)
 def currenttask_planner_update_routine(self, event=None):
     with self.lock:
         if self.refmap_manager.tf_frame_in_refmap is None:
             return
         if self.task_being_executed is None:
             return
         if self.STOP:
             return
         current_task = self.task_being_executed
         taskinfo = current_task["taskinfo"]
         current_task_action = taskinfo["taskaction"]
         startidx = taskinfo["taskstartidx"]
         resultidx = taskinfo["tasktargetpathidx"]
         current_task_path = taskinfo["taskfullpath"][startidx:resultidx]
         #             current_task_target_pos = current_task_path[taskinfo["tasktargetpathidx"]]
         # get next waypoint
         robot_xy_in_refmap = Pose2D(
             self.refmap_manager.tf_frame_in_refmap)[:2]
         current_waypoint_in_refmap = np.array(
             current_task_path[self.current_waypoint_index])
         # move waypoint forward by Xm if reached
         waypoint_dist = self.kWaypointDist_m[current_task_action.typestr()]
         if SLIDING_WPT:
             for index in range(self.current_waypoint_index,
                                len(current_task_path)):
                 new_pos = np.array(current_task_path[index])
                 if np.linalg.norm(new_pos -
                                   robot_xy_in_refmap) >= waypoint_dist:
                     break
                 self.current_waypoint_index = index
                 current_waypoint_in_refmap = new_pos
         else:
             if np.linalg.norm(robot_xy_in_refmap -
                               current_waypoint_in_refmap) < (
                                   self.kRobotRadius + self.kWaypointRadius
                               ) or self.current_waypoint_index == 0:
                 for index in range(self.current_waypoint_index,
                                    len(current_task_path)):
                     new_pos = np.array(current_task_path[index])
                     if np.linalg.norm(new_pos - current_waypoint_in_refmap
                                       ) >= waypoint_dist:
                         break
                     result_index = index
                     result_waypoint_in_refmap = new_pos
                 self.current_waypoint_index = result_index
                 current_waypoint_in_refmap = result_waypoint_in_refmap
         # send waypoint
         from visualization_msgs.msg import Marker
         mk_msg = Marker()
         mk_msg.header.frame_id = self.refmap_manager.kRefMapFrame
         mk_msg.header.stamp = rospy.Time.now()
         mk_msg.type = Marker.CUBE
         mk_msg.color.a = 1
         mk_msg.color.r = 1
         mk_msg.color.g = 1
         mk_msg.scale.x = self.kWaypointRadius
         mk_msg.scale.y = self.kWaypointRadius
         mk_msg.scale.z = self.kWaypointRadius
         mk_msg.pose.position.x = current_waypoint_in_refmap[0]
         mk_msg.pose.position.y = current_waypoint_in_refmap[1]
         mk_msg.text = current_task_action.typestr()
         # some planners also get a path
         for xy in current_task_path:
             p = Point()
             p.x = xy[0]
             p.y = xy[1]
             mk_msg.points.append(p)
         # publish on relevant topics
         if current_task_action.typestr() in ["Intend", "Say"]:
             pub = self.rvo_planner_wpt_pub
             pub.publish(mk_msg)
         elif current_task_action.typestr() in ["Crawl", "Nudge"]:
             pub = self.responsive_wpt_pub
             pub.publish(mk_msg)
         else:
             rospy.logerr("Unknown task action {}".format(
                 current_task_action.typestr()))
    def replan_detector_routine(self, event=None):
        # init, set plan as soon as available
        if self.plan_executor_node.plan_being_executed is None:
            if self.newest_plan is None:
                return  # no plan is found yet, do nothing and wait
            self.plan_executor_node.switch_to_new_plan_requested = True
            self.plan_executor_node.switch_to_plan = self.newest_plan
            return
        with self.lock:
            pass
#             newest_plan = self.newest_plan
#             plan_being_executed = self.plan_executor_node.plan_being_executed
# has the global goal changed? Trigger replan
        if self.replan_due_to_new_goal_flag[0]:
            with self.lock:
                self.replan_due_to_new_goal_flag[0] = False
                self.planning_interrupt_flag[0] = True
                self.state_estimator_node.latest_state_estimate_is_stale_flag = True
                self.newest_plan = None
            with self.plan_executor_node.lock:
                self.plan_executor_node.switch_to_new_plan_requested = True
                self.plan_executor_node.switch_to_plan = None
            return
        # Have we reached the goal? Stop planning.
        if self.refmap_manager.tf_frame_in_refmap is not None and self.goal_xy_in_refmap is not None:
            robot_xy_in_refmap = Pose2D(
                self.refmap_manager.tf_frame_in_refmap)[:2]
            robot_goal_xy_in_refmap = self.goal_xy_in_refmap
            if np.linalg.norm(robot_xy_in_refmap - robot_goal_xy_in_refmap) < (
                    self.kRobotRadius + GOAL_INFLATION_RADIUS):
                if self.plan_executor_node.plan_being_executed is not None:
                    rospy.loginfo("Goal reached, exiting current plan")
                    with self.plan_executor_node.lock:
                        self.plan_executor_node.switch_to_new_plan_requested = True
                        self.plan_executor_node.switch_to_plan = None
                        self.newest_plan = None
                    with self.lock:
                        self.goal_xy_in_refmap = None
                        self.goal_ij_in_refmap = None
            # have we detected task success? Notify plan executor
            task_being_executed = self.plan_executor_node.task_being_executed
            if task_being_executed is not None:
                tbe_taskinfo = task_being_executed["taskinfo"]
                tbe_path = tbe_taskinfo["taskfullpath"]
                tbe_target_pos = tbe_path[tbe_taskinfo["tasktargetpathidx"]]
                if np.linalg.norm(robot_xy_in_refmap - tbe_target_pos) < (
                        self.kRobotRadius + GOAL_INFLATION_RADIUS):
                    with self.plan_executor_node.lock:
                        self.plan_executor_node.task_succeeded_flag = True

        # is the current plan still valid? if not trigger replan
        if False:  # TODO
            with self.plan_executor_node.lock:
                self.plan_executor_node.switch_to_new_plan_requested = True
                self.plan_executor_node.switch_to_plan = self.newest_plan
            return
        # is the newest plan very different from the current plan? trigger replan
        # is the newest plan a much better best cost? a much worse worst cost?
        if False:  # TODO
            with self.plan_executor_node.lock:
                self.plan_executor_node.switch_to_new_plan_requested = True
                self.plan_executor_node.switch_to_plan = self.newest_plan
            return
        # is the state i'm in similar to the state predicted by my plan?
        if False:  # TODO
            with self.plan_executor_node.lock:
                self.plan_executor_node.switch_to_new_plan_requested = True
                self.plan_executor_node.switch_to_plan = self.newest_plan
            return
예제 #13
0
    def publish_obstacles(self):
        with self.lock:
            if self.transport_data is None:
                return
            # non-leg obstacles
            timestamp, xx, yy, clusters, is_legs, cogs, radii, tf_rob_in_fix = self.transport_data
            # tracks
            track_ids = []
            tracks_latest_pos, tracks_color = [], []
            tracks_in_frame, tracks_velocities = [], []
            tracks_radii = []
            for trackid in self.tracker.active_tracks:
                track = self.tracker.active_tracks[trackid]
                xy = np.array(track.pos_history[-1])
                is_track_in_frame = True
                if trackid in self.tracker.latest_matches:
                    color = (0.,1.,0.,1.) # green
                elif trackid in self.tracker.new_tracks:
                    color = (0.,0.,1.,1.) # blue
                else:
                    color = (0.7, 0.7, 0.7, 1.)
                    is_track_in_frame = False
                track_ids.append(trackid)
                tracks_latest_pos.append(xy)
                tracks_color.append(color)
                tracks_in_frame.append(is_track_in_frame)
                tracks_velocities.append(track.estimate_velocity())
                tracks_radii.append(track.avg_radius())

        # publish trackedpersons
        from spencer_tracking_msgs.msg import TrackedPersons, TrackedPerson
        pub = rospy.Publisher("/tracked_persons", TrackedPersons, queue_size=1)
        tp_msg = TrackedPersons()
        tp_msg.header.frame_id = self.kFixedFrame
        tp_msg.header.stamp = timestamp
        for trackid, xy, in_frame, vel, radius in zip(track_ids, tracks_latest_pos, tracks_in_frame, tracks_velocities, tracks_radii):
#             if not in_frame:
#                 continue
            tp = TrackedPerson()
            tp.track_id = trackid
            tp.is_occluded = False
            tp.is_matched = in_frame
            tp.detection_id = trackid
            tp.pose.pose.position.x = xy[0]
            tp.pose.pose.position.y = xy[1]
            heading_angle = np.arctan2(vel[1], vel[0]) # guess heading from velocity
            from geometry_msgs.msg import Quaternion
            tp.pose.pose.orientation = Quaternion(
                *tf.transformations.quaternion_from_euler(0, 0, heading_angle))
            tp.twist.twist.linear.x = vel[0]
            tp.twist.twist.linear.y = vel[1]
            tp.twist.twist.angular.z = 0 # unknown
            tp_msg.tracks.append(tp)
        pub.publish(tp_msg)

        pub = rospy.Publisher('/obstacles', ObstacleArrayMsg, queue_size=1)
        obstacles_msg = ObstacleArrayMsg() 
        obstacles_msg.header.stamp =  timestamp
        obstacles_msg.header.frame_id = self.kFixedFrame
        for trackid, xy, in_frame, vel, radius in zip(track_ids, tracks_latest_pos, tracks_in_frame, tracks_velocities, tracks_radii):
            if not in_frame:
                continue
            # Add point obstacle
            obst = ObstacleMsg()
            obst.id = trackid
            obst.polygon.points = [Point32()]
            obst.polygon.points[0].x = xy[0]
            obst.polygon.points[0].y = xy[1]
            obst.polygon.points[0].z = 0

            obst.radius = radius

            yaw = np.arctan2(vel[1], vel[0])
            q = tf.transformations.quaternion_from_euler(0,0,yaw)
            obst.orientation = Quaternion(*q)

            obst.velocities.twist.linear.x = vel[0]
            obst.velocities.twist.linear.y = vel[1]
            obst.velocities.twist.linear.z = 0
            obst.velocities.twist.angular.x = 0
            obst.velocities.twist.angular.y = 0
            obst.velocities.twist.angular.z = 0
            obstacles_msg.obstacles.append(obst)
        pub.publish(obstacles_msg)

        pub = rospy.Publisher('/close_nonleg_obstacles', ObstacleArrayMsg, queue_size=1)
        MAX_DIST_STATIC_CLUSTERS_M = 3.
        cogs_in_fix = []
        for i in range(len(cogs)):
            cogs_in_fix.append(apply_tf(cogs[i], Pose2D(tf_rob_in_fix)))
        obstacles_msg = ObstacleArrayMsg() 
        obstacles_msg.header.stamp = timestamp
        obstacles_msg.header.frame_id = self.kFixedFrame
        for c, cog_in_fix, cog_in_rob, r, is_leg in zip(clusters, cogs_in_fix, cogs, radii, is_legs):
            if np.linalg.norm(cog_in_rob) < self.kRobotRadius:
                continue
            if len(c) < self.kMinClusterSize:
                continue
            # leg obstacles are already published in the tracked obstacles topic
            if is_leg:
                continue
            # close obstacles only
            if np.linalg.norm(cog_in_rob) > MAX_DIST_STATIC_CLUSTERS_M:
                continue
            # Add point obstacle
            obst = ObstacleMsg()
            obst.id = 0
            obst.polygon.points = [Point32()]
            obst.polygon.points[0].x = cog_in_fix[0]
            obst.polygon.points[0].y = cog_in_fix[1]
            obst.polygon.points[0].z = 0

            obst.radius = r

            yaw = 0
            q = tf.transformations.quaternion_from_euler(0,0,yaw)
            from geometry_msgs.msg import Quaternion
            obst.orientation = Quaternion(*q)

            obst.velocities.twist.linear.x = 0
            obst.velocities.twist.linear.y = 0
            obst.velocities.twist.linear.z = 0
            obst.velocities.twist.angular.x = 0
            obst.velocities.twist.angular.y = 0
            obst.velocities.twist.angular.z = 0
            obstacles_msg.obstacles.append(obst)
        pub.publish(obstacles_msg)

        pub = rospy.Publisher('/obstacle_markers', MarkerArray, queue_size=1)
        # delete all markers
        ma = MarkerArray()
        mk = Marker()
        mk.header.frame_id = self.kFixedFrame
        mk.ns = "obstacles"
        mk.id = 0
        mk.type = 0 # ARROW
        mk.action = 3 # deleteall
        ma.markers.append(mk)
        pub.publish(ma)
        # publish tracks
        ma = MarkerArray()
        id_ = 0
        # track endpoint
        for trackid, xy, in_frame, vel in zip(track_ids, tracks_latest_pos, tracks_in_frame, tracks_velocities):
            if not in_frame:
                continue
            normvel = np.linalg.norm(vel)
            if normvel == 0:
                continue
            mk = Marker()
            mk.header.frame_id = self.kFixedFrame
            mk.ns = "tracks"
            mk.id = trackid
            mk.type = 0 # ARROW
            mk.action = 0
            mk.scale.x = np.linalg.norm(vel)
            mk.scale.y = 0.1
            mk.scale.z = 0.1
            mk.color.r = color[0]
            mk.color.g = color[1]
            mk.color.b = color[2]
            mk.color.a = color[3]
            mk.frame_locked = True
            mk.pose.position.x = xy[0]
            mk.pose.position.y = xy[1]
            mk.pose.position.z = 0.03
            yaw = np.arctan2(vel[1], vel[0])
            q = tf.transformations.quaternion_from_euler(0,0,yaw)
            mk.pose.orientation = Quaternion(*q)
            ma.markers.append(mk)
        pub.publish(ma)
예제 #14
0
    def scan_callback(self, msg):
        atic = timer()
        with self.lock:
            # edge case: first callback
            if self.odom is None:
                print("odom not received yet")
                return
            if self.tf_rob_in_fix is None:
                rospy.logwarn_throttle(10., "tf_rob_in_fix not found yet")
                return
            # TODO check that odom and tf are not old

            # add current position to path history
            PATH_HISTORY_RESOLUTION = 0.05 # m
            self.tf_pastrobs_in_fix.append(self.tf_rob_in_fix)
            # downsample if too large
            if len(self.tf_pastrobs_in_fix) > N_PAST_POS:
                keep = [0]
                for i in range(len(self.tf_pastrobs_in_fix)):
                    latest_xy = np.array(self.tf_pastrobs_in_fix[keep[-1]][0][:2])
                    xy = np.array(self.tf_pastrobs_in_fix[i][0][:2])
                    if np.linalg.norm(xy-latest_xy) > PATH_HISTORY_RESOLUTION:
                        keep.append(i)
                self.tf_pastrobs_in_fix = [self.tf_pastrobs_in_fix[i] for i in keep]
            # strict x2 downsample if still too large
            if len(self.tf_pastrobs_in_fix) > 2*N_PAST_POS:
                self.tf_pastrobs_in_fix = self.tf_pastrobs_in_fix[::2]

            scan = np.array(msg.ranges, dtype=np.float32)

            # clustering
            angles = np.linspace(0, 2*np.pi, scan.shape[0]+1, dtype=np.float32)[:-1]
            xx = np.cos(angles) * scan
            yy = np.sin(angles) * scan
            tic = timer()
            clusters, _, _ = lidar_clustering.euclidean_clustering(scan, angles,
                                                             self.kEuclideanClusteringThresh)
            cluster_sizes = lidar_clustering.cluster_sizes(len(scan), clusters)
            toc = timer()
            clustering_time = toc-tic

            # filter small clusters
    #         clusters = [c for c, l in zip(clusters, cluster_sizes) if l >= self.kMinClusterSize]

            # center of gravity
            tic = timer()
            cogs = [np.array([np.mean(xx[c]), np.mean(yy[c])]) for c in clusters]
            radii = [np.max(np.sqrt((xx[c]-cog[0])**2 + (yy[c]-cog[1])**2)) for cog, c in zip(cogs, clusters)]
            toc = timer()
            cog_radii_time = toc-tic

            # in fixed frame
            cogs_in_fix = []
            for i in range(len(cogs)):
                cogs_in_fix.append(apply_tf(cogs[i], Pose2D(self.tf_rob_in_fix)))

            # legs
            is_legs = []
            for r, c, cog_in_fix in zip(radii, clusters, cogs_in_fix):
                is_leg = True if 0.03 < r and r < 0.15 and len(c) >= self.kMinClusterSize else False
                # if a reference map and localization are available, filter detections which are in map
                if self.refmap_manager.tf_frame_in_refmap is not None:
                    cog_in_refmap = apply_tf(cog_in_fix, Pose2D(self.refmap_manager.tf_frame_in_refmap))
                    ij = cog_in_refmap_ij = self.refmap_manager.map_.xy_to_ij([cog_in_refmap])[0]
                    # the distance between the c.o.g. and the nearest obstacle in the refmap
                    if self.refmap_manager.map_as_tsdf[ij[0], ij[1]] < r:
                        is_leg = False
                is_legs.append(is_leg)


            timestamp = msg.header.stamp
            self.transport_data = (timestamp, xx, yy, clusters, is_legs, cogs, radii, self.tf_rob_in_fix)

            leg_cogs_in_fix = []
            leg_radii = []
            for i in range(len(is_legs)):
                if is_legs[i]:
                    leg_cogs_in_fix.append(cogs_in_fix[i])
                    leg_radii.append(radii[i])

            # Tracks
            self.tracker.match(leg_cogs_in_fix, leg_radii, msg.header.stamp)

        # publish markers
        self.publish_markers()
        self.publish_obstacles()

        atoc = timer()
        if self.args.hz:
            print("DWA callback: {:.2f} Hz | C.O.Gs, Radii: {:.1f} ms, Clustering: {:.1f} ms".format(
                1/(atoc-atic), cog_radii_time*1000., clustering_time*1000.))
예제 #15
0
    def scan_callback(self, msg):
        atic = timer()
        # edge case: first callback
        if self.msg_prev is None:
            self.msg_prev = msg
            return
        if self.odom is None:
            print("odom not received yet")
            return
        if self.tf_rob_in_fix is None:
            print("tf_rob_in_fix not found yet")
            return
        if self.tf_goal_in_fix is None:
            self.tf_goal_in_fix = self.tf_rob_in_fix
            print("goal set")
        # TODO check that odom and tf are not old

        # measure rotation TODO
        s = np.array(msg.ranges)

        # prediction
        dt = (msg.header.stamp - self.msg_prev.header.stamp).to_sec()
        s_prev = np.array(self.msg_prev.ranges)
        ds = (s - s_prev)
        max_ds = self.kMaxObstacleVel_ms * dt
        ds_capped = ds
        ds_capped[np.abs(ds) > max_ds] = 0
        s_next = np.maximum(0, s + ds_capped).astype(np.float32)

        # cluster
        EUCLIDEAN_CLUSTERING_THRESH_M = 0.05
        angles = np.linspace(0,
                             2 * np.pi,
                             s_next.shape[0] + 1,
                             dtype=np.float32)[:-1]
        clusters, x, y = clustering.euclidean_clustering(
            s_next, angles, EUCLIDEAN_CLUSTERING_THRESH_M)
        cluster_sizes = clustering.cluster_sizes(len(s_next), clusters)
        s_next[cluster_sizes <= 3] = 25

        # dwa
        # Get state
        # goal in robot frame
        goal_in_robot_frame = apply_tf_to_pose(
            Pose2D(self.tf_goal_in_fix),
            inverse_pose2d(Pose2D(self.tf_rob_in_fix)))
        gx = goal_in_robot_frame[0]
        gy = goal_in_robot_frame[1]

        # robot speed in robot frame
        u = self.odom.twist.twist.linear.x
        v = self.odom.twist.twist.linear.y
        w = self.odom.twist.twist.angular.z

        DWA_DT = 0.5
        COMFORT_RADIUS_M = self.kRobotComfortRadius_m
        MAX_XY_VEL = 0.5
        tic = timer()
        best_u, best_v, best_score = dynamic_window.linear_dwa(
            s_next,
            angles,
            u,
            v,
            gx,
            gy,
            DWA_DT,
            DV=0.05,
            UMIN=0 if self.args.forward_only else -MAX_XY_VEL,
            UMAX=MAX_XY_VEL,
            VMIN=-MAX_XY_VEL,
            VMAX=MAX_XY_VEL,
            AMAX=10.,
            COMFORT_RADIUS_M=COMFORT_RADIUS_M,
        )
        toc = timer()
        #         print(best_u * DWA_DT, best_v * DWA_DT, best_score)
        #         print("DWA: {:.2f} Hz".format(1/(toc-tic)))

        # Slow turn towards goal
        # TODO
        best_w = 0
        WMAX = 0.5
        angle_to_goal = np.arctan2(gy, gx)  # [-pi, pi]
        if np.sqrt(gx * gx + gy * gy) > 0.5:  # turn only if goal is far away
            if np.abs(angle_to_goal) > (np.pi / 4 / 10):  # deadzone
                best_w = np.clip(angle_to_goal, -WMAX, WMAX)  # linear ramp

        if not self.STOP:
            # publish cmd_vel
            cmd_vel_msg = Twist()
            SIDEWAYS_FACTOR = 0.3 if self.args.forward_only else 1.
            cmd_vel_msg.linear.x = np.clip(best_u * 0.5, -0.3, 0.3)
            cmd_vel_msg.linear.y = np.clip(best_v * 0.5 * SIDEWAYS_FACTOR,
                                           -0.3, 0.3)
            cmd_vel_msg.angular.z = best_w
            self.cmd_vel_pub.publish(cmd_vel_msg)

        # publish cmd_vel vis
        pub = rospy.Publisher("/dwa_cmd_vel", Marker, queue_size=1)
        mk = Marker()
        mk.header.frame_id = self.kRobotFrame
        mk.ns = "arrows"
        mk.id = 0
        mk.type = 0
        mk.action = 0
        mk.scale.x = 0.02
        mk.scale.y = 0.02
        mk.color.b = 1
        mk.color.a = 1
        mk.frame_locked = True
        pt = Point()
        pt.x = 0
        pt.y = 0
        pt.z = 0.03
        mk.points.append(pt)
        pt = Point()
        pt.x = 0 + best_u * DWA_DT
        pt.y = 0 + best_v * DWA_DT
        pt.z = 0.03
        mk.points.append(pt)
        pub.publish(mk)
        pub = rospy.Publisher("/dwa_goal", Marker, queue_size=1)
        mk = Marker()
        mk.header.frame_id = self.kRobotFrame
        mk.ns = "arrows"
        mk.id = 0
        mk.type = 0
        mk.action = 0
        mk.scale.x = 0.02
        mk.scale.y = 0.02
        mk.color.g = 1
        mk.color.a = 1
        mk.frame_locked = True
        pt = Point()
        pt.x = 0
        pt.y = 0
        pt.z = 0.03
        mk.points.append(pt)
        pt = Point()
        pt.x = 0 + gx
        pt.y = 0 + gy
        pt.z = 0.03
        mk.points.append(pt)
        pub.publish(mk)
        pub = rospy.Publisher("/dwa_radius", Marker, queue_size=1)
        mk = Marker()
        mk.header.frame_id = self.kRobotFrame
        mk.ns = "radius"
        mk.id = 0
        mk.type = 3
        mk.action = 0
        mk.pose.position.z = -0.1
        mk.scale.x = COMFORT_RADIUS_M * 2
        mk.scale.y = COMFORT_RADIUS_M * 2
        mk.scale.z = 0.01
        mk.color.b = 1
        mk.color.g = 1
        mk.color.r = 1
        mk.color.a = 1
        mk.frame_locked = True
        pub.publish(mk)

        # publish scan prediction
        msg_next = deepcopy(msg)
        msg_next.ranges = s_next
        # for pretty colors
        cluster_ids = clustering.cluster_ids(len(x), clusters)
        random_map = np.arange(len(cluster_ids))
        np.random.shuffle(random_map)
        cluster_ids = random_map[cluster_ids]
        msg_next.intensities = cluster_ids
        self.pubs[0].publish(msg_next)

        # publish past
        msg_prev = deepcopy(msg)
        msg_prev.ranges = self.msg_prev.ranges
        self.pubs[1].publish(msg_prev)

        # ...

        # finally, set up for next callback
        self.msg_prev = msg

        atoc = timer()
        if self.args.hz:
            print("DWA callback: {:.2f} Hz".format(1 / (atoc - atic)))
예제 #16
0
    def publish_markers(self):
        with self.lock:
            if self.transport_data is None:
                return
            timestamp, xx, yy, clusters, is_legs, cogs, radii, tf_rob_in_fix = self.transport_data
            # transform data to fixed frame
            pose2d_rob_in_fix = Pose2D(tf_rob_in_fix)
            xy_f = apply_tf(np.vstack([xx, yy]).T, pose2d_rob_in_fix)
            cogs_f = apply_tf(np.array(cogs), pose2d_rob_in_fix)
            # past positions
            pose2d_past_in_fix = []
            if self.tf_pastrobs_in_fix:
                for tf_a in self.tf_pastrobs_in_fix[::-1]:
                    pose2d_past_in_fix.append(Pose2D(tf_a))
            # tracks
            tracks_xy, tracks_color, tracks_in_frame = [], [], []
            tracks_avg_r = []
            for trackid in self.tracker.active_tracks:
                track = self.tracker.active_tracks[trackid]
                xy = np.array(track.pos_history)
                is_track_in_frame = True
                if trackid in self.tracker.latest_matches:
                    color = (0.,1.,0.,1.) # green
                elif trackid in self.tracker.new_tracks:
                    color = (0.,0.,1.,1.) # blue
                else:
                    color = (0.7, 0.7, 0.7, 1.)
                    is_track_in_frame = False
                tracks_xy.append(xy)
                tracks_color.append(color)
                tracks_in_frame.append(is_track_in_frame)
                tracks_avg_r.append(track.avg_radius())

        pub = rospy.Publisher("/detections", Marker, queue_size=1)
        # ...

        pub = rospy.Publisher("/tracks", MarkerArray, queue_size=1)
        # delete all markers
        ma = MarkerArray()
        mk = Marker()
        mk.header.frame_id = self.kFixedFrame
        mk.ns = "tracks"
        mk.id = 0
        mk.type = 4 # LINE_STRIP
        mk.action = 3 # deleteall
        ma.markers.append(mk)
        pub.publish(ma)
        ma = MarkerArray()
        mk = Marker()
        mk.header.frame_id = self.kFixedFrame
        mk.ns = "tracks"
        mk.id = 0
        mk.type = 3 # CYLINDER
        mk.action = 3 # deleteall
        ma.markers.append(mk)
        pub.publish(ma)
        # publish tracks
        ma = MarkerArray()
        id_ = 0
        # track lines
        for color, xy in zip(tracks_color, tracks_xy):
            mk = Marker()
            mk.header.frame_id = self.kFixedFrame
            mk.ns = "tracks"
            mk.id = id_
            id_+=1
            mk.type = 4 # LINE_STRIP
            mk.action = 0
            mk.scale.x = 0.02
            mk.color.r = color[0]
            mk.color.g = color[1]
            mk.color.b = color[2]
            mk.color.a = color[3]
            mk.frame_locked = True
            for x, y in xy:
                pt = Point()
                pt.x = x
                pt.y = y
                pt.z = 0.03
                mk.points.append(pt)
            ma.markers.append(mk)
        # track endpoint
        for color, xy, r in zip(tracks_color, tracks_xy, tracks_avg_r):
            x, y = xy[-1]
            mk = Marker()
            mk.header.frame_id = self.kFixedFrame
            mk.ns = "tracks"
            mk.id = id_
            id_+=1
            mk.type = 3 # CYLINDER
            mk.action = 0
            mk.scale.x = r * 2.
            mk.scale.y = r * 2.
            mk.scale.z = 0.1
            mk.color.r = color[0]
            mk.color.g = color[1]
            mk.color.b = color[2]
            mk.color.a = color[3]
            mk.frame_locked = True
            mk.pose.position.x = x
            mk.pose.position.y = y
            mk.pose.position.z = 0.03
            ma.markers.append(mk)
        pub.publish(ma)

        pub = rospy.Publisher("/robot_track", Path, queue_size=1)
        path_msg = Path()
        path_msg.header.stamp = rospy.Time.now()
        path_msg.header.frame_id = self.kFixedFrame
        for x, y, _ in pose2d_past_in_fix:
            pose_msg = PoseStamped()
            pose_msg.header.stamp = path_msg.header.stamp # TODO log actual time
            pose_msg.header.frame_id = path_msg.header.frame_id
            pose_msg.pose.position.x = x
            pose_msg.pose.position.y = y
            path_msg.poses.append(pose_msg)
        pub.publish(path_msg)
예제 #17
0
            cmd_vel = msg
            # store cmd_vel

        if topic in joy_topics:
            joy = msg
            # detect wether autonomous motion is active or not

        # process messages
        if topic in odom_topics:
            # velocity
            current_action = np.array([  # if msg is odometry
                msg.twist.twist.linear.x, msg.twist.twist.linear.y, msg.twist.twist.angular.z])

            # position
            try:
                p2_rob_in_fix = Pose2D(bag_transformer.lookupTransform(
                    FIXED_FRAME, ROBOT_FRAME, msg.header.stamp))
            except:  # noqa
                continue

            trajectory.append(p2_rob_in_fix)

        if topic in reward_topics:
            # goal is reached
            reached = True

        if topic in goal_topics:
            goal_in_msg = np.array([msg.pose.position.x, msg.pose.position.y])
            p2_msg_in_fix = Pose2D(bag_transformer.lookupTransform(
                FIXED_FRAME, msg.header.frame_id, msg.header.stamp))
            goal_in_fix = apply_tf(goal_in_msg[None, :], p2_msg_in_fix)[0]