#!/usr/bin/env python3
import os
import sys
import time
import signal
import traceback
import usb1
from panda import Panda , PandaDFU
from multiprocessing import Pool
jungle = " JUNGLE " in os . environ
if jungle :
from panda_jungle import PandaJungle # pylint: disable=import-error
import cereal . messaging as messaging
from selfdrive . boardd . boardd import can_capnp_to_can_list
def initializer ( ) :
""" Ignore CTRL+C in the worker process.
source : https : / / stackoverflow . com / a / 44869451 """
signal . signal ( signal . SIGINT , signal . SIG_IGN )
def send_thread ( sender_serial ) :
global jungle
while True :
try :
if jungle :
sender = PandaJungle ( sender_serial )
else :
sender = Panda ( sender_serial )
sender . set_safety_mode ( Panda . SAFETY_ALLOUTPUT )
sender . set_can_loopback ( False )
can_sock = messaging . sub_sock ( ' can ' )
while True :
tsc = messaging . recv_one ( can_sock )
snd = can_capnp_to_can_list ( tsc . can )
snd = list ( filter ( lambda x : x [ - 1 ] < = 2 , snd ) )
try :
sender . can_send_many ( snd )
except usb1 . USBErrorTimeout :
pass
# Drain panda message buffer
sender . can_recv ( )
except Exception :
traceback . print_exc ( )
time . sleep ( 1 )
if __name__ == " __main__ " :
if jungle :
serials = PandaJungle . list ( )
else :
serials = Panda . list ( )
num_senders = len ( serials )
if num_senders == 0 :
print ( " No senders found. Exiting " )
sys . exit ( 1 )
else :
print ( " %d senders found. Starting broadcast " % num_senders )
if " FLASH " in os . environ :
for s in PandaDFU . list ( ) :
PandaDFU ( s ) . recover ( )
time . sleep ( 1 )
for s in serials :
Panda ( s ) . recover ( )
Panda ( s ) . flash ( )
pool = Pool ( num_senders , initializer = initializer )
pool . map_async ( send_thread , serials )
while True :
try :
time . sleep ( 10 )
except KeyboardInterrupt :
pool . terminate ( )
pool . join ( )
raise