def control_loop(self, vr: Any, car: Car,
                     csvfile: Optional[SimpleCsvDictWriter]) -> None:
        """Control iteration. This is called on a regular basis.
    Args:
        vr -- VRepInterface object, which is an abstraction on top of the VREP
              Python API. See the class docstring near the top of this file.
        car -- Car object, providing abstractions for the car (like steering and
               velocity control).
        csvfile -- Optional to log data. None to disable.
    """
        sim_time = car.get_sim_time()
        dt = sim_time - self.last_sim_time
        self.last_sim_time = sim_time

        #
        # ASSIGNMENT: Tune / implement a better controller loop here.
        #

        # Here are two different sensors you can play with.
        # One provides an ideal shortest-distance-to-path (in meters), but isn't
        # path-following and may jump at crossings.
        # The other uses a more realistic line sensor (in pixels), which you can
        # plug your track detection algorithm into.

        line_camera_image0 = car.get_line_camera_image(0)
        # line0_err = self.get_line_camera_error(car.get_line_camera_image(0))
        line0_err = self.get_line_camera_error(self.oldimage,
                                               car.get_line_camera_image(0),
                                               self.old_lat_err)
        #line1_err = self.get_line_camera_error(line_camera_image1, car.get_line_camera_image(1), car.old_lat_err)
        line1_err = 0
        self.oldimage = line_camera_image0

        # line camera has 0.7 m field of view
        lat_err = -(np.float(line0_err) /
                    128) * 0.7  # pixel to meter conversion

        if dt > 0.0:
            lat_vel = (lat_err - self.old_lat_err) / dt
        else:
            lat_vel = 0.0
        self.old_lat_err = lat_err

        # calculate integral error
        self.int_err = self.int_err + dt * lat_err

        # Proportional gain in steering control (degrees) / lateral error (meters)
        kp = 195
        kd = 0.5 * kp  # deg per m/s
        ki = 0.4 * kp  # deg per m-s
        steer_angle = -kp * lat_err - kd * lat_vel - ki * self.int_err

        steer_angle = car.set_steering(
            steer_angle,
            dt)  # use set_steering to include servo slew rate limit
        # steer_angle = car.set_steering_fast(steer_angle,dt)  # use set_steering_fast for no delay

        # Constant speed for now. You can tune this and/or implement advanced controllers.
        car.set_speed(3)

        # Print out and record debugging info
        pos = car.get_position()
        vel_vector = car.get_velocity()
        vel = math.sqrt(vel_vector[0]**2 + vel_vector[1]**2 + vel_vector[2]**2)
        print(
            't=%6.3f (x=%5.2f, y=%5.2f, sp=%5.2f): lat_err=%5.2f, int_err=%5.2f, line0_err=%3i, steer_angle=%3.1f'
            % (sim_time, pos[0], pos[1], vel, lat_err, self.int_err,
               (line0_err or 0), steer_angle))

        if csvfile is not None:
            csvfile.writerow({
                't': sim_time,
                'x': pos[0],
                'y': pos[1],
                'linescan': line_camera_image0,
                'line_pos': line0_err +
                63,  # needs to be in camera pixels so overlaid plots work
                #'linescan_far': line_camera_image1,
                'line_pos_far': line1_err + 63,
                'speed': vel,
                'lat_err': lat_err,
                'steer_angle': steer_angle,
            })
Esempio n. 2
0
                (completed_laps + 1, car.get_sim_time() - sim_start_time))
          lap_start_time = car.get_sim_time()
          if args.csvfile and csvfile is not None and not done:
            csvfile.close()
            csvfile = SimpleCsvDictWriter(args.csvfile + '_lap' + str(completed_laps + 1) + '.csv')

        if stopping_wire.check_tripped() and completed_laps > 0:
          print("\ncrossed stopping line, lap+%.2f, total elapsed time: %.2f" %
              (car.get_sim_time() - lap_start_time, car.get_sim_time() - sim_start_time))        
          if completed_laps >= args.laps and args.laps != 0:
            done = True

        if args.synchronous:
          vr.simxSynchronousTrigger()
    except vrepInterface.VRepAPIError:
        print("\n VRepAPIError- simulation stopped. Setting speed 0\n")
        car.set_speed(0.0)  # set to zero, otherwise car will lunge at next sim start
        pass
    except KeyboardInterrupt:
      # Allow a keyboard interrupt to break out of the loop while still shutting
      # down gracefully.
      print("\ncaught keyboard interrupt, terminating control loop")
      pass
    finally:
      print("\nending simulation")
      vr.simxStopSimulation(vrep.simx_opmode_oneshot_wait)

      if csvfile is not None:
        csvfile.close()   # close file and writer
        print("csv files closed")