#!/usr/bin/env python
from __future__ import print_function
import os
import numpy as np
import tempfile
import zmq
from common . services import service_list
import selfdrive . messaging as messaging
from selfdrive . config import ImageParams , VehicleParams
from selfdrive . calibrationd . calibration import ViewCalibrator , CalibStatus
CALIBRATION_TMP_DIR = " /sdcard "
CALIBRATION_FILE = " /sdcard/calibration_param "
def load_calibration ( gctx ) :
# calibration initialization
I = ImageParams ( )
vp_guess = None
if gctx is not None :
warp_matrix_start = np . array (
gctx [ ' calibration ' ] [ " initial_homography " ] ) . reshape ( 3 , 3 )
big_box_size = [ 560 , 304 ]
else :
warp_matrix_start = np . array ( [ [ 1. , 0. , I . SX_R ] ,
[ 0. , 1. , I . SY_R ] ,
[ 0. , 0. , 1. ] ] )
big_box_size = [ 640 , 480 ]
# translate the vanishing point into phone image space
vp_box = ( I . VPX_R - I . SX_R , I . VPY_R - I . SY_R )
vp_trans = np . dot ( warp_matrix_start , vp_box + ( 1. , ) )
vp_img = ( vp_trans [ 0 ] / vp_trans [ 2 ] , vp_trans [ 1 ] / vp_trans [ 2 ] )
# load calibration data
if os . path . isfile ( CALIBRATION_FILE ) :
try :
# If the calibration file exist, start from the last cal values
with open ( CALIBRATION_FILE , " r " ) as cal_file :
data = [ float ( l . strip ( ) ) for l in cal_file . readlines ( ) ]
return ViewCalibrator (
( I . X , I . Y ) ,
big_box_size ,
vp_img ,
warp_matrix_start ,
vp_f = [ data [ 2 ] , data [ 3 ] ] ,
cal_cycle = data [ 0 ] ,
cal_status = data [ 1 ] )
except Exception as e :
print ( " Could not load calibration file: {} " . format ( e ) )
return ViewCalibrator (
( I . X , I . Y ) , big_box_size , vp_img , warp_matrix_start , vp_f = vp_guess )
def store_calibration ( calib ) :
# Tempfile needs to be on the same device as the calbration file.
with tempfile . NamedTemporaryFile ( delete = False , dir = CALIBRATION_TMP_DIR ) as cal_file :
print ( calib . cal_cycle , file = cal_file )
print ( calib . cal_status , file = cal_file )
print ( calib . vp_f [ 0 ] , file = cal_file )
print ( calib . vp_f [ 1 ] , file = cal_file )
cal_file_name = cal_file . name
os . rename ( cal_file_name , CALIBRATION_FILE )
def calibrationd_thread ( gctx ) :
context = zmq . Context ( )
features = messaging . sub_sock ( context , service_list [ ' features ' ] . port )
live100 = messaging . sub_sock ( context , service_list [ ' live100 ' ] . port )
livecalibration = messaging . pub_sock ( context , service_list [ ' liveCalibration ' ] . port )
# subscribe to stats about the car
VP = VehicleParams ( False )
v_ego = None
calib = load_calibration ( gctx )
last_write_cycle = calib . cal_cycle
while 1 :
# calibration at the end so it does not delay radar processing above
ft = messaging . recv_sock ( features , wait = True )
# get latest here
l100 = messaging . recv_sock ( live100 )
if l100 is not None :
v_ego = l100 . live100 . vEgo
steer_angle = l100 . live100 . angleSteers
if v_ego is None :
continue
p0 = ft . features . p0
p1 = ft . features . p1
st = ft . features . status
calib . calibration ( p0 , p1 , st , v_ego , steer_angle , VP )
# write a new calibration every 100 cal cycle
if calib . cal_cycle - last_write_cycle > = 100 :
print ( " writing cal " , calib . cal_cycle )
store_calibration ( calib )
last_write_cycle = calib . cal_cycle
warp_matrix = map ( float , calib . warp_matrix . reshape ( 9 ) . tolist ( ) )
dat = messaging . new_message ( )
dat . init ( ' liveCalibration ' )
dat . liveCalibration . warpMatrix = warp_matrix
dat . liveCalibration . calStatus = calib . cal_status
dat . liveCalibration . calCycle = calib . cal_cycle
dat . liveCalibration . calPerc = calib . cal_perc
livecalibration . send ( dat . to_bytes ( ) )
def main ( gctx = None ) :
calibrationd_thread ( gctx )
if __name__ == " __main__ " :
main ( )