|  |  |  | #!/usr/bin/env python3
 | 
					
						
							|  |  |  | # type: ignore
 | 
					
						
							|  |  |  | import time
 | 
					
						
							|  |  |  | import math
 | 
					
						
							|  |  |  | import atexit
 | 
					
						
							|  |  |  | import numpy as np
 | 
					
						
							|  |  |  | import threading
 | 
					
						
							|  |  |  | import random
 | 
					
						
							|  |  |  | import cereal.messaging as messaging
 | 
					
						
							|  |  |  | import argparse
 | 
					
						
							|  |  |  | from common.params import Params
 | 
					
						
							|  |  |  | from common.realtime import Ratekeeper
 | 
					
						
							|  |  |  | from lib.can import can_function, sendcan_function
 | 
					
						
							|  |  |  | from lib.helpers import FakeSteeringWheel
 | 
					
						
							|  |  |  | from selfdrive.car.honda.values import CruiseButtons
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | parser = argparse.ArgumentParser(description='Bridge between CARLA and openpilot.')
 | 
					
						
							|  |  |  | parser.add_argument('--autopilot', action='store_true')
 | 
					
						
							|  |  |  | parser.add_argument('--joystick', action='store_true')
 | 
					
						
							|  |  |  | parser.add_argument('--realmonitoring', action='store_true')
 | 
					
						
							|  |  |  | args = parser.parse_args()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pm = messaging.PubMaster(['frame', 'sensorEvents', 'can'])
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | W, H = 1164, 874
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def cam_callback(image):
 | 
					
						
							|  |  |  |   img = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
 | 
					
						
							|  |  |  |   img = np.reshape(img, (H, W, 4))
 | 
					
						
							|  |  |  |   img = img[:, :, [0, 1, 2]].copy()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   dat = messaging.new_message('frame')
 | 
					
						
							|  |  |  |   dat.frame = {
 | 
					
						
							|  |  |  |     "frameId": image.frame,
 | 
					
						
							|  |  |  |     "image": img.tostring(),
 | 
					
						
							|  |  |  |     "transform": [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
 | 
					
						
							|  |  |  |   }
 | 
					
						
							|  |  |  |   pm.send('frame', dat)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def imu_callback(imu):
 | 
					
						
							|  |  |  |   #print(imu, imu.accelerometer)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   dat = messaging.new_message('sensorEvents', 2)
 | 
					
						
							|  |  |  |   dat.sensorEvents[0].sensor = 4
 | 
					
						
							|  |  |  |   dat.sensorEvents[0].type = 0x10
 | 
					
						
							|  |  |  |   dat.sensorEvents[0].init('acceleration')
 | 
					
						
							|  |  |  |   dat.sensorEvents[0].acceleration.v = [imu.accelerometer.x, imu.accelerometer.y, imu.accelerometer.z]
 | 
					
						
							|  |  |  |   # copied these numbers from locationd
 | 
					
						
							|  |  |  |   dat.sensorEvents[1].sensor = 5
 | 
					
						
							|  |  |  |   dat.sensorEvents[1].type = 0x10
 | 
					
						
							|  |  |  |   dat.sensorEvents[1].init('gyroUncalibrated')
 | 
					
						
							|  |  |  |   dat.sensorEvents[1].gyroUncalibrated.v = [imu.gyroscope.x, imu.gyroscope.y, imu.gyroscope.z]
 | 
					
						
							|  |  |  |   pm.send('sensorEvents', dat)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def health_function():
 | 
					
						
							|  |  |  |   pm = messaging.PubMaster(['health'])
 | 
					
						
							|  |  |  |   rk = Ratekeeper(1.0)
 | 
					
						
							|  |  |  |   while 1:
 | 
					
						
							|  |  |  |     dat = messaging.new_message('health')
 | 
					
						
							|  |  |  |     dat.valid = True
 | 
					
						
							|  |  |  |     dat.health = {
 | 
					
						
							|  |  |  |       'ignitionLine': True,
 | 
					
						
							|  |  |  |       'hwType': "greyPanda",
 | 
					
						
							|  |  |  |       'controlsAllowed': True
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  |     pm.send('health', dat)
 | 
					
						
							|  |  |  |     rk.keep_time()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def fake_driver_monitoring():
 | 
					
						
							|  |  |  |   if args.realmonitoring:
 | 
					
						
							|  |  |  |     return
 | 
					
						
							|  |  |  |   pm = messaging.PubMaster(['driverState'])
 | 
					
						
							|  |  |  |   while 1:
 | 
					
						
							|  |  |  |     dat = messaging.new_message('driverState')
 | 
					
						
							|  |  |  |     dat.driverState.faceProb = 1.0
 | 
					
						
							|  |  |  |     pm.send('driverState', dat)
 | 
					
						
							|  |  |  |     time.sleep(0.1)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def go(q):
 | 
					
						
							|  |  |  |   threading.Thread(target=health_function).start()
 | 
					
						
							|  |  |  |   threading.Thread(target=fake_driver_monitoring).start()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   client = carla.Client("127.0.0.1", 2000)
 | 
					
						
							|  |  |  |   client.set_timeout(5.0)
 | 
					
						
							|  |  |  |   world = client.load_world('Town04')
 | 
					
						
							|  |  |  |   settings = world.get_settings()
 | 
					
						
							|  |  |  |   settings.fixed_delta_seconds = 0.05
 | 
					
						
							|  |  |  |   world.apply_settings(settings)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   weather = carla.WeatherParameters(
 | 
					
						
							|  |  |  |       cloudyness=0.1,
 | 
					
						
							|  |  |  |       precipitation=0.0,
 | 
					
						
							|  |  |  |       precipitation_deposits=0.0,
 | 
					
						
							|  |  |  |       wind_intensity=0.0,
 | 
					
						
							|  |  |  |       sun_azimuth_angle=15.0,
 | 
					
						
							|  |  |  |       sun_altitude_angle=75.0)
 | 
					
						
							|  |  |  |   world.set_weather(weather)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   blueprint_library = world.get_blueprint_library()
 | 
					
						
							|  |  |  |   # for blueprint in blueprint_library.filter('sensor.*'):
 | 
					
						
							|  |  |  |   #    print(blueprint.id)
 | 
					
						
							|  |  |  |   # exit(0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   world_map = world.get_map()
 | 
					
						
							|  |  |  |   vehicle_bp = random.choice(blueprint_library.filter('vehicle.tesla.*'))
 | 
					
						
							|  |  |  |   vehicle = world.spawn_actor(vehicle_bp, world_map.get_spawn_points()[16])
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # make tires less slippery
 | 
					
						
							|  |  |  |   wheel_control = carla.WheelPhysicsControl(tire_friction=5)
 | 
					
						
							|  |  |  |   physics_control = vehicle.get_physics_control()
 | 
					
						
							|  |  |  |   physics_control.mass = 1326
 | 
					
						
							|  |  |  |   physics_control.wheels = [wheel_control]*4
 | 
					
						
							|  |  |  |   physics_control.torque_curve = [[20.0, 500.0], [5000.0, 500.0]]
 | 
					
						
							|  |  |  |   physics_control.gear_switch_time = 0.0
 | 
					
						
							|  |  |  |   vehicle.apply_physics_control(physics_control)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if args.autopilot:
 | 
					
						
							|  |  |  |     vehicle.set_autopilot(True)
 | 
					
						
							|  |  |  |   # print(vehicle.get_speed_limit())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   blueprint = blueprint_library.find('sensor.camera.rgb')
 | 
					
						
							|  |  |  |   blueprint.set_attribute('image_size_x', str(W))
 | 
					
						
							|  |  |  |   blueprint.set_attribute('image_size_y', str(H))
 | 
					
						
							|  |  |  |   blueprint.set_attribute('fov', '70')
 | 
					
						
							|  |  |  |   blueprint.set_attribute('sensor_tick', '0.05')
 | 
					
						
							|  |  |  |   transform = carla.Transform(carla.Location(x=0.8, z=1.45))
 | 
					
						
							|  |  |  |   camera = world.spawn_actor(blueprint, transform, attach_to=vehicle)
 | 
					
						
							|  |  |  |   camera.listen(cam_callback)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # reenable IMU
 | 
					
						
							|  |  |  |   imu_bp = blueprint_library.find('sensor.other.imu')
 | 
					
						
							|  |  |  |   imu = world.spawn_actor(imu_bp, transform, attach_to=vehicle)
 | 
					
						
							|  |  |  |   imu.listen(imu_callback)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def destroy():
 | 
					
						
							|  |  |  |     print("clean exit")
 | 
					
						
							|  |  |  |     imu.destroy()
 | 
					
						
							|  |  |  |     camera.destroy()
 | 
					
						
							|  |  |  |     vehicle.destroy()
 | 
					
						
							|  |  |  |     print("done")
 | 
					
						
							|  |  |  |   atexit.register(destroy)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # can loop
 | 
					
						
							|  |  |  |   sendcan = messaging.sub_sock('sendcan')
 | 
					
						
							|  |  |  |   rk = Ratekeeper(100, print_delay_threshold=0.05)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # init
 | 
					
						
							|  |  |  |   A_throttle = 2.
 | 
					
						
							|  |  |  |   A_brake = 2.
 | 
					
						
							|  |  |  |   A_steer_torque = 1.
 | 
					
						
							|  |  |  |   fake_wheel = FakeSteeringWheel()
 | 
					
						
							|  |  |  |   is_openpilot_engaged = False
 | 
					
						
							|  |  |  |   in_reverse = False
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   throttle_out = 0
 | 
					
						
							|  |  |  |   brake_out = 0
 | 
					
						
							|  |  |  |   steer_angle_out = 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while 1:
 | 
					
						
							|  |  |  |     cruise_button = 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # check for a input message, this will not block
 | 
					
						
							|  |  |  |     if not q.empty():
 | 
					
						
							|  |  |  |       print("here")
 | 
					
						
							|  |  |  |       message = q.get()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       m = message.split('_')
 | 
					
						
							|  |  |  |       if m[0] == "steer":
 | 
					
						
							|  |  |  |         steer_angle_out = float(m[1])
 | 
					
						
							|  |  |  |         fake_wheel.set_angle(steer_angle_out)  # touching the wheel overrides fake wheel angle
 | 
					
						
							|  |  |  |         # print(" === steering overriden === ")
 | 
					
						
							|  |  |  |       if m[0] == "throttle":
 | 
					
						
							|  |  |  |         throttle_out = float(m[1]) / 100.
 | 
					
						
							|  |  |  |         if throttle_out > 0.3:
 | 
					
						
							|  |  |  |           cruise_button = CruiseButtons.CANCEL
 | 
					
						
							|  |  |  |           is_openpilot_engaged = False
 | 
					
						
							|  |  |  |       if m[0] == "brake":
 | 
					
						
							|  |  |  |         brake_out = float(m[1]) / 100.
 | 
					
						
							|  |  |  |         if brake_out > 0.3:
 | 
					
						
							|  |  |  |           cruise_button = CruiseButtons.CANCEL
 | 
					
						
							|  |  |  |           is_openpilot_engaged = False
 | 
					
						
							|  |  |  |       if m[0] == "reverse":
 | 
					
						
							|  |  |  |         in_reverse = not in_reverse
 | 
					
						
							|  |  |  |         cruise_button = CruiseButtons.CANCEL
 | 
					
						
							|  |  |  |         is_openpilot_engaged = False
 | 
					
						
							|  |  |  |       if m[0] == "cruise":
 | 
					
						
							|  |  |  |         if m[1] == "down":
 | 
					
						
							|  |  |  |           cruise_button = CruiseButtons.DECEL_SET
 | 
					
						
							|  |  |  |           is_openpilot_engaged = True
 | 
					
						
							|  |  |  |         if m[1] == "up":
 | 
					
						
							|  |  |  |           cruise_button = CruiseButtons.RES_ACCEL
 | 
					
						
							|  |  |  |           is_openpilot_engaged = True
 | 
					
						
							|  |  |  |         if m[1] == "cancel":
 | 
					
						
							|  |  |  |           cruise_button = CruiseButtons.CANCEL
 | 
					
						
							|  |  |  |           is_openpilot_engaged = False
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     vel = vehicle.get_velocity()
 | 
					
						
							|  |  |  |     speed = math.sqrt(vel.x**2 + vel.y**2 + vel.z**2) * 3.6
 | 
					
						
							|  |  |  |     can_function(pm, speed, fake_wheel.angle, rk.frame, cruise_button=cruise_button, is_engaged=is_openpilot_engaged)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if rk.frame % 1 == 0:  # 20Hz?
 | 
					
						
							|  |  |  |       throttle_op, brake_op, steer_torque_op = sendcan_function(sendcan)
 | 
					
						
							|  |  |  |       # print(" === torq, ",steer_torque_op, " ===")
 | 
					
						
							|  |  |  |       if is_openpilot_engaged:
 | 
					
						
							|  |  |  |         fake_wheel.response(steer_torque_op * A_steer_torque, speed)
 | 
					
						
							|  |  |  |         throttle_out = throttle_op * A_throttle
 | 
					
						
							|  |  |  |         brake_out = brake_op * A_brake
 | 
					
						
							|  |  |  |         steer_angle_out = fake_wheel.angle
 | 
					
						
							|  |  |  |         # print(steer_torque_op)
 | 
					
						
							|  |  |  |       # print(steer_angle_out)
 | 
					
						
							|  |  |  |       vc = carla.VehicleControl(throttle=throttle_out, steer=steer_angle_out / 3.14, brake=brake_out, reverse=in_reverse)
 | 
					
						
							|  |  |  |       vehicle.apply_control(vc)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rk.keep_time()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__":
 | 
					
						
							|  |  |  |   params = Params()
 | 
					
						
							|  |  |  |   params.delete("Offroad_ConnectivityNeeded")
 | 
					
						
							|  |  |  |   from selfdrive.version import terms_version, training_version
 | 
					
						
							|  |  |  |   params.put("HasAcceptedTerms", terms_version)
 | 
					
						
							|  |  |  |   params.put("CompletedTrainingVersion", training_version)
 | 
					
						
							|  |  |  |   params.put("CommunityFeaturesToggle", "1")
 | 
					
						
							|  |  |  |   params.put("CalibrationParams", '{"vanishing_point": [582.06, 442.78], "valid_blocks": 20}')
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # no carla, still run
 | 
					
						
							|  |  |  |   try:
 | 
					
						
							|  |  |  |     import carla
 | 
					
						
							|  |  |  |   except ImportError:
 | 
					
						
							|  |  |  |     print("WARNING: NO CARLA")
 | 
					
						
							|  |  |  |     while 1:
 | 
					
						
							|  |  |  |       time.sleep(1)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   from multiprocessing import Process, Queue
 | 
					
						
							|  |  |  |   q = Queue()
 | 
					
						
							|  |  |  |   p = Process(target=go, args=(q,))
 | 
					
						
							|  |  |  |   p.daemon = True
 | 
					
						
							|  |  |  |   p.start()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if args.joystick:
 | 
					
						
							|  |  |  |     # start input poll for joystick
 | 
					
						
							|  |  |  |     from lib.manual_ctrl import wheel_poll_thread
 | 
					
						
							|  |  |  |     wheel_poll_thread(q)
 | 
					
						
							|  |  |  |   else:
 | 
					
						
							|  |  |  |     # start input poll for keyboard
 | 
					
						
							|  |  |  |     from lib.keyboard_ctrl import keyboard_poll_thread
 | 
					
						
							|  |  |  |     keyboard_poll_thread(q)
 |