#!/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