показания-скорости на приборке из asetto corsa

Телеметрия из AsettoCorsa в приборную панель Porsche

от автора

в

В статье приборная панель от Porsche мы научились через Arduino и CAN модуль выводить данные. Теперь эти данные было бы неплохо получить из какой-нибудь игры. Я начал пробовать с классической AsettoCorsa, ведь там как раз есть пак с разными автомобилями Порше.

Довольно быстро я нашел рабочий код, на питоне, который парсил телеметрию из асетты. В main для проверки отпринтил скорость, обороты и передачу, убедился, что данные консистентны с игрой

        telemetry = assettoReader.getData()
        speed = telemetry.get("speed")
        rpm = telemetry.get("rpm")
        gear = telemetry.get("gear")
        print('Assetto data:', speed, rpm, gear)

В целом это самое интересное, что мне удалось достать из телеметрии. Хотелось вывести ABS и TractionControl, Но он почему-то не работает в телеметрии AsettoCorsa(. Такую информацию удалось найти на зарубежном форуме.

Hi ! There might be a confusion, ABS and TC active (unlike configured "level") have never been available in Assetto corsa telemetry, but it's available on ACC, Pcars 1/2/3, AMS2

В общем попробовал выводить разные значения, понял что пока остановлюсь на скорости, оборотах и передаче. Вроде еще работает уровень топлива, но на приборке оно отображается путем съема аналоговых значений с разъема (нужно заморочиться, чтобы такое реализовать). Проверял разные показания из телеметрии, на живую, в игре.

телеметрия asetto corsa

Теперь данные нужно отправить в Arduino. Проще всего упаковать в битовую последовательность и отправить в серийный порт. Выбрал максимальную разрядность для значений:
gear = хх
rpm = xxxxx
speed = xxx
Упаковываем:

def pack_to_bytes(speed, rpm, gear):
    packed = (speed << 24) | (rpm << 7) | gear
    return START + packed.to_bytes(5, byteorder='big')

Также я использовал что-то вроде стартового байта, START = b’\xAA’, который вынес в константы. Без него непонятно с какого момента смотреть байты на стороне Ардуино, и все перемешивалось в кучу

Теперь надо бы расшифровать это на стороне Arduino. Жду, когда накопится 6 байт и от стартового начинаю расшифровывать данные. Код наверняка не идеальный, но это работает без сбоев.

  // Этот блок принимает данные на серийный порт от телеметрии.
  if (SERIAL_PORT_MONITOR.available() >= 6) {
    if (SERIAL_PORT_MONITOR.read() == 0xAA) {
      // Читаем полученные данные и сохраняем их в переменные
      SERIAL_PORT_MONITOR.readBytes(buf, 5);
      for (int i = 0; i < 5; i++) {
          input_value = (input_value << 8) | buf[i];
      }
      s_speed = (input_value >> 24) & 0x3FF;
      s_rpm   = (input_value >> 7)  & 0x1FFFF;
      s_gear  = input_value & 0x7F;
    }
  }

В питон-скрипте в цикле, получаем данные, упаковываем и отдаем в серийный порт. С небольшой паузой, а то приборка сходит с ума.

    while True:
        telemetry = assettoReader.getData()
        speed = int(telemetry.get("speed"))
        rpm = int(telemetry.get("rpm"))
        gear = int(telemetry.get("gear"))
        data = pack_to_bytes(speed, rpm, gear)
        ser.write(data)
        time.sleep(0.02)

Также для быстрого запуска сделал себе на рабочем столе .bat файл, который запускает этот скрипт

echo "dashboard cluster asetto"
start /min cmd /k "cd / & cd PATH(Путь до файла)\Dashboard-for-autosimulators\ & venv\Scripts\activate & python assetto_corsa/assetto_corsa_telemetry_reader.py"

Еще решил сделать env-файл с номером COM-порта, чтобы не лазить в код каждый раз.

# COM
COM='3'

И такой простой код, который спрашивает новый com-порт, если не смог подключиться к указанному в env. Если подключение пройдет успешно, новый порт запишется в env

connected = False
    while not connected:
        try:
            print(f"connecting to COM-{COM_PORT}")
            ser = serial.Serial(f'COM{COM_PORT}', 115200)
            connected = True
        except serial.serialutil.SerialException:
            com_input = input(f"Failed to connect to COM-{COM_PORT}\nEnter COM port (number only): ")
            COM_PORT = com_input

    if connected:
        set_key(dotenv_path, "COM", COM_PORT)

Ну что-же. Запускаем, катаемся и проверяем). Как развернуть виртуальное окружение для питон-скрипта и залить прошивку в ардуино, думаю можно найти на других ресурсах. Но попытаюсь позже добавить в README. Код скрипта + ардуино доступен на GitHub.

asetto corsa porshe dashboard

Жалко не получилось достать давление, температуру и так далее из телеметрии, было бы вообще шик вывести эти параметры на ЖК дисплей приборки