#!/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 ' : " whitePanda " ,
' 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 )