Ejemplo n.º 1
0
    def get_control_message(self, waypoints, vehicle_transform, current_speed,
                            speed_factor, timestamp):
        ego_location = vehicle_transform.location.as_carla_location()
        ego_yaw = np.deg2rad(zero_to_2_pi(vehicle_transform.rotation.yaw))

        # step the controller
        self.setup_mpc(waypoints)
        self.mpc.vehicle.x = ego_location.x
        self.mpc.vehicle.y = ego_location.y
        self.mpc.vehicle.yaw = ego_yaw

        try:
            self.mpc.step()
        except Exception as e:
            self._logger.info("Failed to solve MPC.")
            self._logger.info(e)
            return ControlMessage(0, 0, 1, False, False, timestamp)

        # compute pid controls
        target_speed = self.mpc.solution.vel_list[0] * speed_factor
        target_yaw = self.mpc.solution.yaw_list[0]
        target_steer_rad = self.mpc.horizon_steer[0]  # in rad
        steer = self.__rad2steer(target_steer_rad)  # [-1.0, 1.0]
        throttle, brake = self.__get_throttle_brake_without_factor(
            current_speed, target_speed)

        # send controls
        return ControlMessage(steer, throttle, brake, False, False, timestamp)
Ejemplo n.º 2
0
    def get_control_message(self, wp_angle, wp_angle_speed, speed_factor,
                            current_speed, timestamp):
        current_speed = max(current_speed, 0)
        steer = self._flags.steer_gain * wp_angle
        if steer > 0:
            steer = min(steer, 1)
        else:
            steer = max(steer, -1)

        # Don't go to fast around corners
        if math.fabs(wp_angle_speed) < 0.1:
            target_speed_adjusted = self._flags.target_speed * speed_factor / 2
        else:
            target_speed_adjusted = self._flags.target_speed * speed_factor

        self._pid.target = target_speed_adjusted
        pid_gain = self._pid(feedback=current_speed)
        throttle = min(max(self._flags.default_throttle - 1.3 * pid_gain, 0),
                       self._flags.throttle_max)

        if pid_gain > 0.5:
            brake = min(0.35 * pid_gain * self._flags.brake_strength, 1)
        else:
            brake = 0

        return ControlMessage(steer, throttle, brake, False, False, timestamp)
Ejemplo n.º 3
0
 def get_control_message(self, wp_angle, wp_angle_speed, speed_factor,
                         current_speed, target_speed, timestamp):
     current_speed = max(current_speed, 0)
     steer = self.__get_steer(wp_angle)
     throttle, brake = self.__get_throttle_brake(current_speed,
                                                 target_speed,
                                                 wp_angle_speed,
                                                 speed_factor)
     return ControlMessage(steer, throttle, brake, False, False, timestamp)
Ejemplo n.º 4
0
    def on_watermark(self, timestamp, control_stream):
        """Computes and sends the control command on the control stream.

        Invoked when all input streams have received a watermark.

        Args:
            timestamp (:py:class:`erdos.timestamp.Timestamp`): The timestamp of
                the watermark.
        """
        self._logger.debug('@{}: received watermark'.format(timestamp))
        pose_msg = self._pose_msgs.popleft()
        vehicle_transform = pose_msg.data.transform
        # Vehicle sped in m/s
        current_speed = pose_msg.data.forward_speed
        waypoint_msg = self._waypoint_msgs.popleft()
        if current_speed < 0:
            self._logger.warning(
                'Current speed is negative: {}'.format(current_speed))
            current_speed = 0

        waypoints = waypoint_msg.waypoints
        self._logger.debug("@{} Received waypoints of length: {}".format(
            timestamp, len(waypoints)))
        if len(waypoints) > 0:
            pid_steer_wp = self._flags.pid_steer_wp
            pid_speed_wp = self._flags.pid_speed_wp
            if self._flags.carla_mode == "pseudo-asynchronous":
                # The control runs at a higher frequency, we need to choose
                # based on the current speed.
                pid_speed_wp = int(current_speed / 3)
                pid_steer_wp = 2 * pid_speed_wp
            # The operator picks the wp_num_steer-th waypoint to compute the
            # angle it has to steer by when taking a turn.
            # Use 10th waypoint for steering.
            _, wp_angle_steer = \
                pylot.planning.utils.compute_waypoint_vector_and_angle(
                    vehicle_transform, waypoints, pid_steer_wp)
            # Use 5th waypoint for speed.
            _, wp_angle_speed = \
                pylot.planning.utils.compute_waypoint_vector_and_angle(
                    vehicle_transform, waypoints, pid_speed_wp)
            target_speed = waypoint_msg.target_speeds[min(
                len(waypoint_msg.target_speeds) - 1, self._flags.pid_speed_wp)]
            throttle, brake = pylot.control.utils.compute_throttle_and_brake(
                self._pid, current_speed, target_speed, self._flags)
            steer = pylot.control.utils.radians_to_steer(
                wp_angle_steer, self._flags.steer_gain)
        else:
            self._logger.warning('Braking! No more waypoints to follow.')
            throttle, brake = 0.0, 0.5
            steer = 0.0
        self._logger.debug(
            '@{}: speed {}, location {}, steer {}, throttle {}, brake {}'.
            format(timestamp, current_speed, vehicle_transform, steer,
                   throttle, brake))
        control_stream.send(
            ControlMessage(steer, throttle, brake, False, False, timestamp))
Ejemplo n.º 5
0
 def on_can_bus_update(self, msg):
     self._latest_speed = msg.data.forward_speed
     self._vehicle_transform = msg.data.transform
     throttle = 0.0
     brake = 0
     steer = 0
     if self._last_waypoint_msg:
         throttle, brake = self._get_throttle_brake(
             self._last_waypoint_msg.target_speed)
         steer = self._get_steering(self._last_waypoint_msg.waypoints[0])
     control_msg = ControlMessage(steer, throttle, brake, False, False,
                                  msg.timestamp)
     self.get_output_stream('control_stream').send(control_msg)
Ejemplo n.º 6
0
    def on_watermark(self, timestamp, control_stream):
        """Invoked when the input stream has received a watermark.

        The method sends a control message.

        Args:
            timestamp (:py:class:`erdos.timestamp.Timestamp`): The timestamp of
                the watermark.
        """
        # The control message is ignored by the bridge operator because
        # data gathering is conducted using auto pilot. Send default control
        # message.
        control_msg = ControlMessage(0, 0, 0, False, False, timestamp)
        control_stream.send(control_msg)
Ejemplo n.º 7
0
    def get_control_message(self, waypoints, target_speeds, vehicle_transform,
                            current_speed, timestamp):
        self.setup_mpc(waypoints, target_speeds)
        self._mpc.vehicle.x = vehicle_transform.location.x
        self._mpc.vehicle.y = vehicle_transform.location.y
        self._mpc.vehicle.yaw = np.deg2rad(
            zero_to_2_pi(vehicle_transform.rotation.yaw))

        try:
            self._mpc.step()
        except Exception as e:
            self._logger.error('Failed to solve MPC. Emergency braking.')
            self._logger.error(e)
            return ControlMessage(0, 0, 1, False, False, timestamp)

        # Compute pid controls.
        target_speed = self._mpc.solution.vel_list[-1]
        target_steer_rad = self._mpc.horizon_steer[0]  # in rad
        steer = pylot.control.utils.radians_to_steer(target_steer_rad,
                                                     self._flags.steer_gain)
        throttle, brake = pylot.control.utils.compute_throttle_and_brake(
            self._pid, current_speed, target_speed, self._flags, self._logger)
        return ControlMessage(steer, throttle, brake, False, False, timestamp)
Ejemplo n.º 8
0
    def on_watermark(self, timestamp: Timestamp, control_stream: WriteStream):
        """Invoked when the input stream has received a watermark.

        The method sends a control message.

        Args:
            timestamp (:py:class:`erdos.timestamp.Timestamp`): The timestamp of
                the watermark.
        """
        self._logger.debug('@{}: received watermark'.format(timestamp))
        # The control message is ignored by the bridge operator because
        # data gathering is conducted using auto pilot.
        # Send the control that the vehicle is currently applying.
        vehicle_control = self._vehicle.get_control()
        control_msg = ControlMessage(vehicle_control.steer,
                                     vehicle_control.throttle,
                                     vehicle_control.brake,
                                     vehicle_control.hand_brake,
                                     vehicle_control.reverse, timestamp)
        control_stream.send(control_msg)
        control_stream.send(erdos.WatermarkMessage(timestamp))
Ejemplo n.º 9
0
    def on_watermark(self, timestamp: Timestamp, control_stream: WriteStream):
        """Computes and sends the control command on the control stream.

        Invoked when all input streams have received a watermark.

        Args:
            timestamp (:py:class:`erdos.timestamp.Timestamp`): The timestamp of
                the watermark.
        """
        self._logger.debug('@{}: received watermark'.format(timestamp))
        # pose_msg = self._pose_msgs.popleft()
        # ego_transform = pose_msg.data.transform
        # # Vehicle speed in m/s.
        # current_speed = pose_msg.data.forward_speed
        # waypoints = self._waypoint_msgs.popleft().waypoints
        # try:
        #     angle_steer = waypoints.get_angle(
        #         ego_transform, self._flags.min_pid_steer_waypoint_distance)
        #     target_speed = waypoints.get_target_speed(
        #         ego_transform, self._flags.min_pid_speed_waypoint_distance)
        #     throttle, brake = pylot.control.utils.compute_throttle_and_brake(
        #         self._pid, current_speed, target_speed, self._flags,
        #         self._logger)
        #     steer = pylot.control.utils.radians_to_steer(
        #         angle_steer, self._flags.steer_gain)
        # except ValueError:
        #     self._logger.warning('Braking! No more waypoints to follow.')
        #     throttle, brake = 0.0, 0.5
        #     steer = 0.0
        # self._logger.debug(
        #     '@{}: speed {}, location {}, steer {}, throttle {}, brake {}'.
        #     format(timestamp, current_speed, ego_transform, steer, throttle,
        #            brake))
        steer = 0.0
        throttle = 1.0
        brake = 0.0
        control_stream.send(
            ControlMessage(steer, throttle, brake, False, False, timestamp))
        control_stream.send(erdos.WatermarkMessage(timestamp))
Ejemplo n.º 10
0
 def on_watermark(self, timestamp, control_stream):
     # The control message is ignored by the bridge operator because
     # data gathering is conducted using auto pilot. Send default control
     # message.
     control_msg = ControlMessage(0, 0, 0, False, False, timestamp)
     control_stream.send(control_msg)
Ejemplo n.º 11
0
 def on_watermark(self, msg):
     control_msg = ControlMessage(
         0, 0, 0, False, False, msg.timestamp)
     self.get_output_stream('control_stream').send(control_msg)
Ejemplo n.º 12
0
    def run(self):
        # Initialize all the publishers.
        self.enable_pub = rospy.Publisher(ENABLE_TOPIC, Empty, queue_size=10)
        self.disable_pub = rospy.Publisher(DISABLE_TOPIC, Empty, queue_size=10)
        self.throttle_pub = rospy.Publisher(THROTTLE_TOPIC,
                                            ThrottleCmd,
                                            queue_size=10)
        self.brake_pub = rospy.Publisher(BRAKE_TOPIC, BrakeCmd, queue_size=10)
        self.steering_pub = rospy.Publisher(STEERING_TOPIC,
                                            SteeringCmd,
                                            queue_size=10)
        rospy.init_node(self.config.name, anonymous=True, disable_signals=True)

        # Enable the ADAS.
        #self.enable_pub.publish(Empty())

        # Pull from the control stream and publish messages continuously.
        r = rospy.Rate(ROS_FREQUENCY)
        last_control_message = ControlMessage(
            steer=0,
            throttle=0,
            brake=0,
            hand_brake=False,
            reverse=False,
            timestamp=erdos.Timestamp(coordinates=[0]))
        while not rospy.is_shutdown():
            control_message = self._control_stream.try_read()
            if control_message is None or isinstance(control_message,
                                                     erdos.WatermarkMessage):
                control_message = last_control_message
            else:
                last_control_message = control_message

            # Send all the commands from a single ControlMessage one after
            # the other.
            steer_angle = control_message.steer * STEERING_ANGLE_MAX
            self._logger.debug("The steering angle is {}".format(steer_angle))
            steer_message = SteeringCmd(enable=True,
                                        clear=True,
                                        ignore=False,
                                        quiet=False,
                                        count=0,
                                        steering_wheel_angle_cmd=steer_angle,
                                        steering_wheel_angle_velocity=0.0)
            self.steering_pub.publish(steer_message)

            throttle_message = ThrottleCmd(
                enable=True,
                ignore=False,
                count=0,
                pedal_cmd_type=ThrottleCmd.CMD_PERCENT,
                pedal_cmd=control_message.throttle)
            self.throttle_pub.publish(throttle_message)

            brake_message = BrakeCmd(enable=True,
                                     ignore=False,
                                     count=0,
                                     pedal_cmd_type=BrakeCmd.CMD_PERCENT,
                                     pedal_cmd=control_message.brake)
            self.brake_pub.publish(brake_message)

            # Run at frequency
            r.sleep()
Ejemplo n.º 13
0
    def compute_command(self, can_bus_msg, waypoint_msg, tl_msg, obstacles_msg,
                        pc_msg, depth_msg, timestamp):
        start_time = time.time()
        vehicle_transform = can_bus_msg.data.transform
        vehicle_speed = can_bus_msg.data.forward_speed
        wp_angle = waypoint_msg.wp_angle
        wp_vector = waypoint_msg.wp_vector
        wp_angle_speed = waypoint_msg.wp_angle_speed
        target_speed = waypoint_msg.target_speed
        # Transform point cloud to camera coordinates.
        point_cloud = None
        if pc_msg:
            point_cloud = pylot.simulation.utils.lidar_point_cloud_to_camera_coordinates(
                pc_msg.point_cloud)
        depth_frame = None
        if depth_msg:
            depth_frame = depth_msg.frame

        traffic_lights = self.__transform_tl_output(tl_msg, vehicle_transform,
                                                    point_cloud, depth_frame)
        game_time = timestamp.coordinates[0]
        if len(traffic_lights) > 0:
            self._last_traffic_light_game_time = game_time
        (pedestrians,
         vehicles) = self.__transform_detector_output(obstacles_msg,
                                                      vehicle_transform,
                                                      point_cloud, depth_frame)

        # if self._map.is_on_opposite_lane(vehicle_transform):
        #     # Ignore obstacles
        #     self._logger.info('Ego-vehicle {} on opposite lange'.format(
        #         vehicle_transform))
        #     pedestrians = []
        #     vehicles = []
        #     traffic_lights = []

        self._logger.info('{} Current speed {} and location {}'.format(
            timestamp, vehicle_speed, vehicle_transform))
        self._logger.info('{} Pedestrians {}'.format(timestamp, pedestrians))
        self._logger.info('{} Vehicles {}'.format(timestamp, vehicles))

        speed_factor, _ = self.__stop_for_agents(vehicle_transform, wp_angle,
                                                 wp_vector, vehicles,
                                                 pedestrians, traffic_lights,
                                                 timestamp)

        new_target_speed = self.reduce_speed_when_approaching_intersection(
            vehicle_transform, vehicle_speed, target_speed, game_time)
        if new_target_speed != target_speed:
            self._logger.info(
                'Proximity to intersection, reducing speed from {} to {}'.
                format(target_speed, new_target_speed))
            target_speed = new_target_speed

        self._logger.info('{} Current speed factor {}'.format(
            timestamp, speed_factor))

        control_msg = self.get_control_message(wp_angle, wp_angle_speed,
                                               speed_factor, vehicle_speed,
                                               target_speed, timestamp)

        if control_msg.throttle > 0.001:
            self._last_moving_time = game_time
            self._num_control_override = 0

        if self._num_control_override > 0:
            self._num_control_override -= 1
            control_msg.throttle = 0.75

        # Might be stuck because of a faulty detector.
        # Override control message if we haven't been moving for a while.
        if game_time - self._last_moving_time > 30000:
            self._num_control_override = 6
            control_msg = ControlMessage(0, 0.75, 0, False, False, timestamp)

        # Get runtime in ms.
        runtime = (time.time() - start_time) * 1000
        self._csv_logger.info('{},{},"{}",{}'.format(time_epoch_ms(),
                                                     self.name, timestamp,
                                                     runtime))

        self.get_output_stream('control_stream').send(control_msg)
    def on_watermark(self, timestamp, control_stream):
        """ The callback function invoked upon receipt of a WatermarkMessage.

        The function uses the latest location of the vehicle and drives to the
        next waypoint, while doing either a stop or a swerve upon the
        detection of a person.

        Args:
            timestamp: Timestamp for which the WatermarkMessage was received.
            control_stream: Output stream on which the callback can write to.
        """
        self._logger.debug('@{}: received watermark'.format(timestamp))
        can_bus_msg = self._can_bus_msgs.popleft()
        ground_obstacles_msg = self._ground_obstacles_msgs.popleft()
        obstacle_msg = self._obstacle_msgs.popleft()

        self._logger.debug(
            "The vehicle is travelling at a speed of {} m/s.".format(
                can_bus_msg.data.forward_speed))

        ego_transform = can_bus_msg.data.transform
        ego_location = ego_transform.location
        ego_wp = self._map.get_waypoint(ego_location.as_carla_location())

        people_obstacles = [
            obstacle for obstacle in ground_obstacles_msg.obstacles
            if obstacle.label == 'person'
        ]
        # Heuristic to tell us how far away do we detect the person.
        for person in people_obstacles:
            person_wp = self._map.get_waypoint(
                person.transform.location.as_carla_location(),
                project_to_road=False)
            if person_wp and person_wp.road_id == ego_wp.road_id:
                for obstacle in obstacle_msg.obstacles:
                    if obstacle.label == 'person':
                        self._csv_logger.info(
                            "{},{},detected a person {}m away".format(
                                self.config.name, self.SPEED,
                                person.distance(ego_transform)))
                        self._csv_logger.info(
                            "{},{},vehicle speed {} m/s.".format(
                                self.config.name, self.SPEED,
                                can_bus_msg.data.forward_speed))

        # Figure out the location of the ego vehicle and compute the next
        # waypoint.
        if self._goal_reached or ego_location.distance(
                self._goal) <= self.GOAL_DISTANCE:
            self._logger.info(
                "The distance was {} and we reached the goal.".format(
                    ego_location.distance(self._goal)))
            control_stream.send(
                ControlMessage(0.0, 0.0, 1.0, True, False, timestamp))
            self._goal_reached = True
        else:
            person_detected = False
            for person in people_obstacles:
                person_wp = self._map.get_waypoint(
                    person.transform.location.as_carla_location(),
                    project_to_road=False)
                if person_wp and ego_location.distance(
                        person.transform.location) <= self.DETECTION_DISTANCE:
                    person_detected = True
                    break

            if person_detected and self._flags.avoidance_behavior == 'stop':
                control_stream.send(
                    ControlMessage(0.0, 0.0, 1.0, True, False, timestamp))
                return

            # Get the waypoint that is SAMPLING_DISTANCE away.
            sample_distance = self.SAMPLING_DISTANCE if \
                ego_transform.forward_vector.x > 0 else \
                -1 * self.SAMPLING_DISTANCE
            steer_loc = ego_location + pylot.utils.Location(
                x=sample_distance, y=0, z=0)
            wp_steer = self._map.get_waypoint(steer_loc.as_carla_location())

            in_swerve = False
            fwd_vector = wp_steer.transform.get_forward_vector()
            waypoint_fwd = [fwd_vector.x, fwd_vector.y, fwd_vector.z]
            if person_detected:
                # If a pedestrian was detected, make sure we're driving on the
                # wrong direction.
                if np.dot(ego_transform.forward_vector.as_numpy_array(),
                          waypoint_fwd) > 0:
                    # We're not driving in the wrong direction, get left
                    # lane waypoint.
                    if wp_steer.get_left_lane():
                        wp_steer = wp_steer.get_left_lane()
                        in_swerve = True
                else:
                    # We're driving in the right direction, continue driving.
                    pass
            else:
                # The person was not detected, come back from the swerve.
                if np.dot(ego_transform.forward_vector.as_numpy_array(),
                          waypoint_fwd) < 0:
                    # We're driving in the wrong direction, get the left lane
                    # waypoint.
                    if wp_steer.get_left_lane():
                        wp_steer = wp_steer.get_left_lane()
                        in_swerve = True
                else:
                    # We're driving in the right direction, continue driving.
                    pass

            self._world.debug.draw_point(wp_steer.transform.location,
                                         size=0.2,
                                         life_time=30000.0)

            wp_steer_vector, _, wp_steer_angle = \
                ego_transform.get_vector_magnitude_angle(
                    pylot.utils.Location.from_carla_location(
                        wp_steer.transform.location))
            current_speed = max(0, can_bus_msg.data.forward_speed)
            steer = pylot.control.utils.radians_to_steer(
                wp_steer_angle, self._flags.steer_gain)
            # target_speed = self.SPEED if not in_swerve else self.SPEED / 5.0
            target_speed = self.SPEED
            throttle, brake = pylot.control.utils.compute_throttle_and_brake(
                self._pid, current_speed, target_speed, self._flags)

            control_stream.send(
                ControlMessage(steer, throttle, brake, False, False,
                               timestamp))
Ejemplo n.º 15
0
    def on_watermark(self, timestamp, control_stream):
        """Computes and sends the control command on the control stream.

        Invoked when all input streams have received a watermark.

        Args:
            timestamp (:py:class:`erdos.timestamp.Timestamp`): The timestamp of
                the watermark.
        """
        self._logger.debug('@{}: received watermark'.format(timestamp))
        pose_msg = self._pose_msgs.popleft()
        vehicle_transform = pose_msg.data.transform
        # Vehicle sped in m/s
        current_speed = pose_msg.data.forward_speed
        waypoint_msg = self._waypoint_msgs.popleft()
        if current_speed < 0:
            self._logger.warning(
                'Current speed is negative: {}'.format(current_speed))
            current_speed = 0

        waypoints = waypoint_msg.waypoints
        self._logger.debug("@{} Received waypoints of length: {}".format(
            timestamp, len(waypoints)))
        if len(waypoints) > 0:
            pid_steer_wp, pid_speed_wp = None, None
            for index, _wp in enumerate(waypoints):
                # Break if we have found both the desired waypoints.
                if pid_steer_wp and pid_speed_wp:
                    break
                ego_distance = _wp.location.distance(
                    vehicle_transform.location)
                if pid_steer_wp is None and (ego_distance >
                                             self._flags.pid_steer_wp):
                    pid_steer_wp = index

                if pid_speed_wp is None and (ego_distance >
                                             self._flags.pid_speed_wp):
                    pid_speed_wp = index

            if pid_steer_wp is None:
                pid_steer_wp = -1
            if pid_speed_wp is None:
                pid_speed_wp = -1
            _, wp_angle_steer = \
                pylot.planning.utils.compute_waypoint_vector_and_angle(
                    vehicle_transform, waypoints, pid_steer_wp)
            # Use 5th waypoint for speed.
            _, wp_angle_speed = \
                pylot.planning.utils.compute_waypoint_vector_and_angle(
                    vehicle_transform, waypoints, pid_speed_wp)
            target_speed = waypoint_msg.target_speeds[min(
                len(waypoint_msg.target_speeds) - 1, self._flags.pid_speed_wp)]
            throttle, brake = pylot.control.utils.compute_throttle_and_brake(
                self._pid, current_speed, target_speed, self._flags)
            steer = pylot.control.utils.radians_to_steer(
                wp_angle_steer, self._flags.steer_gain)
        else:
            self._logger.warning('Braking! No more waypoints to follow.')
            throttle, brake = 0.0, 0.5
            steer = 0.0
        self._logger.debug(
            '@{}: speed {}, location {}, steer {}, throttle {}, brake {}'.
            format(timestamp, current_speed, vehicle_transform, steer,
                   throttle, brake))
        control_stream.send(
            ControlMessage(steer, throttle, brake, False, False, timestamp))