Merge panda subtree
commit
f878928731
|
@ -1,118 +0,0 @@
|
|||
version: 2
|
||||
jobs:
|
||||
safety:
|
||||
machine:
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build image
|
||||
command: "docker build -t panda_safety -f tests/safety/Dockerfile ."
|
||||
- run:
|
||||
name: Run safety test
|
||||
command: |
|
||||
docker run panda_safety /bin/bash -c "cd /openpilot/panda/tests/safety; PYTHONPATH=/openpilot ./test.sh"
|
||||
|
||||
misra-c2012:
|
||||
machine:
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build image
|
||||
command: "docker build -t panda_misra -f tests/misra/Dockerfile ."
|
||||
- run:
|
||||
name: Run Misra C 2012 test
|
||||
command: |
|
||||
mkdir /tmp/misra
|
||||
docker run -v /tmp/misra:/tmp/misra panda_misra /bin/bash -c "cd /panda/tests/misra; ./test_misra.sh"
|
||||
- store_artifacts:
|
||||
name: Store cppcheck test output
|
||||
path: /tmp/misra/cppcheck_output.txt
|
||||
- store_artifacts:
|
||||
name: Store misra test output
|
||||
path: /tmp/misra/misra_output.txt
|
||||
|
||||
build:
|
||||
machine:
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build image
|
||||
command: "docker build -t panda_build -f tests/build/Dockerfile ."
|
||||
- run:
|
||||
name: Test python package installer
|
||||
command: |
|
||||
docker run panda_build /bin/bash -c "cd /panda; python setup.py install"
|
||||
- run:
|
||||
name: Build Panda STM image
|
||||
command: |
|
||||
docker run panda_build /bin/bash -c "cd /panda/board; make bin"
|
||||
- run:
|
||||
name: Build Panda STM bootstub image
|
||||
command: |
|
||||
docker run panda_build /bin/bash -c "cd /panda/board; make obj/bootstub.panda.bin"
|
||||
- run:
|
||||
name: Build Pedal STM image
|
||||
command: |
|
||||
docker run panda_build /bin/bash -c "cd /panda/board/pedal; make obj/comma.bin"
|
||||
- run:
|
||||
name: Build Pedal STM bootstub image
|
||||
command: |
|
||||
docker run panda_build /bin/bash -c "cd /panda/board/pedal; make obj/bootstub.bin"
|
||||
- run:
|
||||
name: Build ESP image
|
||||
command: |
|
||||
docker run panda_build /bin/bash -c "cd /panda/boardesp; ./get_sdk.sh; make user1.bin"
|
||||
|
||||
safety_replay:
|
||||
machine:
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build image
|
||||
command: "docker build -t panda_safety_replay -f tests/safety_replay/Dockerfile ."
|
||||
- run:
|
||||
name: Replay drives
|
||||
command: |
|
||||
docker run panda_safety_replay /bin/bash -c "cd /openpilot/panda/tests/safety_replay; PYTHONPATH=/openpilot ./test_safety_replay.py"
|
||||
|
||||
language_check:
|
||||
machine:
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build image
|
||||
command: "docker build -t language_check -f tests/language/Dockerfile ."
|
||||
- run:
|
||||
name: Check code for bad language
|
||||
command: |
|
||||
docker run language_check /bin/bash -c "cd /panda/tests/language; ./test_language.py"
|
||||
|
||||
linter_python:
|
||||
machine:
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build image
|
||||
command: "docker build -t linter_python -f tests/linter_python/Dockerfile ."
|
||||
- run:
|
||||
name: Run linter python test
|
||||
command: |
|
||||
docker run linter_python /bin/bash -c "cd /panda/tests/linter_python; PYTHONPATH=/ ./flake8_panda.sh"
|
||||
docker run linter_python /bin/bash -c "cd /panda/tests/linter_python; PYTHONPATH=/ ./pylint_panda.sh"
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
main:
|
||||
jobs:
|
||||
- safety
|
||||
- misra-c2012
|
||||
- build
|
||||
- safety_replay
|
||||
- language_check
|
||||
- linter_python
|
|
@ -0,0 +1,128 @@
|
|||
name: panda tests
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
RUN: docker run --rm panda /bin/bash -c
|
||||
PERSIST: docker run --name panda panda /bin/sh -c
|
||||
BUILD: |
|
||||
docker pull $(grep -ioP '(?<=^from)\s+\S+' Dockerfile.panda) || true
|
||||
docker pull docker.io/commaai/panda:latest || true
|
||||
docker build --cache-from docker.io/commaai/panda:latest -t panda -f Dockerfile.panda .
|
||||
|
||||
jobs:
|
||||
docker_push:
|
||||
name: docker push
|
||||
runs-on: ubuntu-16.04
|
||||
timeout-minutes: 45
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/panda'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Login to dockerhub
|
||||
run: docker login -u wmelching -p ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Tag image
|
||||
run: docker tag panda docker.io/commaai/panda:latest
|
||||
- name: Push image
|
||||
run: docker push docker.io/commaai/panda:latest
|
||||
|
||||
build:
|
||||
name: build
|
||||
runs-on: ubuntu-16.04
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Test python package installer
|
||||
run: $RUN "cd /tmp/openpilot/panda && python setup.py install"
|
||||
- name: Build panda STM image
|
||||
run: $RUN "cd /tmp/openpilot/panda/board && make bin"
|
||||
- name: Build panda STM bootstub image
|
||||
run: $RUN "cd /tmp/openpilot/panda/board && make obj/bootstub.panda.bin"
|
||||
- name: Build pedal STM image
|
||||
run: $RUN "cd /tmp/openpilot/panda/board/pedal && make obj/comma.bin"
|
||||
- name: Build pedal STM bootstub image
|
||||
run: $RUN "cd /tmp/openpilot/panda/board/pedal && make obj/bootstub.bin"
|
||||
|
||||
build_esp:
|
||||
name: build esp
|
||||
runs-on: ubuntu-16.04
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build docker image
|
||||
run: |
|
||||
docker pull $(grep -ioP '(?<=^from)\s+\S+' tests/build/Dockerfile.panda_esp) || true
|
||||
docker pull docker.io/commaai/panda_esp:latest || true
|
||||
docker build --cache-from docker.io/commaai/panda_esp:latest -t panda_esp -f tests/build/Dockerfile.panda_esp .
|
||||
- name: Build ESP image
|
||||
run: docker run --rm panda_esp /bin/sh -c "cd /panda/boardesp && make user1.bin"
|
||||
- name: Push image
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/panda'
|
||||
run: |
|
||||
docker login -u wmelching -p ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
docker tag panda_esp docker.io/commaai/panda_esp:latest
|
||||
docker push docker.io/commaai/panda_esp:latest
|
||||
|
||||
safety:
|
||||
name: safety
|
||||
runs-on: ubuntu-16.04
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Run safety tests
|
||||
run: |
|
||||
$RUN "cd /tmp/openpilot && \
|
||||
scons -c && \
|
||||
scons -j$(nproc) opendbc/ cereal/ && \
|
||||
cd panda/tests/safety && \
|
||||
./test.sh"
|
||||
|
||||
safety_replay:
|
||||
name: safety replay
|
||||
runs-on: ubuntu-16.04
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Run safety replay
|
||||
run: $RUN "cd /tmp/openpilot/panda/tests/safety_replay && ./test_safety_replay.py"
|
||||
|
||||
misra:
|
||||
name: misra c2012
|
||||
runs-on: ubuntu-16.04
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Run Misra C 2012 analysis
|
||||
run: $PERSIST "cd /tmp/openpilot/panda/tests/misra && ./test_misra.sh"
|
||||
- name: Copy analysis outputs
|
||||
run: docker cp panda:/tmp/misra /tmp
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: cppcheck.txt
|
||||
path: /tmp/misra/cppcheck_output.txt
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: misra.txt
|
||||
path: /tmp/misra/misra_output.txt
|
||||
|
||||
python_linter:
|
||||
name: python linter
|
||||
runs-on: ubuntu-16.04
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build Docker image
|
||||
run: eval "$BUILD"
|
||||
- name: Run static analysis
|
||||
run: |
|
||||
$RUN "cd /tmp/openpilot/panda && git init && git add -A && MYPYPATH=/tmp/openpilot pre-commit run --all"
|
|
@ -15,3 +15,4 @@ examples/output.csv
|
|||
.DS_Store
|
||||
.vscode
|
||||
nosetests.xml
|
||||
.mypy_cache/
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: master
|
||||
hooks:
|
||||
- id: check-ast
|
||||
- id: check-json
|
||||
- id: check-xml
|
||||
- id: check-yaml
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: master
|
||||
hooks:
|
||||
- id: mypy
|
||||
exclude: '^(tests/automated)/'
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: master
|
||||
hooks:
|
||||
- id: flake8
|
||||
exclude: '^(tests/automated)/'
|
||||
args:
|
||||
- --select=F
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: pylint
|
||||
name: pylint
|
||||
entry: pylint
|
||||
language: system
|
||||
types: [python]
|
||||
exclude: '^(tests/automated)/'
|
||||
args:
|
||||
- --disable=R,C,W
|
|
@ -0,0 +1,2 @@
|
|||
[MASTER]
|
||||
generated-members=usb1.*
|
|
@ -0,0 +1,66 @@
|
|||
FROM ubuntu:16.04
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
ENV PYTHONPATH /tmp/openpilot:$PYTHONPATH
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
autoconf \
|
||||
automake \
|
||||
bzip2 \
|
||||
capnproto \
|
||||
clang \
|
||||
curl \
|
||||
g++ \
|
||||
gcc-arm-none-eabi libnewlib-arm-none-eabi \
|
||||
git \
|
||||
libarchive-dev \
|
||||
libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev libavresample-dev libavfilter-dev \
|
||||
libbz2-dev \
|
||||
libcapnp-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libffi-dev \
|
||||
libtool \
|
||||
libssl-dev \
|
||||
libsqlite3-dev \
|
||||
libusb-1.0-0 \
|
||||
libzmq3-dev \
|
||||
locales \
|
||||
make \
|
||||
pkg-config \
|
||||
python \
|
||||
python-dev \
|
||||
python-pip \
|
||||
unzip \
|
||||
wget \
|
||||
zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
|
||||
COPY requirements.txt /tmp/
|
||||
RUN pyenv install 3.7.3 && \
|
||||
pyenv global 3.7.3 && \
|
||||
pyenv rehash && \
|
||||
pip install --no-cache-dir --upgrade pip==18.0 && \
|
||||
pip install --no-cache-dir -r /tmp/requirements.txt
|
||||
|
||||
RUN cd /tmp && \
|
||||
git clone https://github.com/commaai/openpilot.git tmppilot || true && \
|
||||
cd /tmp/tmppilot && \
|
||||
git pull && git checkout 44560b5bb74e451767725144c3fa5f1564481a20 && \
|
||||
git submodule update --init cereal opendbc && \
|
||||
mkdir /tmp/openpilot && \
|
||||
cp -pR SConstruct tools/ selfdrive/ common/ cereal/ opendbc/ /tmp/openpilot && \
|
||||
rm -rf /tmp/tmppilot
|
||||
|
||||
RUN cd /tmp/openpilot && \
|
||||
pip install --no-cache-dir -r opendbc/requirements.txt && \
|
||||
pip install --no-cache-dir -r tools/requirements.txt
|
||||
|
||||
COPY . /tmp/openpilot/panda
|
||||
RUN rm -rf /tmp/openpilot/panda/.git
|
|
@ -13,7 +13,7 @@ It uses an [STM32F413](http://www.st.com/en/microcontrollers/stm32f413-423.html?
|
|||
|
||||
It is 2nd gen hardware, reusing code and parts from the [NEO](https://github.com/commaai/neo) interface board.
|
||||
|
||||
[![CircleCI](https://circleci.com/gh/commaai/panda.svg?style=svg)](https://circleci.com/gh/commaai/panda)
|
||||
![panda tests](https://github.com/commaai/panda/workflows/panda%20tests/badge.svg)
|
||||
|
||||
Usage (Python)
|
||||
------
|
||||
|
@ -99,7 +99,7 @@ When compiled from an [EON Dev Kit](https://comma.ai/shop/products/eon-gold-dash
|
|||
conjuction with [openpilot](https://github.com/commaai/openpilot). The panda FW, through its safety model, provides and enforces the
|
||||
[openpilot Safety](https://github.com/commaai/openpilot/blob/devel/SAFETY.md). Due to its critical function, it's important that the application code rigor within the `board` folder is held to high standards.
|
||||
|
||||
These are the [CI regression tests](https://circleci.com/gh/commaai/panda) we have in place:
|
||||
These are the [CI regression tests](https://github.com/commaai/panda/actions) we have in place:
|
||||
* A generic static code analysis is performed by [Cppcheck](https://github.com/danmar/cppcheck/).
|
||||
* In addition, [Cppcheck](https://github.com/danmar/cppcheck/) has a specific addon to check for [MISRA C:2012](https://www.misra.org.uk/MISRAHome/MISRAC2012/tabid/196/Default.aspx) violations. See [current coverage](https://github.com/commaai/panda/blob/master/tests/misra/coverage_table).
|
||||
* Compiler options are relatively strict: the flags `-Wall -Wextra -Wstrict-prototypes -Werror` are enforced on board and pedal makefiles.
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
from .python import Panda, PandaWifiStreaming, PandaDFU, ESPROM, CesantaFlasher, flash_release, BASEDIR, ensure_st_up_to_date, build_st, PandaSerial # noqa: F401
|
||||
# flake8: noqa
|
||||
# pylint: skip-file
|
||||
from .python import Panda, PandaWifiStreaming, PandaDFU, ESPROM, CesantaFlasher, flash_release, BASEDIR, ensure_st_up_to_date, build_st, PandaSerial
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "boards/grey.h"
|
||||
#include "boards/black.h"
|
||||
#include "boards/uno.h"
|
||||
#include "boards/dos.h"
|
||||
#else
|
||||
#include "boards/pedal.h"
|
||||
#endif
|
||||
|
@ -22,7 +23,10 @@ void detect_board_type(void) {
|
|||
// SPI lines floating: white (TODO: is this reliable? Not really, we have to enable ESP/GPS to be able to detect this on the UART)
|
||||
set_gpio_output(GPIOC, 14, 1);
|
||||
set_gpio_output(GPIOC, 5, 1);
|
||||
if((detect_with_pull(GPIOA, 4, PULL_DOWN)) || (detect_with_pull(GPIOA, 5, PULL_DOWN)) || (detect_with_pull(GPIOA, 6, PULL_DOWN)) || (detect_with_pull(GPIOA, 7, PULL_DOWN))){
|
||||
if(!detect_with_pull(GPIOB, 1, PULL_UP)){
|
||||
hw_type = HW_TYPE_DOS;
|
||||
current_board = &board_dos;
|
||||
} else if((detect_with_pull(GPIOA, 4, PULL_DOWN)) || (detect_with_pull(GPIOA, 5, PULL_DOWN)) || (detect_with_pull(GPIOA, 6, PULL_DOWN)) || (detect_with_pull(GPIOA, 7, PULL_DOWN))){
|
||||
hw_type = HW_TYPE_WHITE_PANDA;
|
||||
current_board = &board_white;
|
||||
} else if(detect_with_pull(GPIOA, 13, PULL_DOWN)) { // Rev AB deprecated, so no pullup means black. In REV C, A13 is pulled up to 5V with a 10K
|
||||
|
@ -78,7 +82,7 @@ bool board_has_gmlan(void) {
|
|||
}
|
||||
|
||||
bool board_has_obd(void) {
|
||||
return ((hw_type == HW_TYPE_BLACK_PANDA) || (hw_type == HW_TYPE_UNO));
|
||||
return ((hw_type == HW_TYPE_BLACK_PANDA) || (hw_type == HW_TYPE_UNO) || (hw_type == HW_TYPE_DOS));
|
||||
}
|
||||
|
||||
bool board_has_lin(void) {
|
||||
|
@ -86,9 +90,9 @@ bool board_has_lin(void) {
|
|||
}
|
||||
|
||||
bool board_has_rtc(void) {
|
||||
return (hw_type == HW_TYPE_UNO);
|
||||
return ((hw_type == HW_TYPE_UNO) || (hw_type == HW_TYPE_DOS));
|
||||
}
|
||||
|
||||
bool board_has_relay(void) {
|
||||
return ((hw_type == HW_TYPE_BLACK_PANDA) || (hw_type == HW_TYPE_UNO));
|
||||
return ((hw_type == HW_TYPE_BLACK_PANDA) || (hw_type == HW_TYPE_UNO) || (hw_type == HW_TYPE_DOS));
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ struct board {
|
|||
#define HW_TYPE_BLACK_PANDA 3U
|
||||
#define HW_TYPE_PEDAL 4U
|
||||
#define HW_TYPE_UNO 5U
|
||||
#define HW_TYPE_DOS 6U
|
||||
|
||||
// LED colors
|
||||
#define LED_RED 0U
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
// ///////////// //
|
||||
// Dos + Harness //
|
||||
// ///////////// //
|
||||
|
||||
void dos_enable_can_transciever(uint8_t transciever, bool enabled) {
|
||||
switch (transciever){
|
||||
case 1U:
|
||||
set_gpio_output(GPIOC, 1, !enabled);
|
||||
break;
|
||||
case 2U:
|
||||
set_gpio_output(GPIOC, 13, !enabled);
|
||||
break;
|
||||
case 3U:
|
||||
set_gpio_output(GPIOA, 0, !enabled);
|
||||
break;
|
||||
case 4U:
|
||||
set_gpio_output(GPIOB, 10, !enabled);
|
||||
break;
|
||||
default:
|
||||
puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dos_enable_can_transcievers(bool enabled) {
|
||||
for(uint8_t i=1U; i<=4U; i++){
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
if((car_harness_status == HARNESS_STATUS_FLIPPED) ? (i == 3U) : (i == 1U)){
|
||||
uno_enable_can_transciever(i, true);
|
||||
} else {
|
||||
uno_enable_can_transciever(i, enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dos_set_led(uint8_t color, bool enabled) {
|
||||
switch (color){
|
||||
case LED_RED:
|
||||
set_gpio_output(GPIOC, 9, !enabled);
|
||||
break;
|
||||
case LED_GREEN:
|
||||
set_gpio_output(GPIOC, 7, !enabled);
|
||||
break;
|
||||
case LED_BLUE:
|
||||
set_gpio_output(GPIOC, 6, !enabled);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dos_set_gps_load_switch(bool enabled) {
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void dos_set_bootkick(bool enabled){
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void dos_bootkick(void) {}
|
||||
|
||||
void dos_set_phone_power(bool enabled){
|
||||
UNUSED(enabled);
|
||||
}
|
||||
|
||||
void dos_set_usb_power_mode(uint8_t mode) {
|
||||
UNUSED(mode);
|
||||
}
|
||||
|
||||
void dos_set_esp_gps_mode(uint8_t mode) {
|
||||
UNUSED(mode);
|
||||
}
|
||||
|
||||
void dos_set_can_mode(uint8_t mode){
|
||||
switch (mode) {
|
||||
case CAN_MODE_NORMAL:
|
||||
case CAN_MODE_OBD_CAN2:
|
||||
if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(car_harness_status == HARNESS_STATUS_FLIPPED)) {
|
||||
// B12,B13: disable OBD mode
|
||||
set_gpio_mode(GPIOB, 12, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 13, MODE_INPUT);
|
||||
|
||||
// B5,B6: normal CAN2 mode
|
||||
set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2);
|
||||
set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2);
|
||||
} else {
|
||||
// B5,B6: disable normal CAN2 mode
|
||||
set_gpio_mode(GPIOB, 5, MODE_INPUT);
|
||||
set_gpio_mode(GPIOB, 6, MODE_INPUT);
|
||||
|
||||
// B12,B13: OBD mode
|
||||
set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2);
|
||||
set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
puts("Tried to set unsupported CAN mode: "); puth(mode); puts("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dos_usb_power_mode_tick(uint32_t uptime){
|
||||
UNUSED(uptime);
|
||||
if(bootkick_timer != 0U){
|
||||
bootkick_timer--;
|
||||
} else {
|
||||
dos_set_bootkick(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool dos_check_ignition(void){
|
||||
// ignition is checked through harness
|
||||
return harness_check_ignition();
|
||||
}
|
||||
|
||||
void dos_set_usb_switch(bool phone){
|
||||
set_gpio_output(GPIOB, 3, phone);
|
||||
}
|
||||
|
||||
void dos_set_ir_power(uint8_t percentage){
|
||||
pwm_set(TIM4, 2, percentage);
|
||||
}
|
||||
|
||||
void dos_set_fan_power(uint8_t percentage){
|
||||
// Enable fan power only if percentage is non-zero.
|
||||
set_gpio_output(GPIOA, 1, (percentage != 0U));
|
||||
fan_set_power(percentage);
|
||||
}
|
||||
|
||||
uint32_t dos_read_current(void){
|
||||
// No current sense on Dos
|
||||
return 0U;
|
||||
}
|
||||
|
||||
void dos_init(void) {
|
||||
common_init_gpio();
|
||||
|
||||
// A8,A15: normal CAN3 mode
|
||||
set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3);
|
||||
set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3);
|
||||
|
||||
// C0: OBD_SBU1 (orientation detection)
|
||||
// C3: OBD_SBU2 (orientation detection)
|
||||
set_gpio_mode(GPIOC, 0, MODE_ANALOG);
|
||||
set_gpio_mode(GPIOC, 3, MODE_ANALOG);
|
||||
|
||||
// C10: OBD_SBU1_RELAY (harness relay driving output)
|
||||
// C11: OBD_SBU2_RELAY (harness relay driving output)
|
||||
set_gpio_mode(GPIOC, 10, MODE_OUTPUT);
|
||||
set_gpio_mode(GPIOC, 11, MODE_OUTPUT);
|
||||
set_gpio_output_type(GPIOC, 10, OUTPUT_TYPE_OPEN_DRAIN);
|
||||
set_gpio_output_type(GPIOC, 11, OUTPUT_TYPE_OPEN_DRAIN);
|
||||
set_gpio_output(GPIOC, 10, 1);
|
||||
set_gpio_output(GPIOC, 11, 1);
|
||||
|
||||
// C8: FAN PWM aka TIM3_CH3
|
||||
set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3);
|
||||
|
||||
// Initialize IR PWM and set to 0%
|
||||
set_gpio_alternate(GPIOB, 7, GPIO_AF2_TIM4);
|
||||
pwm_init(TIM4, 2);
|
||||
dos_set_ir_power(0U);
|
||||
|
||||
// Initialize fan and set to 0%
|
||||
fan_init();
|
||||
dos_set_fan_power(0U);
|
||||
|
||||
// Initialize harness
|
||||
harness_init();
|
||||
|
||||
// Initialize RTC
|
||||
rtc_init();
|
||||
|
||||
// Enable CAN transcievers
|
||||
dos_enable_can_transcievers(true);
|
||||
|
||||
// Disable LEDs
|
||||
dos_set_led(LED_RED, false);
|
||||
dos_set_led(LED_GREEN, false);
|
||||
dos_set_led(LED_BLUE, false);
|
||||
|
||||
// Set normal CAN mode
|
||||
dos_set_can_mode(CAN_MODE_NORMAL);
|
||||
|
||||
// flip CAN0 and CAN2 if we are flipped
|
||||
if (car_harness_status == HARNESS_STATUS_FLIPPED) {
|
||||
can_flip_buses(0, 2);
|
||||
}
|
||||
|
||||
// init multiplexer
|
||||
can_set_obd(car_harness_status, false);
|
||||
}
|
||||
|
||||
const harness_configuration dos_harness_config = {
|
||||
.has_harness = true,
|
||||
.GPIO_SBU1 = GPIOC,
|
||||
.GPIO_SBU2 = GPIOC,
|
||||
.GPIO_relay_SBU1 = GPIOC,
|
||||
.GPIO_relay_SBU2 = GPIOC,
|
||||
.pin_SBU1 = 0,
|
||||
.pin_SBU2 = 3,
|
||||
.pin_relay_SBU1 = 10,
|
||||
.pin_relay_SBU2 = 11,
|
||||
.adc_channel_SBU1 = 10,
|
||||
.adc_channel_SBU2 = 13
|
||||
};
|
||||
|
||||
const board board_dos = {
|
||||
.board_type = "Dos",
|
||||
.harness_config = &dos_harness_config,
|
||||
.init = dos_init,
|
||||
.enable_can_transciever = dos_enable_can_transciever,
|
||||
.enable_can_transcievers = dos_enable_can_transcievers,
|
||||
.set_led = dos_set_led,
|
||||
.set_usb_power_mode = dos_set_usb_power_mode,
|
||||
.set_esp_gps_mode = dos_set_esp_gps_mode,
|
||||
.set_can_mode = dos_set_can_mode,
|
||||
.usb_power_mode_tick = dos_usb_power_mode_tick,
|
||||
.check_ignition = dos_check_ignition,
|
||||
.read_current = dos_read_current,
|
||||
.set_fan_power = dos_set_fan_power,
|
||||
.set_ir_power = dos_set_ir_power,
|
||||
.set_phone_power = dos_set_phone_power
|
||||
};
|
|
@ -14,6 +14,7 @@
|
|||
#define GET_BYTE(msg, b) (((int)(b) > 3) ? (((msg)->RDHR >> (8U * ((unsigned int)(b) % 4U))) & 0xFFU) : (((msg)->RDLR >> (8U * (unsigned int)(b))) & 0xFFU))
|
||||
#define GET_BYTES_04(msg) ((msg)->RDLR)
|
||||
#define GET_BYTES_48(msg) ((msg)->RDHR)
|
||||
#define GET_FLAG(value, mask) (((__typeof__(mask))param & mask) == mask)
|
||||
|
||||
#define CAN_INIT_TIMEOUT_MS 500U
|
||||
#define CAN_NAME_FROM_CANIF(CAN_DEV) (((CAN_DEV)==CAN1) ? "CAN1" : (((CAN_DEV) == CAN2) ? "CAN2" : "CAN3"))
|
||||
|
|
|
@ -72,10 +72,14 @@ void gen_crc_lookup_table(uint8_t poly, uint8_t crc_lut[]) {
|
|||
}
|
||||
}
|
||||
|
||||
bool msg_allowed(int addr, int bus, const AddrBus addr_list[], int len) {
|
||||
bool msg_allowed(CAN_FIFOMailBox_TypeDef *to_send, const CanMsg msg_list[], int len) {
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
int length = GET_LEN(to_send);
|
||||
|
||||
bool allowed = false;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if ((addr == addr_list[i].addr) && (bus == addr_list[i].bus)) {
|
||||
if ((addr == msg_list[i].addr) && (bus == msg_list[i].bus) && (length == msg_list[i].len)) {
|
||||
allowed = true;
|
||||
break;
|
||||
}
|
||||
|
@ -92,17 +96,29 @@ uint32_t get_ts_elapsed(uint32_t ts, uint32_t ts_last) {
|
|||
int get_addr_check_index(CAN_FIFOMailBox_TypeDef *to_push, AddrCheckStruct addr_list[], const int len) {
|
||||
int bus = GET_BUS(to_push);
|
||||
int addr = GET_ADDR(to_push);
|
||||
int length = GET_LEN(to_push);
|
||||
|
||||
int index = -1;
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (uint8_t j = 0U; addr_list[i].addr[j] != 0; j++) {
|
||||
if ((addr == addr_list[i].addr[j]) && (bus == addr_list[i].bus)) {
|
||||
index = i;
|
||||
goto Return;
|
||||
// if multiple msgs are allowed, determine which one is present on the bus
|
||||
if (!addr_list[i].msg_seen) {
|
||||
for (uint8_t j = 0U; addr_list[i].msg[j].addr != 0; j++) {
|
||||
if ((addr == addr_list[i].msg[j].addr) && (bus == addr_list[i].msg[j].bus) &&
|
||||
(length == addr_list[i].msg[j].len)) {
|
||||
addr_list[i].index = j;
|
||||
addr_list[i].msg_seen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int idx = addr_list[i].index;
|
||||
if ((addr == addr_list[i].msg[idx].addr) && (bus == addr_list[i].msg[idx].bus) &&
|
||||
(length == addr_list[i].msg[idx].len)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Return:
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -115,7 +131,7 @@ void safety_tick(const safety_hooks *hooks) {
|
|||
// lag threshold is max of: 1s and MAX_MISSED_MSGS * expected timestep.
|
||||
// Quite conservative to not risk false triggers.
|
||||
// 2s of lag is worse case, since the function is called at 1Hz
|
||||
bool lagging = elapsed_time > MAX(hooks->addr_check[i].expected_timestep * MAX_MISSED_MSGS, 1e6);
|
||||
bool lagging = elapsed_time > MAX(hooks->addr_check[i].msg[hooks->addr_check[i].index].expected_timestep * MAX_MISSED_MSGS, 1e6);
|
||||
hooks->addr_check[i].lagging = lagging;
|
||||
if (lagging) {
|
||||
controls_allowed = 0;
|
||||
|
@ -126,7 +142,7 @@ void safety_tick(const safety_hooks *hooks) {
|
|||
|
||||
void update_counter(AddrCheckStruct addr_list[], int index, uint8_t counter) {
|
||||
if (index != -1) {
|
||||
uint8_t expected_counter = (addr_list[index].last_counter + 1U) % (addr_list[index].max_counter + 1U);
|
||||
uint8_t expected_counter = (addr_list[index].last_counter + 1U) % (addr_list[index].msg[addr_list[index].index].max_counter + 1U);
|
||||
addr_list[index].wrong_counters += (expected_counter == counter) ? -1 : 1;
|
||||
addr_list[index].wrong_counters = MAX(MIN(addr_list[index].wrong_counters, MAX_WRONG_COUNTERS), 0);
|
||||
addr_list[index].last_counter = counter;
|
||||
|
@ -163,7 +179,7 @@ bool addr_safety_check(CAN_FIFOMailBox_TypeDef *to_push,
|
|||
|
||||
if (index != -1) {
|
||||
// checksum check
|
||||
if ((get_checksum != NULL) && (compute_checksum != NULL) && rx_checks[index].check_checksum) {
|
||||
if ((get_checksum != NULL) && (compute_checksum != NULL) && rx_checks[index].msg[rx_checks[index].index].check_checksum) {
|
||||
uint8_t checksum = get_checksum(to_push);
|
||||
uint8_t checksum_comp = compute_checksum(to_push);
|
||||
rx_checks[index].valid_checksum = checksum_comp == checksum;
|
||||
|
@ -172,7 +188,7 @@ bool addr_safety_check(CAN_FIFOMailBox_TypeDef *to_push,
|
|||
}
|
||||
|
||||
// counter check (max_counter == 0 means skip check)
|
||||
if ((get_counter != NULL) && (rx_checks[index].max_counter > 0U)) {
|
||||
if ((get_counter != NULL) && (rx_checks[index].msg[rx_checks[index].index].max_counter > 0U)) {
|
||||
uint8_t counter = get_counter(to_push);
|
||||
update_counter(rx_checks, index, counter);
|
||||
} else {
|
||||
|
@ -209,13 +225,13 @@ const safety_hook_config safety_hook_registry[] = {
|
|||
{SAFETY_CHRYSLER, &chrysler_hooks},
|
||||
{SAFETY_SUBARU, &subaru_hooks},
|
||||
{SAFETY_SUBARU_LEGACY, &subaru_legacy_hooks},
|
||||
{SAFETY_MAZDA, &mazda_hooks},
|
||||
{SAFETY_VOLKSWAGEN_MQB, &volkswagen_mqb_hooks},
|
||||
{SAFETY_VOLKSWAGEN_PQ, &volkswagen_pq_hooks},
|
||||
{SAFETY_NISSAN, &nissan_hooks},
|
||||
{SAFETY_NOOUTPUT, &nooutput_hooks},
|
||||
#ifdef ALLOW_DEBUG
|
||||
{SAFETY_MAZDA, &mazda_hooks},
|
||||
{SAFETY_TESLA, &tesla_hooks},
|
||||
{SAFETY_NISSAN, &nissan_hooks},
|
||||
{SAFETY_ALLOUTPUT, &alloutput_hooks},
|
||||
{SAFETY_GM_ASCM, &gm_ascm_hooks},
|
||||
{SAFETY_FORD, &ford_hooks},
|
||||
|
@ -223,7 +239,29 @@ const safety_hook_config safety_hook_registry[] = {
|
|||
};
|
||||
|
||||
int set_safety_hooks(uint16_t mode, int16_t param) {
|
||||
safety_mode_cnt = 0U; // reset safety mode timer
|
||||
// reset state set by safety mode
|
||||
safety_mode_cnt = 0U;
|
||||
relay_malfunction = false;
|
||||
gas_interceptor_detected = false;
|
||||
gas_interceptor_prev = 0;
|
||||
gas_pressed_prev = false;
|
||||
brake_pressed_prev = false;
|
||||
cruise_engaged_prev = false;
|
||||
vehicle_speed = 0;
|
||||
vehicle_moving = false;
|
||||
desired_torque_last = 0;
|
||||
rt_torque_last = 0;
|
||||
ts_angle_last = 0;
|
||||
desired_angle_last = 0;
|
||||
ts_last = 0;
|
||||
|
||||
torque_meas.max = 0;
|
||||
torque_meas.max = 0;
|
||||
torque_driver.min = 0;
|
||||
torque_driver.max = 0;
|
||||
angle_meas.min = 0;
|
||||
angle_meas.max = 0;
|
||||
|
||||
int set_status = -1; // not set
|
||||
int hook_config_count = sizeof(safety_hook_registry) / sizeof(safety_hook_config);
|
||||
for (int i = 0; i < hook_config_count; i++) {
|
||||
|
@ -231,7 +269,12 @@ int set_safety_hooks(uint16_t mode, int16_t param) {
|
|||
current_hooks = safety_hook_registry[i].hooks;
|
||||
current_safety_mode = safety_hook_registry[i].id;
|
||||
set_status = 0; // set
|
||||
break;
|
||||
}
|
||||
|
||||
// reset message index and seen flags in addr struct
|
||||
for (int j = 0; j < safety_hook_registry[i].hooks->addr_check_len; j++) {
|
||||
safety_hook_registry[i].hooks->addr_check[j].index = 0;
|
||||
safety_hook_registry[i].hooks->addr_check[j].msg_seen = false;
|
||||
}
|
||||
}
|
||||
if ((set_status == 0) && (current_hooks->init != NULL)) {
|
||||
|
|
|
@ -6,20 +6,17 @@ const int CHRYSLER_MAX_RATE_DOWN = 3;
|
|||
const int CHRYSLER_MAX_TORQUE_ERROR = 80; // max torque cmd in excess of torque motor
|
||||
const int CHRYSLER_GAS_THRSLD = 30; // 7% more than 2m/s
|
||||
const int CHRYSLER_STANDSTILL_THRSLD = 10; // about 1m/s
|
||||
const AddrBus CHRYSLER_TX_MSGS[] = {{571, 0}, {658, 0}, {678, 0}};
|
||||
const CanMsg CHRYSLER_TX_MSGS[] = {{571, 0, 3}, {658, 0, 6}, {678, 0, 8}};
|
||||
|
||||
// TODO: do checksum and counter checks
|
||||
AddrCheckStruct chrysler_rx_checks[] = {
|
||||
{.addr = {544}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U},
|
||||
{.addr = {514}, .bus = 0, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U},
|
||||
{.addr = {500}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.addr = {308}, .bus = 0, .check_checksum = false, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.addr = {320}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.msg = {{544, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{514, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{500, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
{.msg = {{308, 0, 8, .check_checksum = false, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
{.msg = {{320, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
};
|
||||
const int CHRYSLER_RX_CHECK_LEN = sizeof(chrysler_rx_checks) / sizeof(chrysler_rx_checks[0]);
|
||||
|
||||
int chrysler_speed = 0;
|
||||
|
||||
static uint8_t chrysler_get_checksum(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
int checksum_byte = GET_LEN(to_push) - 1;
|
||||
return (uint8_t)(GET_BYTE(to_push, checksum_byte));
|
||||
|
@ -98,14 +95,14 @@ static int chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
|||
if (addr == 514) {
|
||||
int speed_l = (GET_BYTE(to_push, 0) << 4) + (GET_BYTE(to_push, 1) >> 4);
|
||||
int speed_r = (GET_BYTE(to_push, 2) << 4) + (GET_BYTE(to_push, 3) >> 4);
|
||||
chrysler_speed = (speed_l + speed_r) / 2;
|
||||
vehicle_moving = chrysler_speed > CHRYSLER_STANDSTILL_THRSLD;
|
||||
vehicle_speed = (speed_l + speed_r) / 2;
|
||||
vehicle_moving = (int)vehicle_speed > CHRYSLER_STANDSTILL_THRSLD;
|
||||
}
|
||||
|
||||
// exit controls on rising edge of gas press
|
||||
if (addr == 308) {
|
||||
bool gas_pressed = (GET_BYTE(to_push, 5) & 0x7F) != 0;
|
||||
if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev && (chrysler_speed > CHRYSLER_GAS_THRSLD)) {
|
||||
if (!unsafe_allow_gas && gas_pressed && !gas_pressed_prev && ((int)vehicle_speed > CHRYSLER_GAS_THRSLD)) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
gas_pressed_prev = gas_pressed;
|
||||
|
@ -132,9 +129,8 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
|
||||
int tx = 1;
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
|
||||
if (!msg_allowed(addr, bus, CHRYSLER_TX_MSGS, sizeof(CHRYSLER_TX_MSGS) / sizeof(CHRYSLER_TX_MSGS[0]))) {
|
||||
if (!msg_allowed(to_send, CHRYSLER_TX_MSGS, sizeof(CHRYSLER_TX_MSGS) / sizeof(CHRYSLER_TX_MSGS[0]))) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,18 +18,18 @@ const int GM_DRIVER_TORQUE_FACTOR = 4;
|
|||
const int GM_MAX_GAS = 3072;
|
||||
const int GM_MAX_REGEN = 1404;
|
||||
const int GM_MAX_BRAKE = 350;
|
||||
const AddrBus GM_TX_MSGS[] = {{384, 0}, {1033, 0}, {1034, 0}, {715, 0}, {880, 0}, // pt bus
|
||||
{161, 1}, {774, 1}, {776, 1}, {784, 1}, // obs bus
|
||||
{789, 2}, // ch bus
|
||||
{0x104c006c, 3}, {0x10400060, 3}}; // gmlan
|
||||
const CanMsg GM_TX_MSGS[] = {{384, 0, 4}, {1033, 0, 7}, {1034, 0, 7}, {715, 0, 8}, {880, 0, 6}, // pt bus
|
||||
{161, 1, 7}, {774, 1, 8}, {776, 1, 7}, {784, 1, 2}, // obs bus
|
||||
{789, 2, 5}, // ch bus
|
||||
{0x104c006c, 3, 3}, {0x10400060, 3, 5}}; // gmlan
|
||||
|
||||
// TODO: do checksum and counter checks. Add correct timestep, 0.1s for now.
|
||||
AddrCheckStruct gm_rx_checks[] = {
|
||||
{.addr = {388}, .bus = 0, .expected_timestep = 100000U},
|
||||
{.addr = {842}, .bus = 0, .expected_timestep = 100000U},
|
||||
{.addr = {481}, .bus = 0, .expected_timestep = 100000U},
|
||||
{.addr = {241}, .bus = 0, .expected_timestep = 100000U},
|
||||
{.addr = {417}, .bus = 0, .expected_timestep = 100000U},
|
||||
{.msg = {{388, 0, 8, .expected_timestep = 100000U}}},
|
||||
{.msg = {{842, 0, 5, .expected_timestep = 100000U}}},
|
||||
{.msg = {{481, 0, 7, .expected_timestep = 100000U}}},
|
||||
{.msg = {{241, 0, 6, .expected_timestep = 100000U}}},
|
||||
{.msg = {{417, 0, 7, .expected_timestep = 100000U}}},
|
||||
};
|
||||
const int GM_RX_CHECK_LEN = sizeof(gm_rx_checks) / sizeof(gm_rx_checks[0]);
|
||||
|
||||
|
@ -122,9 +122,8 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
|
||||
int tx = 1;
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
|
||||
if (!msg_allowed(addr, bus, GM_TX_MSGS, sizeof(GM_TX_MSGS)/sizeof(GM_TX_MSGS[0]))) {
|
||||
if (!msg_allowed(to_send, GM_TX_MSGS, sizeof(GM_TX_MSGS)/sizeof(GM_TX_MSGS[0]))) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
// accel rising edge
|
||||
// brake rising edge
|
||||
// brake > 0mph
|
||||
const AddrBus HONDA_N_TX_MSGS[] = {{0xE4, 0}, {0x194, 0}, {0x1FA, 0}, {0x200, 0}, {0x30C, 0}, {0x33D, 0}};
|
||||
const AddrBus HONDA_BG_TX_MSGS[] = {{0xE4, 2}, {0xE5, 2}, {0x296, 0}, {0x33D, 2}}; // Bosch Giraffe
|
||||
const AddrBus HONDA_BH_TX_MSGS[] = {{0xE4, 0}, {0xE5, 0}, {0x296, 1}, {0x33D, 0}}; // Bosch Harness
|
||||
const CanMsg HONDA_N_TX_MSGS[] = {{0xE4, 0, 5}, {0x194, 0, 4}, {0x1FA, 0, 8}, {0x200, 0, 6}, {0x30C, 0, 8}, {0x33D, 0, 5}};
|
||||
const CanMsg HONDA_BG_TX_MSGS[] = {{0xE4, 2, 5}, {0xE5, 2, 8}, {0x296, 0, 4}, {0x33D, 2, 5}}; // Bosch Giraffe
|
||||
const CanMsg HONDA_BH_TX_MSGS[] = {{0xE4, 0, 5}, {0xE5, 0, 8}, {0x296, 1, 4}, {0x33D, 0, 5}}; // Bosch Harness
|
||||
const CanMsg HONDA_BG_LONG_TX_MSGS[] = {{0xE4, 0, 5}, {0x1DF, 0, 8}, {0x1EF, 0, 8}, {0x1FA, 0, 8}, {0x30C, 0, 8}, {0x33D, 0, 5}, {0x39F, 0, 8}, {0x18DAB0F1, 0, 8}}; // Bosch Giraffe w/ gas and brakes
|
||||
const CanMsg HONDA_BH_LONG_TX_MSGS[] = {{0xE4, 1, 5}, {0x1DF, 1, 8}, {0x1EF, 1, 8}, {0x1FA, 1, 8}, {0x30C, 1, 8}, {0x33D, 1, 5}, {0x39F, 1, 8}, {0x18DAB0F1, 1, 8}}; // Bosch Harness w/ gas and brakes
|
||||
|
||||
// Roughly calculated using the offsets in openpilot +5%:
|
||||
// In openpilot: ((gas1_norm + gas2_norm)/2) > 15
|
||||
|
@ -18,26 +20,34 @@ const AddrBus HONDA_BH_TX_MSGS[] = {{0xE4, 0}, {0xE5, 0}, {0x296, 1}, {0x33D, 0}
|
|||
// In this safety: ((gas1 + (gas2/2))/2) > THRESHOLD
|
||||
const int HONDA_GAS_INTERCEPTOR_THRESHOLD = 344;
|
||||
#define HONDA_GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + ((GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2 ) / 2) // avg between 2 tracks
|
||||
const int HONDA_BOSCH_NO_GAS_VALUE = -30000; // value sent when not requesting gas
|
||||
const int HONDA_BOSCH_GAS_MAX = 2000;
|
||||
const int HONDA_BOSCH_ACCEL_MIN = -350; // max braking == -3.5m/s2
|
||||
|
||||
// Nidec and Bosch giraffe have pt on bus 0
|
||||
AddrCheckStruct honda_rx_checks[] = {
|
||||
{.addr = {0x1A6, 0x296}, .bus = 0, .check_checksum = true, .max_counter = 3U, .expected_timestep = 40000U},
|
||||
{.addr = { 0x158}, .bus = 0, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U},
|
||||
{.addr = { 0x17C}, .bus = 0, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U},
|
||||
{.msg = {{0x1A6, 0, 8, .check_checksum = true, .max_counter = 3U, .expected_timestep = 40000U},
|
||||
{0x296, 0, 4, .check_checksum = true, .max_counter = 3U, .expected_timestep = 40000U}}},
|
||||
{.msg = {{0x158, 0, 8, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{0x17C, 0, 8, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U}}},
|
||||
};
|
||||
const int HONDA_RX_CHECKS_LEN = sizeof(honda_rx_checks) / sizeof(honda_rx_checks[0]);
|
||||
|
||||
// Bosch harness has pt on bus 1
|
||||
AddrCheckStruct honda_bh_rx_checks[] = {
|
||||
{.addr = {0x296}, .bus = 1, .check_checksum = true, .max_counter = 3U, .expected_timestep = 40000U},
|
||||
{.addr = {0x158}, .bus = 1, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U},
|
||||
{.addr = {0x17C}, .bus = 1, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U},
|
||||
{.msg = {{0x296, 1, 4, .check_checksum = true, .max_counter = 3U, .expected_timestep = 40000U}}},
|
||||
{.msg = {{0x158, 1, 8, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{0x17C, 1, 8, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U}}},
|
||||
};
|
||||
const int HONDA_BH_RX_CHECKS_LEN = sizeof(honda_bh_rx_checks) / sizeof(honda_bh_rx_checks[0]);
|
||||
|
||||
const uint16_t HONDA_PARAM_ALT_BRAKE = 1;
|
||||
const uint16_t HONDA_PARAM_BOSCH_LONG = 2;
|
||||
|
||||
int honda_brake = 0;
|
||||
bool honda_alt_brake_msg = false;
|
||||
bool honda_fwd_brake = false;
|
||||
bool honda_bosch_long = false;
|
||||
enum {HONDA_N_HW, HONDA_BG_HW, HONDA_BH_HW} honda_hw = HONDA_N_HW;
|
||||
|
||||
|
||||
|
@ -191,12 +201,16 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
|
||||
if (honda_hw == HONDA_BG_HW) {
|
||||
tx = msg_allowed(addr, bus, HONDA_BG_TX_MSGS, sizeof(HONDA_BG_TX_MSGS)/sizeof(HONDA_BG_TX_MSGS[0]));
|
||||
} else if (honda_hw == HONDA_BH_HW) {
|
||||
tx = msg_allowed(addr, bus, HONDA_BH_TX_MSGS, sizeof(HONDA_BH_TX_MSGS)/sizeof(HONDA_BH_TX_MSGS[0]));
|
||||
if ((honda_hw == HONDA_BG_HW) && !honda_bosch_long) {
|
||||
tx = msg_allowed(to_send, HONDA_BG_TX_MSGS, sizeof(HONDA_BG_TX_MSGS)/sizeof(HONDA_BG_TX_MSGS[0]));
|
||||
} else if ((honda_hw == HONDA_BG_HW) && honda_bosch_long) {
|
||||
tx = msg_allowed(to_send, HONDA_BG_LONG_TX_MSGS, sizeof(HONDA_BG_LONG_TX_MSGS)/sizeof(HONDA_BG_LONG_TX_MSGS[0]));
|
||||
} else if ((honda_hw == HONDA_BH_HW) && !honda_bosch_long) {
|
||||
tx = msg_allowed(to_send, HONDA_BH_TX_MSGS, sizeof(HONDA_BH_TX_MSGS)/sizeof(HONDA_BH_TX_MSGS[0]));
|
||||
} else if ((honda_hw == HONDA_BH_HW) && honda_bosch_long) {
|
||||
tx = msg_allowed(to_send, HONDA_BH_LONG_TX_MSGS, sizeof(HONDA_BH_LONG_TX_MSGS)/sizeof(HONDA_BH_LONG_TX_MSGS[0]));
|
||||
} else {
|
||||
tx = msg_allowed(addr, bus, HONDA_N_TX_MSGS, sizeof(HONDA_N_TX_MSGS)/sizeof(HONDA_N_TX_MSGS[0]));
|
||||
tx = msg_allowed(to_send, HONDA_N_TX_MSGS, sizeof(HONDA_N_TX_MSGS)/sizeof(HONDA_N_TX_MSGS[0]));
|
||||
}
|
||||
|
||||
if (relay_malfunction) {
|
||||
|
@ -211,9 +225,10 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
pedal_pressed = pedal_pressed || gas_pressed_prev || (gas_interceptor_prev > HONDA_GAS_INTERCEPTOR_THRESHOLD);
|
||||
}
|
||||
bool current_controls_allowed = controls_allowed && !(pedal_pressed);
|
||||
int bus_pt = (honda_hw == HONDA_BH_HW)? 1 : 0;
|
||||
|
||||
// BRAKE: safety check
|
||||
if ((addr == 0x1FA) && (bus == 0)) {
|
||||
// BRAKE: safety check (nidec)
|
||||
if ((addr == 0x1FA) && (bus == bus_pt)) {
|
||||
honda_brake = (GET_BYTE(to_send, 0) << 2) + ((GET_BYTE(to_send, 1) >> 6) & 0x3);
|
||||
if (!current_controls_allowed) {
|
||||
if (honda_brake != 0) {
|
||||
|
@ -228,6 +243,31 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
}
|
||||
}
|
||||
|
||||
// BRAKE/GAS: safety check (bosch)
|
||||
if ((addr == 0x1DF) && (bus == bus_pt)) {
|
||||
int accel = (GET_BYTE(to_send, 3) << 3) | ((GET_BYTE(to_send, 4) >> 5) & 0x7);
|
||||
accel = to_signed(accel, 11);
|
||||
if (!current_controls_allowed) {
|
||||
if (accel != 0) {
|
||||
tx = 0;
|
||||
}
|
||||
}
|
||||
if (accel < HONDA_BOSCH_ACCEL_MIN) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
int gas = (GET_BYTE(to_send, 0) << 8) | GET_BYTE(to_send, 1);
|
||||
gas = to_signed(gas, 16);
|
||||
if (!current_controls_allowed) {
|
||||
if (gas != HONDA_BOSCH_NO_GAS_VALUE) {
|
||||
tx = 0;
|
||||
}
|
||||
}
|
||||
if (gas > HONDA_BOSCH_GAS_MAX) {
|
||||
tx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// STEER: safety check
|
||||
if ((addr == 0xE4) || (addr == 0x194)) {
|
||||
if (!current_controls_allowed) {
|
||||
|
@ -245,7 +285,7 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
}
|
||||
}
|
||||
|
||||
// GAS: safety check
|
||||
// GAS: safety check (interceptor)
|
||||
if (addr == 0x200) {
|
||||
if (!current_controls_allowed) {
|
||||
if (GET_BYTE(to_send, 0) || GET_BYTE(to_send, 1)) {
|
||||
|
@ -257,7 +297,6 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
// FORCE CANCEL: safety check only relevant when spamming the cancel button in Bosch HW
|
||||
// ensuring that only the cancel button press is sent (VAL 2) when controls are off.
|
||||
// This avoids unintended engagements while still allowing resume spam
|
||||
int bus_pt = (honda_hw == HONDA_BH_HW)? 1 : 0;
|
||||
if ((addr == 0x296) && !current_controls_allowed && (bus == bus_pt)) {
|
||||
if (((GET_BYTE(to_send, 0) >> 5) & 0x7) != 2) {
|
||||
tx = 0;
|
||||
|
@ -275,6 +314,7 @@ static void honda_nidec_init(int16_t param) {
|
|||
gas_interceptor_detected = 0;
|
||||
honda_hw = HONDA_N_HW;
|
||||
honda_alt_brake_msg = false;
|
||||
honda_bosch_long = false;
|
||||
}
|
||||
|
||||
static void honda_bosch_giraffe_init(int16_t param) {
|
||||
|
@ -282,7 +322,9 @@ static void honda_bosch_giraffe_init(int16_t param) {
|
|||
relay_malfunction_reset();
|
||||
honda_hw = HONDA_BG_HW;
|
||||
// Checking for alternate brake override from safety parameter
|
||||
honda_alt_brake_msg = (param == 1) ? true : false;
|
||||
honda_alt_brake_msg = GET_FLAG(param, HONDA_PARAM_ALT_BRAKE);
|
||||
// radar disabled so allow gas/brakes
|
||||
honda_bosch_long = GET_FLAG(param, HONDA_PARAM_BOSCH_LONG);
|
||||
}
|
||||
|
||||
static void honda_bosch_harness_init(int16_t param) {
|
||||
|
@ -290,7 +332,9 @@ static void honda_bosch_harness_init(int16_t param) {
|
|||
relay_malfunction_reset();
|
||||
honda_hw = HONDA_BH_HW;
|
||||
// Checking for alternate brake override from safety parameter
|
||||
honda_alt_brake_msg = (param == 1) ? true : false;
|
||||
honda_alt_brake_msg = GET_FLAG(param, HONDA_PARAM_ALT_BRAKE);
|
||||
// radar disabled so allow gas/brakes
|
||||
honda_bosch_long = GET_FLAG(param, HONDA_PARAM_BOSCH_LONG);
|
||||
}
|
||||
|
||||
static int honda_nidec_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||
|
|
|
@ -6,15 +6,28 @@ const int HYUNDAI_MAX_RATE_DOWN = 7;
|
|||
const int HYUNDAI_DRIVER_TORQUE_ALLOWANCE = 50;
|
||||
const int HYUNDAI_DRIVER_TORQUE_FACTOR = 2;
|
||||
const int HYUNDAI_STANDSTILL_THRSLD = 30; // ~1kph
|
||||
const AddrBus HYUNDAI_TX_MSGS[] = {{832, 0}, {1265, 0}, {1157, 0}};
|
||||
const CanMsg HYUNDAI_TX_MSGS[] = {
|
||||
{832, 0, 8}, // LKAS11 Bus 0
|
||||
{1265, 0, 4}, // CLU11 Bus 0
|
||||
{1157, 0, 4}, // LFAHDA_MFC Bus 0
|
||||
// {1056, 0, 8}, // SCC11, Bus 0
|
||||
// {1057, 0, 8}, // SCC12, Bus 0
|
||||
// {1290, 0, 8}, // SCC13, Bus 0
|
||||
// {905, 0, 8}, // SCC14, Bus 0
|
||||
// {1186, 0, 8} // 4a2SCC, Bus 0
|
||||
};
|
||||
|
||||
// TODO: do checksum checks
|
||||
// TODO: missing checksum for wheel speeds message,worst failure case is
|
||||
// wheel speeds stuck at 0 and we don't disengage on brake press
|
||||
// TODO: refactor addr check to cleanly re-enable commented out checks for cars that have them
|
||||
AddrCheckStruct hyundai_rx_checks[] = {
|
||||
{.addr = {608}, .bus = 0, .max_counter = 3U, .expected_timestep = 10000U},
|
||||
{.addr = {897}, .bus = 0, .max_counter = 255U, .expected_timestep = 10000U},
|
||||
{.addr = {902}, .bus = 0, .max_counter = 3U, .expected_timestep = 10000U},
|
||||
{.addr = {916}, .bus = 0, .max_counter = 7U, .expected_timestep = 10000U},
|
||||
{.addr = {1057}, .bus = 0, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.msg = {{608, 0, 8, .check_checksum = true, .max_counter = 3U, .expected_timestep = 10000U}}},
|
||||
// TODO: older hyundai models don't populate the counter bits in 902
|
||||
//{.msg = {{902, 0, 8, .max_counter = 15U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{902, 0, 8, .max_counter = 0U, .expected_timestep = 10000U}}},
|
||||
//{.msg = {{916, 0, 8, .check_checksum = true, .max_counter = 7U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{916, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{1057, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
};
|
||||
const int HYUNDAI_RX_CHECK_LEN = sizeof(hyundai_rx_checks) / sizeof(hyundai_rx_checks[0]);
|
||||
|
||||
|
@ -24,10 +37,8 @@ static uint8_t hyundai_get_counter(CAN_FIFOMailBox_TypeDef *to_push) {
|
|||
uint8_t cnt;
|
||||
if (addr == 608) {
|
||||
cnt = (GET_BYTE(to_push, 7) >> 4) & 0x3;
|
||||
} else if (addr == 897) {
|
||||
cnt = GET_BYTE(to_push, 5);
|
||||
} else if (addr == 902) {
|
||||
cnt = (GET_BYTE(to_push, 1) >> 6) & 0x3;
|
||||
cnt = ((GET_BYTE(to_push, 3) >> 6) << 2) | (GET_BYTE(to_push, 1) >> 6);
|
||||
} else if (addr == 916) {
|
||||
cnt = (GET_BYTE(to_push, 1) >> 5) & 0x7;
|
||||
} else if (addr == 1057) {
|
||||
|
@ -38,10 +49,42 @@ static uint8_t hyundai_get_counter(CAN_FIFOMailBox_TypeDef *to_push) {
|
|||
return cnt;
|
||||
}
|
||||
|
||||
static uint8_t hyundai_get_checksum(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
int addr = GET_ADDR(to_push);
|
||||
|
||||
uint8_t chksum;
|
||||
if (addr == 608) {
|
||||
chksum = GET_BYTE(to_push, 7) & 0xF;
|
||||
} else if (addr == 916) {
|
||||
chksum = GET_BYTE(to_push, 6) & 0xF;
|
||||
} else if (addr == 1057) {
|
||||
chksum = GET_BYTE(to_push, 7) >> 4;
|
||||
} else {
|
||||
chksum = 0;
|
||||
}
|
||||
return chksum;
|
||||
}
|
||||
|
||||
static uint8_t hyundai_compute_checksum(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
int addr = GET_ADDR(to_push);
|
||||
|
||||
uint8_t chksum = 0;
|
||||
// same algorithm, but checksum is in a different place
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint8_t b = GET_BYTE(to_push, i);
|
||||
if (((addr == 608) && (i == 7)) || ((addr == 916) && (i == 6)) || ((addr == 1057) && (i == 7))) {
|
||||
b &= (addr == 1057) ? 0x0FU : 0xF0U; // remove checksum
|
||||
}
|
||||
chksum += (b % 16U) + (b / 16U);
|
||||
}
|
||||
return (16U - (chksum % 16U)) % 16U;
|
||||
}
|
||||
|
||||
static int hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
|
||||
bool valid = addr_safety_check(to_push, hyundai_rx_checks, HYUNDAI_RX_CHECK_LEN,
|
||||
NULL, NULL, hyundai_get_counter);
|
||||
hyundai_get_checksum, hyundai_compute_checksum,
|
||||
hyundai_get_counter);
|
||||
|
||||
bool unsafe_allow_gas = unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS;
|
||||
|
||||
|
@ -106,9 +149,8 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
|
||||
int tx = 1;
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
|
||||
if (!msg_allowed(addr, bus, HYUNDAI_TX_MSGS, sizeof(HYUNDAI_TX_MSGS)/sizeof(HYUNDAI_TX_MSGS[0]))) {
|
||||
if (!msg_allowed(to_send, HYUNDAI_TX_MSGS, sizeof(HYUNDAI_TX_MSGS)/sizeof(HYUNDAI_TX_MSGS[0]))) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
|
@ -192,7 +234,6 @@ static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
|||
return bus_fwd;
|
||||
}
|
||||
|
||||
|
||||
const safety_hooks hyundai_hooks = {
|
||||
.init = nooutput_init,
|
||||
.rx = hyundai_rx_hook,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
// CAN msgs we care about
|
||||
#define MAZDA_LKAS 0x243
|
||||
#define MAZDA_LANEINFO 0x440
|
||||
#define MAZDA_CRZ_CTRL 0x21c
|
||||
#define MAZDA_WHEEL_SPEED 0x215
|
||||
#define MAZDA_STEER_TORQUE 0x240
|
||||
#define MAZDA_LKAS 0x243
|
||||
#define MAZDA_CRZ_CTRL 0x21c
|
||||
#define MAZDA_CRZ_BTNS 0x09d
|
||||
#define MAZDA_STEER_TORQUE 0x240
|
||||
#define MAZDA_ENGINE_DATA 0x202
|
||||
#define MAZDA_PEDALS 0x165
|
||||
|
||||
// CAN bus numbers
|
||||
#define MAZDA_MAIN 0
|
||||
|
@ -21,43 +21,102 @@
|
|||
#define MAZDA_MAX_RATE_DOWN 25
|
||||
#define MAZDA_DRIVER_TORQUE_ALLOWANCE 15
|
||||
#define MAZDA_DRIVER_TORQUE_FACTOR 1
|
||||
#define MAZDA_MAX_TORQUE_ERROR 350
|
||||
|
||||
int mazda_cruise_engaged_last = 0;
|
||||
int mazda_rt_torque_last = 0;
|
||||
int mazda_desired_torque_last = 0;
|
||||
uint32_t mazda_ts_last = 0;
|
||||
struct sample_t mazda_torque_driver; // last few driver torques measured
|
||||
// lkas enable speed 52kph, disable at 45kph
|
||||
#define MAZDA_LKAS_ENABLE_SPEED 5200
|
||||
#define MAZDA_LKAS_DISABLE_SPEED 4500
|
||||
|
||||
const CanMsg MAZDA_TX_MSGS[] = {{MAZDA_LKAS, 0, 8}, {MAZDA_CRZ_BTNS, 0, 8}};
|
||||
bool mazda_lkas_allowed = false;
|
||||
|
||||
AddrCheckStruct mazda_rx_checks[] = {
|
||||
{.msg = {{MAZDA_CRZ_CTRL, 0, 8, .expected_timestep = 20000U}}},
|
||||
{.msg = {{MAZDA_CRZ_BTNS, 0, 8, .expected_timestep = 100000U}}},
|
||||
{.msg = {{MAZDA_STEER_TORQUE, 0, 8, .expected_timestep = 12000U}}},
|
||||
{.msg = {{MAZDA_ENGINE_DATA, 0, 8, .expected_timestep = 10000U}}},
|
||||
{.msg = {{MAZDA_PEDALS, 0, 8, .expected_timestep = 20000U}}},
|
||||
};
|
||||
const int MAZDA_RX_CHECKS_LEN = sizeof(mazda_rx_checks) / sizeof(mazda_rx_checks[0]);
|
||||
|
||||
// track msgs coming from OP so that we know what CAM msgs to drop and what to forward
|
||||
static int mazda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
int bus = GET_BUS(to_push);
|
||||
int addr = GET_ADDR(to_push);
|
||||
bool valid;
|
||||
|
||||
if ((addr == MAZDA_STEER_TORQUE) && (bus == MAZDA_MAIN)) {
|
||||
int torque_driver_new = GET_BYTE(to_push, 0) - 127;
|
||||
// update array of samples
|
||||
update_sample(&mazda_torque_driver, torque_driver_new);
|
||||
}
|
||||
valid = addr_safety_check(to_push, mazda_rx_checks, MAZDA_RX_CHECKS_LEN,
|
||||
NULL, NULL, NULL);
|
||||
if (valid) {
|
||||
int bus = GET_BUS(to_push);
|
||||
int addr = GET_ADDR(to_push);
|
||||
|
||||
// enter controls on rising edge of ACC, exit controls on ACC off
|
||||
if ((addr == MAZDA_CRZ_CTRL) && (bus == MAZDA_MAIN)) {
|
||||
int cruise_engaged = GET_BYTE(to_push, 0) & 8;
|
||||
if (cruise_engaged != 0) {
|
||||
if (!mazda_cruise_engaged_last) {
|
||||
controls_allowed = 1;
|
||||
if (bus == MAZDA_MAIN) {
|
||||
|
||||
if (addr == MAZDA_ENGINE_DATA) {
|
||||
// sample speed: scale by 0.01 to get kph
|
||||
int speed = (GET_BYTE(to_push, 2) << 8) | GET_BYTE(to_push, 3);
|
||||
|
||||
vehicle_moving = speed > 10; // moving when speed > 0.1 kph
|
||||
|
||||
// Enable LKAS at 52kph going up, disable at 45kph going down
|
||||
if (speed > MAZDA_LKAS_ENABLE_SPEED) {
|
||||
mazda_lkas_allowed = true;
|
||||
} else if (speed < MAZDA_LKAS_DISABLE_SPEED) {
|
||||
mazda_lkas_allowed = false;
|
||||
} else {
|
||||
// Misra-able appeasment block!
|
||||
}
|
||||
}
|
||||
|
||||
if (addr == MAZDA_STEER_TORQUE) {
|
||||
int torque_driver_new = GET_BYTE(to_push, 0) - 127;
|
||||
// update array of samples
|
||||
update_sample(&torque_driver, torque_driver_new);
|
||||
}
|
||||
|
||||
// enter controls on rising edge of ACC, exit controls on ACC off
|
||||
if (addr == MAZDA_CRZ_CTRL) {
|
||||
bool cruise_engaged = GET_BYTE(to_push, 0) & 8;
|
||||
if (cruise_engaged) {
|
||||
if (!cruise_engaged_prev) {
|
||||
// do not engage until we hit the speed at which lkas is on
|
||||
if (mazda_lkas_allowed) {
|
||||
controls_allowed = 1;
|
||||
} else {
|
||||
controls_allowed = 0;
|
||||
cruise_engaged = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
cruise_engaged_prev = cruise_engaged;
|
||||
}
|
||||
|
||||
// Exit controls on rising edge of gas press
|
||||
if (addr == MAZDA_ENGINE_DATA) {
|
||||
bool gas_pressed = (GET_BYTE(to_push, 4) || (GET_BYTE(to_push, 5) & 0xF0));
|
||||
if (gas_pressed && !gas_pressed_prev && !(unsafe_mode & UNSAFE_DISABLE_DISENGAGE_ON_GAS)) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
gas_pressed_prev = gas_pressed;
|
||||
}
|
||||
|
||||
// Exit controls on rising edge of brake press
|
||||
if (addr == MAZDA_PEDALS) {
|
||||
bool brake_pressed = (GET_BYTE(to_push, 0) & 0x10);
|
||||
if (brake_pressed && (!brake_pressed_prev || vehicle_moving)) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
brake_pressed_prev = brake_pressed;
|
||||
}
|
||||
|
||||
// if we see lkas msg on MAZDA_MAIN bus then relay is closed
|
||||
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (addr == MAZDA_LKAS)) {
|
||||
relay_malfunction_set();
|
||||
}
|
||||
}
|
||||
else {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
mazda_cruise_engaged_last = cruise_engaged;
|
||||
}
|
||||
|
||||
// if we see wheel speed msgs on MAZDA_CAM bus then relay is closed
|
||||
if ((safety_mode_cnt > RELAY_TRNS_TIMEOUT) && (bus == MAZDA_CAM) && (addr == MAZDA_WHEEL_SPEED)) {
|
||||
relay_malfunction_set();
|
||||
}
|
||||
return 1;
|
||||
return valid;
|
||||
}
|
||||
|
||||
static int mazda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
|
@ -65,12 +124,17 @@ static int mazda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
|
||||
if (!msg_allowed(to_send, MAZDA_TX_MSGS, sizeof(MAZDA_TX_MSGS)/sizeof(MAZDA_TX_MSGS[0]))) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
if (relay_malfunction) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
// Check if msg is sent on the main BUS
|
||||
if (bus == MAZDA_MAIN) {
|
||||
|
||||
// steer cmd checks
|
||||
if (addr == MAZDA_LKAS) {
|
||||
int desired_torque = (((GET_BYTE(to_send, 0) & 0x0f) << 8) | GET_BYTE(to_send, 1)) - MAZDA_MAX_STEER;
|
||||
|
@ -83,20 +147,21 @@ static int mazda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
violation |= max_limit_check(desired_torque, MAZDA_MAX_STEER, -MAZDA_MAX_STEER);
|
||||
|
||||
// *** torque rate limit check ***
|
||||
violation |= driver_limit_check(desired_torque, mazda_desired_torque_last, &mazda_torque_driver,
|
||||
violation |= driver_limit_check(desired_torque, desired_torque_last, &torque_driver,
|
||||
MAZDA_MAX_STEER, MAZDA_MAX_RATE_UP, MAZDA_MAX_RATE_DOWN,
|
||||
MAZDA_DRIVER_TORQUE_ALLOWANCE, MAZDA_DRIVER_TORQUE_FACTOR);
|
||||
|
||||
// used next time
|
||||
mazda_desired_torque_last = desired_torque;
|
||||
desired_torque_last = desired_torque;
|
||||
|
||||
// *** torque real time rate limit check ***
|
||||
violation |= rt_rate_limit_check(desired_torque, mazda_rt_torque_last, MAZDA_MAX_RT_DELTA);
|
||||
violation |= rt_rate_limit_check(desired_torque, rt_torque_last, MAZDA_MAX_RT_DELTA);
|
||||
|
||||
// every RT_INTERVAL set the new limits
|
||||
uint32_t ts_elapsed = get_ts_elapsed(ts, mazda_ts_last);
|
||||
uint32_t ts_elapsed = get_ts_elapsed(ts, ts_last);
|
||||
if (ts_elapsed > ((uint32_t) MAZDA_RT_INTERVAL)) {
|
||||
mazda_rt_torque_last = desired_torque;
|
||||
mazda_ts_last = ts;
|
||||
rt_torque_last = desired_torque;
|
||||
ts_last = ts;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,9 +172,9 @@ static int mazda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
|
||||
// reset to 0 if either controls is not allowed or there's a violation
|
||||
if (violation || !controls_allowed) {
|
||||
mazda_desired_torque_last = 0;
|
||||
mazda_rt_torque_last = 0;
|
||||
mazda_ts_last = ts;
|
||||
desired_torque_last = 0;
|
||||
rt_torque_last = 0;
|
||||
ts_last = ts;
|
||||
}
|
||||
|
||||
if (violation) {
|
||||
|
@ -126,24 +191,30 @@ static int mazda_fwd_hook(int bus, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
|||
int addr = GET_ADDR(to_fwd);
|
||||
if (bus == MAZDA_MAIN) {
|
||||
bus_fwd = MAZDA_CAM;
|
||||
}
|
||||
else if (bus == MAZDA_CAM) {
|
||||
} else if (bus == MAZDA_CAM) {
|
||||
if (!(addr == MAZDA_LKAS)) {
|
||||
bus_fwd = MAZDA_MAIN;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
bus_fwd = -1;
|
||||
}
|
||||
}
|
||||
return bus_fwd;
|
||||
}
|
||||
|
||||
static void mazda_init(int16_t param) {
|
||||
UNUSED(param);
|
||||
controls_allowed = false;
|
||||
relay_malfunction_reset();
|
||||
mazda_lkas_allowed = false;
|
||||
}
|
||||
|
||||
const safety_hooks mazda_hooks = {
|
||||
.init = nooutput_init,
|
||||
.init = mazda_init,
|
||||
.rx = mazda_rx_hook,
|
||||
.tx = mazda_tx_hook,
|
||||
.tx_lin = nooutput_tx_lin_hook,
|
||||
.fwd = mazda_fwd_hook,
|
||||
// TODO: add addr safety checks
|
||||
.addr_check = mazda_rx_checks,
|
||||
.addr_check_len = sizeof(mazda_rx_checks) / sizeof(mazda_rx_checks[0]),
|
||||
};
|
||||
|
|
|
@ -11,24 +11,19 @@ const struct lookup_t NISSAN_LOOKUP_ANGLE_RATE_DOWN = {
|
|||
|
||||
const int NISSAN_DEG_TO_CAN = 100;
|
||||
|
||||
const AddrBus NISSAN_TX_MSGS[] = {{0x169, 0}, {0x2b1, 0}, {0x4cc, 0}, {0x20b, 2}, {0x280, 2}};
|
||||
const CanMsg NISSAN_TX_MSGS[] = {{0x169, 0, 8}, {0x2b1, 0, 8}, {0x4cc, 0, 8}, {0x20b, 2, 6}, {0x280, 2, 8}};
|
||||
|
||||
AddrCheckStruct nissan_rx_checks[] = {
|
||||
{.addr = {0x2}, .bus = 0, .expected_timestep = 10000U}, // STEER_ANGLE_SENSOR (100Hz)
|
||||
{.addr = {0x285}, .bus = 0, .expected_timestep = 20000U}, // WHEEL_SPEEDS_REAR (50Hz)
|
||||
{.addr = {0x30f}, .bus = 2, .expected_timestep = 100000U}, // CRUISE_STATE (10Hz)
|
||||
{.addr = {0x15c, 0x239}, .bus = 0, .expected_timestep = 20000U}, // GAS_PEDAL (100Hz / 50Hz)
|
||||
{.addr = {0x454, 0x1cc}, .bus = 0, .expected_timestep = 100000U}, // DOORS_LIGHTS (10Hz) / BRAKE (100Hz)
|
||||
{.msg = {{0x2, 0, 5, .expected_timestep = 10000U}}}, // STEER_ANGLE_SENSOR (100Hz)
|
||||
{.msg = {{0x285, 0, 8, .expected_timestep = 20000U}}}, // WHEEL_SPEEDS_REAR (50Hz)
|
||||
{.msg = {{0x30f, 2, 3, .expected_timestep = 100000U}}}, // CRUISE_STATE (10Hz)
|
||||
{.msg = {{0x15c, 0, 8, .expected_timestep = 20000U},
|
||||
{0x239, 0, 8, .expected_timestep = 20000U}}}, // GAS_PEDAL (100Hz / 50Hz)
|
||||
{.msg = {{0x454, 0, 8, .expected_timestep = 100000U},
|
||||
{0x1cc, 0, 4, .expected_timestep = 10000U}}}, // DOORS_LIGHTS (10Hz) / BRAKE (100Hz)
|
||||
};
|
||||
const int NISSAN_RX_CHECK_LEN = sizeof(nissan_rx_checks) / sizeof(nissan_rx_checks[0]);
|
||||
|
||||
float nissan_speed = 0;
|
||||
//int nissan_controls_allowed_last = 0;
|
||||
uint32_t nissan_ts_angle_last = 0;
|
||||
int nissan_desired_angle_last = 0;
|
||||
|
||||
struct sample_t nissan_angle_meas; // last 3 steer angles
|
||||
|
||||
|
||||
static int nissan_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||
|
||||
|
@ -50,14 +45,14 @@ static int nissan_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
|||
angle_meas_new = to_signed(angle_meas_new, 16) * 10;
|
||||
|
||||
// update array of samples
|
||||
update_sample(&nissan_angle_meas, angle_meas_new);
|
||||
update_sample(&angle_meas, angle_meas_new);
|
||||
}
|
||||
|
||||
if (addr == 0x285) {
|
||||
// Get current speed
|
||||
// Factor 0.005
|
||||
nissan_speed = ((GET_BYTE(to_push, 2) << 8) | (GET_BYTE(to_push, 3))) * 0.005 / 3.6;
|
||||
vehicle_moving = nissan_speed > 0.;
|
||||
vehicle_speed = ((GET_BYTE(to_push, 2) << 8) | (GET_BYTE(to_push, 3))) * 0.005 / 3.6;
|
||||
vehicle_moving = vehicle_speed > 0.;
|
||||
}
|
||||
|
||||
// exit controls on rising edge of gas press
|
||||
|
@ -119,10 +114,9 @@ static int nissan_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
|||
static int nissan_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
int tx = 1;
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
bool violation = 0;
|
||||
|
||||
if (!msg_allowed(addr, bus, NISSAN_TX_MSGS, sizeof(NISSAN_TX_MSGS) / sizeof(NISSAN_TX_MSGS[0]))) {
|
||||
if (!msg_allowed(to_send, NISSAN_TX_MSGS, sizeof(NISSAN_TX_MSGS) / sizeof(NISSAN_TX_MSGS[0]))) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
|
@ -141,24 +135,22 @@ static int nissan_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
if (controls_allowed && lka_active) {
|
||||
// add 1 to not false trigger the violation
|
||||
float delta_angle_float;
|
||||
delta_angle_float = (interpolate(NISSAN_LOOKUP_ANGLE_RATE_UP, nissan_speed) * NISSAN_DEG_TO_CAN) + 1.;
|
||||
delta_angle_float = (interpolate(NISSAN_LOOKUP_ANGLE_RATE_UP, vehicle_speed) * NISSAN_DEG_TO_CAN) + 1.;
|
||||
int delta_angle_up = (int)(delta_angle_float);
|
||||
delta_angle_float = (interpolate(NISSAN_LOOKUP_ANGLE_RATE_DOWN, nissan_speed) * NISSAN_DEG_TO_CAN) + 1.;
|
||||
delta_angle_float = (interpolate(NISSAN_LOOKUP_ANGLE_RATE_DOWN, vehicle_speed) * NISSAN_DEG_TO_CAN) + 1.;
|
||||
int delta_angle_down = (int)(delta_angle_float);
|
||||
int highest_desired_angle = nissan_desired_angle_last + ((nissan_desired_angle_last > 0) ? delta_angle_up : delta_angle_down);
|
||||
int lowest_desired_angle = nissan_desired_angle_last - ((nissan_desired_angle_last >= 0) ? delta_angle_down : delta_angle_up);
|
||||
int highest_desired_angle = desired_angle_last + ((desired_angle_last > 0) ? delta_angle_up : delta_angle_down);
|
||||
int lowest_desired_angle = desired_angle_last - ((desired_angle_last >= 0) ? delta_angle_down : delta_angle_up);
|
||||
|
||||
// check for violation;
|
||||
violation |= max_limit_check(desired_angle, highest_desired_angle, lowest_desired_angle);
|
||||
|
||||
//nissan_controls_allowed_last = controls_allowed;
|
||||
}
|
||||
nissan_desired_angle_last = desired_angle;
|
||||
desired_angle_last = desired_angle;
|
||||
|
||||
// desired steer angle should be the same as steer angle measured when controls are off
|
||||
if ((!controls_allowed) &&
|
||||
((desired_angle < (nissan_angle_meas.min - 1)) ||
|
||||
(desired_angle > (nissan_angle_meas.max + 1)))) {
|
||||
((desired_angle < (angle_meas.min - 1)) ||
|
||||
(desired_angle > (angle_meas.max + 1)))) {
|
||||
violation = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,23 +9,23 @@ const int SUBARU_DRIVER_TORQUE_ALLOWANCE = 60;
|
|||
const int SUBARU_DRIVER_TORQUE_FACTOR = 10;
|
||||
const int SUBARU_STANDSTILL_THRSLD = 20; // about 1kph
|
||||
|
||||
const AddrBus SUBARU_TX_MSGS[] = {{0x122, 0}, {0x221, 0}, {0x322, 0}};
|
||||
const AddrBus SUBARU_L_TX_MSGS[] = {{0x164, 0}, {0x221, 0}, {0x322, 0}};
|
||||
const CanMsg SUBARU_TX_MSGS[] = {{0x122, 0, 8}, {0x221, 0, 8}, {0x322, 0, 8}};
|
||||
const CanMsg SUBARU_L_TX_MSGS[] = {{0x164, 0, 8}, {0x221, 0, 8}, {0x322, 0, 8}};
|
||||
const int SUBARU_TX_MSGS_LEN = sizeof(SUBARU_TX_MSGS) / sizeof(SUBARU_TX_MSGS[0]);
|
||||
const int SUBARU_L_TX_MSGS_LEN = sizeof(SUBARU_L_TX_MSGS) / sizeof(SUBARU_L_TX_MSGS[0]);
|
||||
|
||||
AddrCheckStruct subaru_rx_checks[] = {
|
||||
{.addr = { 0x40}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U},
|
||||
{.addr = {0x119}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.addr = {0x139}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.addr = {0x13a}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.addr = {0x240}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 50000U},
|
||||
{.msg = {{ 0x40, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{0x119, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
{.msg = {{0x139, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
{.msg = {{0x13a, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
{.msg = {{0x240, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 50000U}}},
|
||||
};
|
||||
// TODO: do checksum and counter checks after adding the signals to the outback dbc file
|
||||
AddrCheckStruct subaru_l_rx_checks[] = {
|
||||
{.addr = {0x140}, .bus = 0, .expected_timestep = 10000U},
|
||||
{.addr = {0x371}, .bus = 0, .expected_timestep = 20000U},
|
||||
{.addr = {0x144}, .bus = 0, .expected_timestep = 50000U},
|
||||
{.msg = {{0x140, 0, 8, .expected_timestep = 10000U}}},
|
||||
{.msg = {{0x371, 0, 8, .expected_timestep = 20000U}}},
|
||||
{.msg = {{0x144, 0, 8, .expected_timestep = 50000U}}},
|
||||
};
|
||||
const int SUBARU_RX_CHECK_LEN = sizeof(subaru_rx_checks) / sizeof(subaru_rx_checks[0]);
|
||||
const int SUBARU_L_RX_CHECK_LEN = sizeof(subaru_l_rx_checks) / sizeof(subaru_l_rx_checks[0]);
|
||||
|
@ -131,10 +131,9 @@ static int subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
|||
static int subaru_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
int tx = 1;
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
|
||||
if ((!msg_allowed(addr, bus, SUBARU_TX_MSGS, SUBARU_TX_MSGS_LEN) && subaru_global) ||
|
||||
(!msg_allowed(addr, bus, SUBARU_L_TX_MSGS, SUBARU_L_TX_MSGS_LEN) && !subaru_global)) {
|
||||
if ((!msg_allowed(to_send, SUBARU_TX_MSGS, SUBARU_TX_MSGS_LEN) && subaru_global) ||
|
||||
(!msg_allowed(to_send, SUBARU_L_TX_MSGS, SUBARU_L_TX_MSGS_LEN) && !subaru_global)) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,16 +29,17 @@ const int TOYOTA_STANDSTILL_THRSLD = 100; // 1kph
|
|||
const int TOYOTA_GAS_INTERCEPTOR_THRSLD = 845;
|
||||
#define TOYOTA_GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + (GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2) // avg between 2 tracks
|
||||
|
||||
const AddrBus TOYOTA_TX_MSGS[] = {{0x283, 0}, {0x2E6, 0}, {0x2E7, 0}, {0x33E, 0}, {0x344, 0}, {0x365, 0}, {0x366, 0}, {0x4CB, 0}, // DSU bus 0
|
||||
{0x128, 1}, {0x141, 1}, {0x160, 1}, {0x161, 1}, {0x470, 1}, // DSU bus 1
|
||||
{0x2E4, 0}, {0x411, 0}, {0x412, 0}, {0x343, 0}, {0x1D2, 0}, // LKAS + ACC
|
||||
{0x200, 0}, {0x750, 0}}; // interceptor + Blindspot monitor
|
||||
const CanMsg TOYOTA_TX_MSGS[] = {{0x283, 0, 7}, {0x2E6, 0, 8}, {0x2E7, 0, 8}, {0x33E, 0, 7}, {0x344, 0, 8}, {0x365, 0, 7}, {0x366, 0, 7}, {0x4CB, 0, 8}, // DSU bus 0
|
||||
{0x128, 1, 6}, {0x141, 1, 4}, {0x160, 1, 8}, {0x161, 1, 7}, {0x470, 1, 4}, // DSU bus 1
|
||||
{0x2E4, 0, 5}, {0x411, 0, 8}, {0x412, 0, 8}, {0x343, 0, 8}, {0x1D2, 0, 8}, // LKAS + ACC
|
||||
{0x200, 0, 6}, {0x750, 0, 8}}; // interceptor + Blindspot monitor
|
||||
|
||||
AddrCheckStruct toyota_rx_checks[] = {
|
||||
{.addr = { 0xaa}, .bus = 0, .check_checksum = false, .expected_timestep = 12000U},
|
||||
{.addr = {0x260}, .bus = 0, .check_checksum = true, .expected_timestep = 20000U},
|
||||
{.addr = {0x1D2}, .bus = 0, .check_checksum = true, .expected_timestep = 30000U},
|
||||
{.addr = {0x224, 0x226}, .bus = 0, .check_checksum = false, .expected_timestep = 25000U},
|
||||
{.msg = {{ 0xaa, 0, 8, .check_checksum = false, .expected_timestep = 12000U}}},
|
||||
{.msg = {{0x260, 0, 8, .check_checksum = true, .expected_timestep = 20000U}}},
|
||||
{.msg = {{0x1D2, 0, 8, .check_checksum = true, .expected_timestep = 30000U}}},
|
||||
{.msg = {{0x224, 0, 8, .check_checksum = false, .expected_timestep = 25000U},
|
||||
{0x226, 0, 8, .check_checksum = false, .expected_timestep = 25000U}}},
|
||||
};
|
||||
const int TOYOTA_RX_CHECKS_LEN = sizeof(toyota_rx_checks) / sizeof(toyota_rx_checks[0]);
|
||||
|
||||
|
@ -153,7 +154,7 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
|
||||
if (!msg_allowed(addr, bus, TOYOTA_TX_MSGS, sizeof(TOYOTA_TX_MSGS)/sizeof(TOYOTA_TX_MSGS[0]))) {
|
||||
if (!msg_allowed(to_send, TOYOTA_TX_MSGS, sizeof(TOYOTA_TX_MSGS)/sizeof(TOYOTA_TX_MSGS[0]))) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,15 +18,15 @@ const int VOLKSWAGEN_DRIVER_TORQUE_FACTOR = 3;
|
|||
#define MSG_LDW_02 0x397 // TX by OP, Lane line recognition and text alerts
|
||||
|
||||
// Transmit of GRA_ACC_01 is allowed on bus 0 and 2 to keep compatibility with gateway and camera integration
|
||||
const AddrBus VOLKSWAGEN_MQB_TX_MSGS[] = {{MSG_HCA_01, 0}, {MSG_GRA_ACC_01, 0}, {MSG_GRA_ACC_01, 2}, {MSG_LDW_02, 0}};
|
||||
const CanMsg VOLKSWAGEN_MQB_TX_MSGS[] = {{MSG_HCA_01, 0, 8}, {MSG_GRA_ACC_01, 0, 8}, {MSG_GRA_ACC_01, 2, 8}, {MSG_LDW_02, 0, 8}};
|
||||
const int VOLKSWAGEN_MQB_TX_MSGS_LEN = sizeof(VOLKSWAGEN_MQB_TX_MSGS) / sizeof(VOLKSWAGEN_MQB_TX_MSGS[0]);
|
||||
|
||||
AddrCheckStruct volkswagen_mqb_rx_checks[] = {
|
||||
{.addr = {MSG_ESP_19}, .bus = 0, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U},
|
||||
{.addr = {MSG_EPS_01}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U},
|
||||
{.addr = {MSG_ESP_05}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.addr = {MSG_TSK_06}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.addr = {MSG_MOTOR_20}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U},
|
||||
{.msg = {{MSG_ESP_19, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{MSG_EPS_01, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{MSG_ESP_05, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
{.msg = {{MSG_TSK_06, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
{.msg = {{MSG_MOTOR_20, 0, 8, .check_checksum = true, .max_counter = 15U, .expected_timestep = 20000U}}},
|
||||
};
|
||||
const int VOLKSWAGEN_MQB_RX_CHECKS_LEN = sizeof(volkswagen_mqb_rx_checks) / sizeof(volkswagen_mqb_rx_checks[0]);
|
||||
|
||||
|
@ -40,14 +40,14 @@ const int VOLKSWAGEN_MQB_RX_CHECKS_LEN = sizeof(volkswagen_mqb_rx_checks) / size
|
|||
#define MSG_LDW_1 0x5BE // TX by OP, Lane line recognition and text alerts
|
||||
|
||||
// Transmit of GRA_Neu is allowed on bus 0 and 2 to keep compatibility with gateway and camera integration
|
||||
const AddrBus VOLKSWAGEN_PQ_TX_MSGS[] = {{MSG_HCA_1, 0}, {MSG_GRA_NEU, 0}, {MSG_GRA_NEU, 2}, {MSG_LDW_1, 0}};
|
||||
const CanMsg VOLKSWAGEN_PQ_TX_MSGS[] = {{MSG_HCA_1, 0, 5}, {MSG_GRA_NEU, 0, 4}, {MSG_GRA_NEU, 2, 4}, {MSG_LDW_1, 0, 8}};
|
||||
const int VOLKSWAGEN_PQ_TX_MSGS_LEN = sizeof(VOLKSWAGEN_PQ_TX_MSGS) / sizeof(VOLKSWAGEN_PQ_TX_MSGS[0]);
|
||||
|
||||
AddrCheckStruct volkswagen_pq_rx_checks[] = {
|
||||
{.addr = {MSG_LENKHILFE_3}, .bus = 0, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U},
|
||||
{.addr = {MSG_MOTOR_2}, .bus = 0, .check_checksum = false, .max_counter = 0U, .expected_timestep = 20000U},
|
||||
{.addr = {MSG_MOTOR_3}, .bus = 0, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U},
|
||||
{.addr = {MSG_BREMSE_3}, .bus = 0, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U},
|
||||
{.msg = {{MSG_LENKHILFE_3, 0, 6, .check_checksum = true, .max_counter = 15U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{MSG_MOTOR_2, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 20000U}}},
|
||||
{.msg = {{MSG_MOTOR_3, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U}}},
|
||||
{.msg = {{MSG_BREMSE_3, 0, 8, .check_checksum = false, .max_counter = 0U, .expected_timestep = 10000U}}},
|
||||
};
|
||||
const int VOLKSWAGEN_PQ_RX_CHECKS_LEN = sizeof(volkswagen_pq_rx_checks) / sizeof(volkswagen_pq_rx_checks[0]);
|
||||
|
||||
|
@ -311,10 +311,9 @@ static bool volkswagen_steering_check(int desired_torque) {
|
|||
|
||||
static int volkswagen_mqb_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
int tx = 1;
|
||||
|
||||
if (!msg_allowed(addr, bus, VOLKSWAGEN_MQB_TX_MSGS, VOLKSWAGEN_MQB_TX_MSGS_LEN) || relay_malfunction) {
|
||||
if (!msg_allowed(to_send, VOLKSWAGEN_MQB_TX_MSGS, VOLKSWAGEN_MQB_TX_MSGS_LEN) || relay_malfunction) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
|
@ -348,10 +347,9 @@ static int volkswagen_mqb_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
|||
|
||||
static int volkswagen_pq_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||
int addr = GET_ADDR(to_send);
|
||||
int bus = GET_BUS(to_send);
|
||||
int tx = 1;
|
||||
|
||||
if (!msg_allowed(addr, bus, VOLKSWAGEN_PQ_TX_MSGS, VOLKSWAGEN_PQ_TX_MSGS_LEN) || relay_malfunction) {
|
||||
if (!msg_allowed(to_send, VOLKSWAGEN_PQ_TX_MSGS, VOLKSWAGEN_PQ_TX_MSGS_LEN) || relay_malfunction) {
|
||||
tx = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,17 +17,25 @@ struct lookup_t {
|
|||
typedef struct {
|
||||
int addr;
|
||||
int bus;
|
||||
} AddrBus;
|
||||
int len;
|
||||
} CanMsg;
|
||||
|
||||
typedef struct {
|
||||
const int addr;
|
||||
const int bus;
|
||||
const int len;
|
||||
const bool check_checksum; // true is checksum check is performed
|
||||
const uint8_t max_counter; // maximum value of the counter. 0 means that the counter check is skipped
|
||||
const uint32_t expected_timestep; // expected time between message updates [us]
|
||||
} CanMsgCheck;
|
||||
|
||||
// params and flags about checksum, counter and frequency checks for each monitored address
|
||||
typedef struct {
|
||||
// const params
|
||||
const int addr[3]; // check either messages (e.g. honda steer). Array MUST terminate with a zero to know its length.
|
||||
const int bus; // bus where to expect the addr. Temp hack: -1 means skip the bus check
|
||||
const bool check_checksum; // true is checksum check is performed
|
||||
const uint8_t max_counter; // maximum value of the counter. 0 means that the counter check is skipped
|
||||
const uint32_t expected_timestep; // expected time between message updates [us]
|
||||
const CanMsgCheck msg[3]; // check either messages (e.g. honda steer). Array MUST terminate with an empty struct to know its length.
|
||||
// dynamic flags
|
||||
bool msg_seen;
|
||||
int index; // if multiple messages are allowed to be checked, this stores the index of the first one seen. only msg[msg_index] will be used
|
||||
bool valid_checksum; // true if and only if checksum check is passed
|
||||
int wrong_counters; // counter of wrong counters, saturated between 0 and MAX_WRONG_COUNTERS
|
||||
uint8_t last_counter; // last counter value
|
||||
|
@ -50,7 +58,7 @@ bool driver_limit_check(int val, int val_last, struct sample_t *val_driver,
|
|||
bool rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA);
|
||||
float interpolate(struct lookup_t xy, float x);
|
||||
void gen_crc_lookup_table(uint8_t poly, uint8_t crc_lut[]);
|
||||
bool msg_allowed(int addr, int bus, const AddrBus addr_list[], int len);
|
||||
bool msg_allowed(CAN_FIFOMailBox_TypeDef *to_send, const CanMsg msg_list[], int len);
|
||||
int get_addr_check_index(CAN_FIFOMailBox_TypeDef *to_push, AddrCheckStruct addr_list[], const int len);
|
||||
void update_counter(AddrCheckStruct addr_list[], int index, uint8_t counter);
|
||||
void update_addr_timestamp(AddrCheckStruct addr_list[], int index);
|
||||
|
@ -90,15 +98,21 @@ int gas_interceptor_prev = 0;
|
|||
bool gas_pressed_prev = false;
|
||||
bool brake_pressed_prev = false;
|
||||
bool cruise_engaged_prev = false;
|
||||
float vehicle_speed = 0;
|
||||
bool vehicle_moving = false;
|
||||
|
||||
// for torque-based safety modes
|
||||
// for safety modes with torque steering control
|
||||
int desired_torque_last = 0; // last desired steer torque
|
||||
int rt_torque_last = 0; // last desired torque for real time check
|
||||
struct sample_t torque_meas; // last 3 motor torques produced by the eps
|
||||
struct sample_t torque_driver; // last 3 driver torques measured
|
||||
uint32_t ts_last = 0;
|
||||
|
||||
// for safety modes with angle steering control
|
||||
uint32_t ts_angle_last = 0;
|
||||
int desired_angle_last = 0;
|
||||
struct sample_t angle_meas; // last 3 steer angles
|
||||
|
||||
// This can be set with a USB command
|
||||
// It enables features we consider to be unsafe, but understand others may have different opinions
|
||||
// It is always 0 on mainline comma.ai openpilot
|
||||
|
|
|
@ -10,12 +10,13 @@ import time
|
|||
import traceback
|
||||
import subprocess
|
||||
import sys
|
||||
from .dfu import PandaDFU
|
||||
from .esptool import ESPROM, CesantaFlasher # noqa: F401
|
||||
from .flash_release import flash_release # noqa: F401
|
||||
from .update import ensure_st_up_to_date # noqa: F401
|
||||
from .serial import PandaSerial # noqa: F401
|
||||
from .isotp import isotp_send, isotp_recv
|
||||
from .dfu import PandaDFU # pylint: disable=import-error
|
||||
from .esptool import ESPROM, CesantaFlasher # noqa pylint: disable=import-error
|
||||
from .flash_release import flash_release # noqa pylint: disable=import-error
|
||||
from .update import ensure_st_up_to_date # noqa pylint: disable=import-error
|
||||
from .serial import PandaSerial # noqa pylint: disable=import-error
|
||||
from .isotp import isotp_send, isotp_recv # pylint: disable=import-error
|
||||
|
||||
|
||||
__version__ = '0.0.9'
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import time
|
||||
import struct
|
||||
from collections import deque
|
||||
from typing import Callable, NamedTuple, Tuple, List
|
||||
from typing import Callable, NamedTuple, Tuple, List, Deque, Generator, Optional, cast
|
||||
from enum import IntEnum
|
||||
|
||||
class SERVICE_TYPE(IntEnum):
|
||||
|
@ -271,12 +271,12 @@ _negative_response_codes = {
|
|||
|
||||
|
||||
class CanClient():
|
||||
def __init__(self, can_send: Callable[[Tuple[int, bytes, int]], None], can_recv: Callable[[], List[Tuple[int, int, bytes, int]]], tx_addr: int, rx_addr: int, bus: int, sub_addr: int=None, debug: bool=False):
|
||||
def __init__(self, can_send: Callable[[int, bytes, int], None], can_recv: Callable[[], List[Tuple[int, int, bytes, int]]], tx_addr: int, rx_addr: int, bus: int, sub_addr: int=None, debug: bool=False):
|
||||
self.tx = can_send
|
||||
self.rx = can_recv
|
||||
self.tx_addr = tx_addr
|
||||
self.rx_addr = rx_addr
|
||||
self.rx_buff = deque()
|
||||
self.rx_buff = deque() # type: Deque[bytes]
|
||||
self.sub_addr = sub_addr
|
||||
self.bus = bus
|
||||
self.debug = debug
|
||||
|
@ -320,7 +320,7 @@ class CanClient():
|
|||
if len(msgs) < 254:
|
||||
return
|
||||
|
||||
def recv(self, drain: bool=False) -> List[bytes]:
|
||||
def recv(self, drain: bool=False) -> Generator[bytes, None, None]:
|
||||
# buffer rx messages in case two response messages are received at once
|
||||
# (e.g. response pending and success/failure response)
|
||||
self._recv_buffer(drain)
|
||||
|
@ -372,7 +372,7 @@ class IsoTpMessage():
|
|||
self._tx_first_frame()
|
||||
|
||||
def _tx_first_frame(self) -> None:
|
||||
if self.tx_len < 8:
|
||||
if self.tx_len < self.max_len:
|
||||
# single frame (send all bytes)
|
||||
if self.debug: print("ISO-TP: TX - single frame")
|
||||
msg = (bytes([self.tx_len]) + self.tx_dat).ljust(self.max_len, b"\x00")
|
||||
|
@ -380,10 +380,10 @@ class IsoTpMessage():
|
|||
else:
|
||||
# first frame (send first 6 bytes)
|
||||
if self.debug: print("ISO-TP: TX - first frame")
|
||||
msg = (struct.pack("!H", 0x1000 | self.tx_len) + self.tx_dat[:6]).ljust(self.max_len, b"\x00")
|
||||
msg = (struct.pack("!H", 0x1000 | self.tx_len) + self.tx_dat[:self.max_len - 2]).ljust(self.max_len - 2, b"\x00")
|
||||
self._can_client.send([msg])
|
||||
|
||||
def recv(self) -> bytes:
|
||||
def recv(self) -> Optional[bytes]:
|
||||
start_time = time.time()
|
||||
try:
|
||||
while True:
|
||||
|
@ -416,7 +416,7 @@ class IsoTpMessage():
|
|||
self.rx_idx = 0
|
||||
self.rx_done = False
|
||||
if self.debug: print(f"ISO-TP: RX - first frame - idx={self.rx_idx} done={self.rx_done}")
|
||||
if self.debug: print(f"ISO-TP: TX - flow control continue")
|
||||
if self.debug: print("ISO-TP: TX - flow control continue")
|
||||
# send flow control message (send all bytes)
|
||||
msg = b"\x30\x00\x00".ljust(self.max_len, b"\x00")
|
||||
self._can_client.send([msg])
|
||||
|
@ -505,6 +505,10 @@ class UdsClient():
|
|||
isotp_msg.send(req)
|
||||
while True:
|
||||
resp = isotp_msg.recv()
|
||||
|
||||
if resp is None:
|
||||
continue
|
||||
|
||||
resp_sid = resp[0] if len(resp) > 0 else None
|
||||
|
||||
# negative response
|
||||
|
@ -518,7 +522,7 @@ class UdsClient():
|
|||
try:
|
||||
error_desc = _negative_response_codes[error_code]
|
||||
except BaseException:
|
||||
error_desc = resp[3:]
|
||||
error_desc = resp[3:].hex()
|
||||
# wait for another message if response pending
|
||||
if error_code == 0x78:
|
||||
if self.debug: print("UDS-RX: response pending")
|
||||
|
@ -534,7 +538,7 @@ class UdsClient():
|
|||
resp_sfn = resp[1] if len(resp) > 1 else None
|
||||
if subfunction != resp_sfn:
|
||||
resp_sfn_hex = hex(resp_sfn) if resp_sfn is not None else None
|
||||
raise InvalidSubFunctioneError('invalid response subfunction: {}'.format(hex(resp_sfn_hex)))
|
||||
raise InvalidSubFunctioneError(f'invalid response subfunction: {resp_sfn_hex:x}')
|
||||
|
||||
# return data (exclude service id and sub-function id)
|
||||
return resp[(1 if subfunction is None else 2):]
|
||||
|
@ -595,7 +599,7 @@ class UdsClient():
|
|||
|
||||
def response_on_event(self, response_event_type: RESPONSE_EVENT_TYPE, store_event: bool, window_time: int, event_type_record: int, service_response_record: int):
|
||||
if store_event:
|
||||
response_event_type |= 0x20
|
||||
response_event_type |= 0x20 # type: ignore
|
||||
# TODO: split record parameters into arrays
|
||||
data = bytes([window_time, event_type_record, service_response_record])
|
||||
resp = self._uds_request(SERVICE_TYPE.RESPONSE_ON_EVENT, subfunction=response_event_type, data=data)
|
||||
|
@ -613,9 +617,11 @@ class UdsClient():
|
|||
}
|
||||
|
||||
def link_control(self, link_control_type: LINK_CONTROL_TYPE, baud_rate_type: BAUD_RATE_TYPE=None):
|
||||
data : Optional[bytes]
|
||||
|
||||
if link_control_type == LINK_CONTROL_TYPE.VERIFY_BAUDRATE_TRANSITION_WITH_FIXED_BAUDRATE:
|
||||
# baud_rate_type = BAUD_RATE_TYPE
|
||||
data = bytes([baud_rate_type])
|
||||
data = bytes([cast(int, baud_rate_type)])
|
||||
elif link_control_type == LINK_CONTROL_TYPE.VERIFY_BAUDRATE_TRANSITION_WITH_SPECIFIC_BAUDRATE:
|
||||
# baud_rate_type = custom value (3 bytes big-endian)
|
||||
data = struct.pack('!I', baud_rate_type)[1:]
|
||||
|
@ -671,16 +677,16 @@ class UdsClient():
|
|||
data = struct.pack('!H', dynamic_data_identifier)
|
||||
if dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.DEFINE_BY_IDENTIFIER:
|
||||
for s in source_definitions:
|
||||
data += struct.pack('!H', s["data_identifier"]) + bytes([s["position"], s["memory_size"]])
|
||||
data += struct.pack('!H', s.data_identifier) + bytes([s.position, s.memory_size])
|
||||
elif dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.DEFINE_BY_MEMORY_ADDRESS:
|
||||
data += bytes([memory_size_bytes<<4 | memory_address_bytes])
|
||||
for s in source_definitions:
|
||||
if s["memory_address"] >= 1<<(memory_address_bytes*8):
|
||||
raise ValueError('invalid memory_address: {}'.format(s["memory_address"]))
|
||||
data += struct.pack('!I', s["memory_address"])[4-memory_address_bytes:]
|
||||
if s["memory_size"] >= 1<<(memory_size_bytes*8):
|
||||
raise ValueError('invalid memory_size: {}'.format(s["memory_size"]))
|
||||
data += struct.pack('!I', s["memory_size"])[4-memory_size_bytes:]
|
||||
if s.memory_address >= 1<<(memory_address_bytes*8):
|
||||
raise ValueError('invalid memory_address: {}'.format(s.memory_address))
|
||||
data += struct.pack('!I', s.memory_address)[4-memory_address_bytes:]
|
||||
if s.memory_size >= 1<<(memory_size_bytes*8):
|
||||
raise ValueError('invalid memory_size: {}'.format(s.memory_size))
|
||||
data += struct.pack('!I', s.memory_size)[4-memory_size_bytes:]
|
||||
elif dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.CLEAR_DYNAMICALLY_DEFINED_DATA_IDENTIFIER:
|
||||
pass
|
||||
else:
|
||||
|
@ -736,7 +742,7 @@ class UdsClient():
|
|||
if dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_IDENTIFICATION or \
|
||||
dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_RECORD_BY_DTC_NUMBER or \
|
||||
dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_RECORD_BY_RECORD_NUMBER:
|
||||
data += ord(dtc_snapshot_record_num)
|
||||
data += bytes([dtc_snapshot_record_num])
|
||||
# dtc_extended_record_num
|
||||
if dtc_report_type == DTC_REPORT_TYPE.DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER or \
|
||||
dtc_report_type == DTC_REPORT_TYPE.MIRROR_MEMORY_DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER:
|
||||
|
@ -784,7 +790,7 @@ class UdsClient():
|
|||
data += struct.pack('!I', memory_size)[4-memory_size_bytes:]
|
||||
|
||||
resp = self._uds_request(SERVICE_TYPE.REQUEST_DOWNLOAD, subfunction=None, data=data)
|
||||
max_num_bytes_len = resp[0] >> 4 if len(resp) > 0 else None
|
||||
max_num_bytes_len = resp[0] >> 4 if len(resp) > 0 else 0
|
||||
if max_num_bytes_len >= 1 and max_num_bytes_len <= 4:
|
||||
max_num_bytes = struct.unpack('!I', (b"\x00"*(4-max_num_bytes_len))+resp[1:max_num_bytes_len+1])[0]
|
||||
else:
|
||||
|
@ -809,7 +815,7 @@ class UdsClient():
|
|||
data += struct.pack('!I', memory_size)[4-memory_size_bytes:]
|
||||
|
||||
resp = self._uds_request(SERVICE_TYPE.REQUEST_UPLOAD, subfunction=None, data=data)
|
||||
max_num_bytes_len = resp[0] >> 4 if len(resp) > 0 else None
|
||||
max_num_bytes_len = resp[0] >> 4 if len(resp) > 0 else 0
|
||||
if max_num_bytes_len >= 1 and max_num_bytes_len <= 4:
|
||||
max_num_bytes = struct.unpack('!I', (b"\x00"*(4-max_num_bytes_len))+resp[1:max_num_bytes_len+1])[0]
|
||||
else:
|
||||
|
|
|
@ -7,6 +7,7 @@ nose
|
|||
parameterized
|
||||
requests
|
||||
flake8==3.7.9
|
||||
pylint==2.4.3
|
||||
cffi==1.11.4
|
||||
crcmod
|
||||
pre-commit==2.4.0
|
||||
pylint==2.5.2
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
import requests
|
||||
import json
|
||||
from .automated.helpers import _connect_wifi
|
||||
from .automated.helpers import _connect_wifi # pylint: disable=import-error
|
||||
from panda import Panda
|
||||
from nose.tools import assert_equal
|
||||
|
||||
|
@ -25,5 +25,3 @@ if __name__ == "__main__":
|
|||
assert_equal(str(dongle_id), wifi_dongle_id)
|
||||
assert_equal(latest_version, st_version)
|
||||
assert_equal(latest_version, esp_version)
|
||||
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ def test_orientation_detection(p):
|
|||
reset_pandas()
|
||||
p.reconnect()
|
||||
detected_harness_orientation = p.health()['car_harness_status']
|
||||
print(f"Detected orientation: {detected_harness_orientation}")
|
||||
if (i == 0 and detected_harness_orientation != 0) or detected_harness_orientation in seen_orientations:
|
||||
assert False
|
||||
seen_orientations.append(detected_harness_orientation)
|
||||
|
|
|
@ -14,7 +14,7 @@ def test_gps_version(p):
|
|||
for i in range(2):
|
||||
# Reset GPS
|
||||
p.set_esp_power(0)
|
||||
time.sleep(0.5)
|
||||
time.sleep(2)
|
||||
p.set_esp_power(1)
|
||||
time.sleep(1)
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ from .wifi_helpers import _connect_wifi
|
|||
SPEED_NORMAL = 500
|
||||
SPEED_GMLAN = 33.3
|
||||
BUS_SPEEDS = [(0, SPEED_NORMAL), (1, SPEED_NORMAL), (2, SPEED_NORMAL), (3, SPEED_GMLAN)]
|
||||
TIMEOUT = 30
|
||||
TIMEOUT = 45
|
||||
GEN2_HW_TYPES = [Panda.HW_TYPE_BLACK_PANDA, Panda.HW_TYPE_UNO]
|
||||
GPS_HW_TYPES = [Panda.HW_TYPE_GREY_PANDA, Panda.HW_TYPE_BLACK_PANDA, Panda.HW_TYPE_UNO]
|
||||
|
||||
|
@ -41,16 +41,17 @@ init_panda_serials()
|
|||
test_all_types = parameterized([
|
||||
param(panda_type=Panda.HW_TYPE_WHITE_PANDA),
|
||||
param(panda_type=Panda.HW_TYPE_GREY_PANDA),
|
||||
param(panda_type=Panda.HW_TYPE_BLACK_PANDA)
|
||||
param(panda_type=Panda.HW_TYPE_BLACK_PANDA),
|
||||
param(panda_type=Panda.HW_TYPE_UNO)
|
||||
])
|
||||
test_all_pandas = parameterized(
|
||||
list(map(lambda x: x[0], _panda_serials))
|
||||
list(map(lambda x: x[0], _panda_serials)) # type: ignore
|
||||
)
|
||||
test_all_gen2_pandas = parameterized(
|
||||
list(map(lambda x: x[0], filter(lambda x: x[1] in GEN2_HW_TYPES, _panda_serials)))
|
||||
list(map(lambda x: x[0], filter(lambda x: x[1] in GEN2_HW_TYPES, _panda_serials))) # type: ignore
|
||||
)
|
||||
test_all_gps_pandas = parameterized(
|
||||
list(map(lambda x: x[0], filter(lambda x: x[1] in GPS_HW_TYPES, _panda_serials)))
|
||||
list(map(lambda x: x[0], filter(lambda x: x[1] in GPS_HW_TYPES, _panda_serials))) # type: ignore
|
||||
)
|
||||
test_white_and_grey = parameterized([
|
||||
param(panda_type=Panda.HW_TYPE_WHITE_PANDA),
|
||||
|
@ -65,6 +66,9 @@ test_grey = parameterized([
|
|||
test_black = parameterized([
|
||||
param(panda_type=Panda.HW_TYPE_BLACK_PANDA)
|
||||
])
|
||||
test_uno = parameterized([
|
||||
param(panda_type=Panda.HW_TYPE_UNO)
|
||||
])
|
||||
|
||||
def connect_wifi(serial=None):
|
||||
p = Panda(serial=serial)
|
||||
|
@ -112,7 +116,7 @@ def time_many_sends(p, bus, p_recv=None, msg_count=100, msg_id=None, two_pandas=
|
|||
|
||||
def reset_pandas():
|
||||
panda_jungle.set_panda_power(False)
|
||||
time.sleep(2)
|
||||
time.sleep(3)
|
||||
panda_jungle.set_panda_power(True)
|
||||
time.sleep(5)
|
||||
|
||||
|
@ -198,7 +202,7 @@ def panda_connect_and_init(fn):
|
|||
finally:
|
||||
# Close all connections
|
||||
for panda in pandas:
|
||||
panda.close()
|
||||
panda.close()
|
||||
return wrapper
|
||||
|
||||
def clear_can_buffers(panda):
|
||||
|
|
|
@ -1,21 +1,13 @@
|
|||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi python python-pip gcc g++ git autoconf gperf bison flex automake texinfo wget help2man gawk libtool libtool-bin ncurses-dev unzip unrar-free libexpat-dev sed bzip2 locales curl zlib1g-dev libffi-dev libssl-dev
|
||||
RUN apt-get update && apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi python python-pip gcc g++ git autoconf gperf bison flex automake texinfo wget help2man gawk libtool libtool-bin ncurses-dev unzip unrar-free libexpat-dev sed bzip2 locales curl zlib1g-dev libffi-dev libssl-dev python3 python3-pip
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
RUN pyenv install 2.7.12
|
||||
RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
RUN pip install pycrypto==2.6.1
|
||||
RUN pip3 install pycrypto==2.6.1
|
||||
|
||||
# Build esp toolchain
|
||||
RUN mkdir -p /panda/boardesp
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
import time
|
||||
import threading
|
||||
import time
|
||||
from typing import Any, List
|
||||
|
||||
from panda import Panda
|
||||
|
||||
|
@ -18,18 +19,18 @@ if __name__ == "__main__":
|
|||
serials = Panda.list()
|
||||
if len(serials) != 2:
|
||||
raise Exception("Connect two pandas to perform this test!")
|
||||
|
||||
|
||||
sender = Panda(serials[0])
|
||||
receiver = Panda(serials[1])
|
||||
|
||||
|
||||
sender.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
receiver.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||
|
||||
|
||||
# Start transmisson
|
||||
threading.Thread(target=flood_tx, args=(sender,)).start()
|
||||
|
||||
# Receive as much as we can in a few second time period
|
||||
rx = []
|
||||
rx: List[Any] = []
|
||||
old_len = 0
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < 2 or len(rx) > old_len:
|
||||
|
|
|
@ -28,7 +28,7 @@ if __name__ == "__main__":
|
|||
|
||||
if os.getenv("BAUD") is not None:
|
||||
for panda in pandas:
|
||||
panda.set_uart_baud(port_number, int(os.getenv("BAUD")))
|
||||
panda.set_uart_baud(port_number, int(os.getenv("BAUD"))) # type: ignore
|
||||
|
||||
while True:
|
||||
for i, panda in enumerate(pandas):
|
||||
|
|
|
@ -299,10 +299,10 @@ class ELMCarSimulator():
|
|||
|
||||
if __name__ == "__main__":
|
||||
serial = os.getenv("SERIAL") if os.getenv("SERIAL") else None
|
||||
kbaud = int(os.getenv("CANKBAUD")) if os.getenv("CANKBAUD") else 500
|
||||
bitwidth = int(os.getenv("CANBITWIDTH")) if os.getenv("CANBITWIDTH") else 0
|
||||
canenable = bool(int(os.getenv("CANENABLE"))) if os.getenv("CANENABLE") else True
|
||||
linenable = bool(int(os.getenv("LINENABLE"))) if os.getenv("LINENABLE") else True
|
||||
kbaud = int(os.getenv("CANKBAUD")) if os.getenv("CANKBAUD") else 500 # type: ignore
|
||||
bitwidth = int(os.getenv("CANBITWIDTH")) if os.getenv("CANBITWIDTH") else 0 # type: ignore
|
||||
canenable = bool(int(os.getenv("CANENABLE"))) if os.getenv("CANENABLE") else True # type: ignore
|
||||
linenable = bool(int(os.getenv("LINENABLE"))) if os.getenv("LINENABLE") else True # type: ignore
|
||||
sim = ELMCarSimulator(serial, can_kbaud=kbaud, can=canenable, lin=linenable)
|
||||
if(bitwidth == 0):
|
||||
sim.can_mode_11b_29b()
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y make python python-pip locales curl git zlib1g-dev libffi-dev bzip2 libssl-dev
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY . /panda
|
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -1,451 +0,0 @@
|
|||
4r5e
|
||||
5h1t
|
||||
5hit
|
||||
a55
|
||||
anal
|
||||
anus
|
||||
ar5e
|
||||
arrse
|
||||
arse
|
||||
ass
|
||||
ass-fucker
|
||||
asses
|
||||
assfucker
|
||||
assfukka
|
||||
asshole
|
||||
assholes
|
||||
asswhole
|
||||
a_s_s
|
||||
b!tch
|
||||
b00bs
|
||||
b17ch
|
||||
b1tch
|
||||
ballbag
|
||||
balls
|
||||
ballsack
|
||||
bastard
|
||||
beastial
|
||||
beastiality
|
||||
bellend
|
||||
bestial
|
||||
bestiality
|
||||
bi+ch
|
||||
biatch
|
||||
bitch
|
||||
bitcher
|
||||
bitchers
|
||||
bitches
|
||||
bitchin
|
||||
bitching
|
||||
bloody
|
||||
blow job
|
||||
blowjob
|
||||
blowjobs
|
||||
boiolas
|
||||
bollock
|
||||
bollok
|
||||
boner
|
||||
boob
|
||||
boobs
|
||||
booobs
|
||||
boooobs
|
||||
booooobs
|
||||
booooooobs
|
||||
breasts
|
||||
buceta
|
||||
bugger
|
||||
bum
|
||||
bunny fucker
|
||||
bullshit
|
||||
butt
|
||||
butthole
|
||||
buttmuch
|
||||
buttplug
|
||||
c0ck
|
||||
c0cksucker
|
||||
carpet muncher
|
||||
cawk
|
||||
chink
|
||||
cipa
|
||||
cl1t
|
||||
clit
|
||||
clitoris
|
||||
clits
|
||||
cnut
|
||||
cock
|
||||
cock-sucker
|
||||
cockface
|
||||
cockhead
|
||||
cockmunch
|
||||
cockmuncher
|
||||
cocks
|
||||
cocksuck
|
||||
cocksucked
|
||||
cocksucker
|
||||
cocksucking
|
||||
cocksucks
|
||||
cocksuka
|
||||
cocksukka
|
||||
cok
|
||||
cokmuncher
|
||||
coksucka
|
||||
coon
|
||||
cox
|
||||
crap
|
||||
cum
|
||||
cummer
|
||||
cumming
|
||||
cums
|
||||
cumshot
|
||||
cunilingus
|
||||
cunillingus
|
||||
cunnilingus
|
||||
cunt
|
||||
cuntlick
|
||||
cuntlicker
|
||||
cuntlicking
|
||||
cunts
|
||||
cyalis
|
||||
cyberfuc
|
||||
cyberfuck
|
||||
cyberfucked
|
||||
cyberfucker
|
||||
cyberfuckers
|
||||
cyberfucking
|
||||
d1ck
|
||||
damn
|
||||
dick
|
||||
dickhead
|
||||
dildo
|
||||
dildos
|
||||
dink
|
||||
dinks
|
||||
dirsa
|
||||
dlck
|
||||
dog-fucker
|
||||
doggin
|
||||
dogging
|
||||
donkeyribber
|
||||
doosh
|
||||
duche
|
||||
dyke
|
||||
ejaculate
|
||||
ejaculated
|
||||
ejaculates
|
||||
ejaculating
|
||||
ejaculatings
|
||||
ejaculation
|
||||
ejakulate
|
||||
f u c k
|
||||
f u c k e r
|
||||
f4nny
|
||||
fag
|
||||
fagging
|
||||
faggitt
|
||||
faggot
|
||||
faggs
|
||||
fagot
|
||||
fagots
|
||||
fags
|
||||
fanny
|
||||
fannyflaps
|
||||
fannyfucker
|
||||
fanyy
|
||||
fatass
|
||||
fcuk
|
||||
fcuker
|
||||
fcuking
|
||||
feck
|
||||
fecker
|
||||
felching
|
||||
fellate
|
||||
fellatio
|
||||
fingerfuck
|
||||
fingerfucked
|
||||
fingerfucker
|
||||
fingerfuckers
|
||||
fingerfucking
|
||||
fingerfucks
|
||||
fistfuck
|
||||
fistfucked
|
||||
fistfucker
|
||||
fistfuckers
|
||||
fistfucking
|
||||
fistfuckings
|
||||
fistfucks
|
||||
flange
|
||||
fook
|
||||
fooker
|
||||
fuck
|
||||
fucka
|
||||
fucked
|
||||
fucker
|
||||
fuckers
|
||||
fuckhead
|
||||
fuckheads
|
||||
fuckin
|
||||
fucking
|
||||
fuckings
|
||||
fuckingshitmotherfucker
|
||||
fuckme
|
||||
fucks
|
||||
fuckwhit
|
||||
fuckwit
|
||||
fudge packer
|
||||
fudgepacker
|
||||
fuk
|
||||
fuker
|
||||
fukker
|
||||
fukkin
|
||||
fuks
|
||||
fukwhit
|
||||
fukwit
|
||||
fux
|
||||
fux0r
|
||||
f_u_c_k
|
||||
gangbang
|
||||
gangbanged
|
||||
gangbangs
|
||||
gaylord
|
||||
gaysex
|
||||
goatse
|
||||
God
|
||||
god-dam
|
||||
god-damned
|
||||
goddamn
|
||||
goddamned
|
||||
hardcoresex
|
||||
hell
|
||||
heshe
|
||||
hoar
|
||||
hoare
|
||||
hoer
|
||||
homo
|
||||
hore
|
||||
horniest
|
||||
horny
|
||||
hotsex
|
||||
jack-off
|
||||
jackoff
|
||||
jap
|
||||
jerk-off
|
||||
jism
|
||||
jiz
|
||||
jizm
|
||||
jizz
|
||||
kawk
|
||||
knob
|
||||
knobead
|
||||
knobed
|
||||
knobend
|
||||
knobhead
|
||||
knobjocky
|
||||
knobjokey
|
||||
kock
|
||||
kondum
|
||||
kondums
|
||||
kum
|
||||
kummer
|
||||
kumming
|
||||
kums
|
||||
kunilingus
|
||||
l3i+ch
|
||||
l3itch
|
||||
labia
|
||||
lmfao
|
||||
lust
|
||||
lusting
|
||||
m0f0
|
||||
m0fo
|
||||
m45terbate
|
||||
ma5terb8
|
||||
ma5terbate
|
||||
masochist
|
||||
master-bate
|
||||
masterb8
|
||||
masterbat*
|
||||
masterbat3
|
||||
masterbate
|
||||
masterbation
|
||||
masterbations
|
||||
masturbate
|
||||
mo-fo
|
||||
mof0
|
||||
mofo
|
||||
mothafuck
|
||||
mothafucka
|
||||
mothafuckas
|
||||
mothafuckaz
|
||||
mothafucked
|
||||
mothafucker
|
||||
mothafuckers
|
||||
mothafuckin
|
||||
mothafucking
|
||||
mothafuckings
|
||||
mothafucks
|
||||
mother fucker
|
||||
motherfuck
|
||||
motherfucked
|
||||
motherfucker
|
||||
motherfuckers
|
||||
motherfuckin
|
||||
motherfucking
|
||||
motherfuckings
|
||||
motherfuckka
|
||||
motherfucks
|
||||
muff
|
||||
mutha
|
||||
muthafecker
|
||||
muthafuckker
|
||||
muther
|
||||
mutherfucker
|
||||
n1gga
|
||||
n1gger
|
||||
nazi
|
||||
nigg3r
|
||||
nigg4h
|
||||
nigga
|
||||
niggah
|
||||
niggas
|
||||
niggaz
|
||||
nigger
|
||||
niggers
|
||||
nob
|
||||
nob jokey
|
||||
nobhead
|
||||
nobjocky
|
||||
nobjokey
|
||||
numbnuts
|
||||
nutsack
|
||||
orgasim
|
||||
orgasims
|
||||
orgasm
|
||||
orgasms
|
||||
p0rn
|
||||
pawn
|
||||
pecker
|
||||
penis
|
||||
penisfucker
|
||||
phonesex
|
||||
phuck
|
||||
phuk
|
||||
phuked
|
||||
phuking
|
||||
phukked
|
||||
phukking
|
||||
phuks
|
||||
phuq
|
||||
pigfucker
|
||||
pimpis
|
||||
piss
|
||||
pissed
|
||||
pisser
|
||||
pissers
|
||||
pisses
|
||||
pissflaps
|
||||
pissin
|
||||
pissing
|
||||
pissoff
|
||||
poop
|
||||
porn
|
||||
porno
|
||||
pornography
|
||||
pornos
|
||||
prick
|
||||
pricks
|
||||
pron
|
||||
pube
|
||||
pusse
|
||||
pussi
|
||||
pussies
|
||||
pussy
|
||||
pussys
|
||||
rectum
|
||||
retard
|
||||
rimjaw
|
||||
rimming
|
||||
s hit
|
||||
s.o.b.
|
||||
sadist
|
||||
schlong
|
||||
screwing
|
||||
scroat
|
||||
scrote
|
||||
scrotum
|
||||
semen
|
||||
sex
|
||||
sh!+
|
||||
sh!t
|
||||
sh1t
|
||||
shag
|
||||
shagger
|
||||
shaggin
|
||||
shagging
|
||||
shemale
|
||||
shi+
|
||||
shit
|
||||
shitdick
|
||||
shite
|
||||
shited
|
||||
shitey
|
||||
shitfuck
|
||||
shitfull
|
||||
shithead
|
||||
shiting
|
||||
shitings
|
||||
shits
|
||||
shitted
|
||||
shitter
|
||||
shitters
|
||||
shitting
|
||||
shittings
|
||||
shitty
|
||||
skank
|
||||
slut
|
||||
sluts
|
||||
smegma
|
||||
smut
|
||||
snatch
|
||||
son-of-a-bitch
|
||||
spac
|
||||
spunk
|
||||
s_h_i_t
|
||||
t1tt1e5
|
||||
t1tties
|
||||
teets
|
||||
teez
|
||||
testical
|
||||
testicle
|
||||
tit
|
||||
titfuck
|
||||
tits
|
||||
titt
|
||||
tittie5
|
||||
tittiefucker
|
||||
titties
|
||||
tittyfuck
|
||||
tittywank
|
||||
titwank
|
||||
tosser
|
||||
turd
|
||||
tw4t
|
||||
twat
|
||||
twathead
|
||||
twatty
|
||||
twunt
|
||||
twunter
|
||||
v14gra
|
||||
v1gra
|
||||
vagina
|
||||
viagra
|
||||
vulva
|
||||
w00se
|
||||
wang
|
||||
wank
|
||||
wanker
|
||||
wanky
|
||||
whoar
|
||||
whore
|
||||
willies
|
||||
willy
|
||||
xrated
|
|
@ -1,28 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
checked_ext = ["h", "c", "py", "pyx", "cpp", "hpp", "md", "mk"]
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("list.txt", 'r') as handle:
|
||||
|
||||
suffix_cmd = " "
|
||||
for i in checked_ext:
|
||||
suffix_cmd += "--include \*." + i + " "
|
||||
|
||||
found_bad_language = False
|
||||
for line in handle:
|
||||
line = line.rstrip('\n').rstrip(" ")
|
||||
try:
|
||||
cmd = "cd ../../; grep -R -i -w " + suffix_cmd + " '" + line + "'"
|
||||
res = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
|
||||
print(res)
|
||||
found_bad_language = True
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
if found_bad_language:
|
||||
sys.exit("Failed: found bad language")
|
||||
else:
|
||||
print("Success")
|
|
@ -1,585 +0,0 @@
|
|||
[MASTER]
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code
|
||||
extension-pkg-whitelist=scipy
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the blacklist. The
|
||||
# regex matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint.
|
||||
jobs=4
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# Specify a configuration file.
|
||||
#rcfile=
|
||||
|
||||
# When enabled, pylint would attempt to guess common misconfiguration and emit
|
||||
# user-friendly hints instead of false-positive error messages
|
||||
suggestion-mode=yes
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
||||
confidence=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once).You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
disable=print-statement,
|
||||
parameter-unpacking,
|
||||
unpacking-in-except,
|
||||
old-raise-syntax,
|
||||
backtick,
|
||||
long-suffix,
|
||||
old-ne-operator,
|
||||
old-octal-literal,
|
||||
import-star-module-level,
|
||||
non-ascii-bytes-literal,
|
||||
raw-checker-failed,
|
||||
bad-inline-option,
|
||||
locally-disabled,
|
||||
locally-enabled,
|
||||
file-ignored,
|
||||
suppressed-message,
|
||||
useless-suppression,
|
||||
deprecated-pragma,
|
||||
apply-builtin,
|
||||
basestring-builtin,
|
||||
buffer-builtin,
|
||||
cmp-builtin,
|
||||
coerce-builtin,
|
||||
execfile-builtin,
|
||||
file-builtin,
|
||||
long-builtin,
|
||||
raw_input-builtin,
|
||||
reduce-builtin,
|
||||
standarderror-builtin,
|
||||
unicode-builtin,
|
||||
xrange-builtin,
|
||||
coerce-method,
|
||||
delslice-method,
|
||||
getslice-method,
|
||||
setslice-method,
|
||||
no-absolute-import,
|
||||
old-division,
|
||||
dict-iter-method,
|
||||
dict-view-method,
|
||||
next-method-called,
|
||||
metaclass-assignment,
|
||||
indexing-exception,
|
||||
raising-string,
|
||||
reload-builtin,
|
||||
oct-method,
|
||||
hex-method,
|
||||
nonzero-method,
|
||||
cmp-method,
|
||||
input-builtin,
|
||||
round-builtin,
|
||||
intern-builtin,
|
||||
unichr-builtin,
|
||||
map-builtin-not-iterating,
|
||||
zip-builtin-not-iterating,
|
||||
range-builtin-not-iterating,
|
||||
filter-builtin-not-iterating,
|
||||
using-cmp-argument,
|
||||
eq-without-hash,
|
||||
div-method,
|
||||
idiv-method,
|
||||
rdiv-method,
|
||||
exception-message-attribute,
|
||||
invalid-str-codec,
|
||||
sys-max-int,
|
||||
bad-python3-import,
|
||||
deprecated-string-function,
|
||||
deprecated-str-translate-call,
|
||||
deprecated-itertools-function,
|
||||
deprecated-types-field,
|
||||
next-method-defined,
|
||||
dict-items-not-iterating,
|
||||
dict-keys-not-iterating,
|
||||
dict-values-not-iterating,
|
||||
bad-indentation,
|
||||
line-too-long,
|
||||
missing-docstring,
|
||||
multiple-statements,
|
||||
bad-continuation,
|
||||
invalid-name,
|
||||
too-many-arguments,
|
||||
too-many-locals,
|
||||
superfluous-parens,
|
||||
bad-whitespace,
|
||||
too-many-instance-attributes,
|
||||
wrong-import-position,
|
||||
ungrouped-imports,
|
||||
wrong-import-order,
|
||||
protected-access,
|
||||
trailing-whitespace,
|
||||
too-many-branches,
|
||||
too-few-public-methods,
|
||||
too-many-statements,
|
||||
trailing-newlines,
|
||||
attribute-defined-outside-init,
|
||||
too-many-return-statements,
|
||||
too-many-public-methods,
|
||||
unused-argument,
|
||||
old-style-class,
|
||||
no-init,
|
||||
len-as-condition,
|
||||
unneeded-not,
|
||||
no-self-use,
|
||||
multiple-imports,
|
||||
no-else-return,
|
||||
logging-not-lazy,
|
||||
fixme,
|
||||
redefined-outer-name,
|
||||
unused-variable,
|
||||
unsubscriptable-object,
|
||||
expression-not-assigned,
|
||||
too-many-boolean-expressions,
|
||||
consider-using-ternary,
|
||||
invalid-unary-operand-type,
|
||||
relative-import,
|
||||
deprecated-lambda
|
||||
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
enable=c-extension-no-member
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Python expression which should return a note less than 10 (10 is the highest
|
||||
# note). You have access to the variables errors warning, statement which
|
||||
# respectively contain the number of errors / warnings messages and the total
|
||||
# number of statements analyzed. This is used by the global evaluation report
|
||||
# (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details
|
||||
#msg-template=
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, json
|
||||
# and msvs (visual studio).You can also give a reporter class, eg
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Tells whether to display a full report or only the messages
|
||||
reports=no
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=yes
|
||||
|
||||
|
||||
[REFACTORING]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=5
|
||||
|
||||
# Complete name of functions that never returns. When checking for
|
||||
# inconsistent-return-statements if a never returning function is called then
|
||||
# it will be considered as an explicit return statement and no message will be
|
||||
# printed.
|
||||
never-returning-functions=optparse.Values,sys.exit
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Limits count of emitted suggestions for spelling mistakes
|
||||
max-spelling-suggestions=4
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
||||
# install python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to indicated private dictionary in
|
||||
# --spelling-private-dict-file option instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,
|
||||
XXX,
|
||||
TODO
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=capnp.* cereal.* pygame.* zmq.* setproctitle.* smbus2.* usb1.* serial.* cv2.*
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# This flag controls whether pylint should warn about no-member and similar
|
||||
# checks whenever an opaque object is returned when inferring. The inference
|
||||
# can return multiple potential results while evaluating a Python object, but
|
||||
# some branches might not be evaluated, which results in partial inference. In
|
||||
# that case, it might be useful to still emit no-member and other checks for
|
||||
# the rest of the inferred objects.
|
||||
ignore-on-opaque-inference=yes
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=flask setproctitle usb1 flask.ext.socketio smbus2 usb1.*
|
||||
|
||||
# Show a hint with possible names when a member name was not found. The aspect
|
||||
# of finding the hint is based on edit distance.
|
||||
missing-member-hint=yes
|
||||
|
||||
# The minimum edit distance a name should have in order to be considered a
|
||||
# similar match for a missing member name.
|
||||
missing-member-hint-distance=1
|
||||
|
||||
# The total number of similar names that should be taken in consideration when
|
||||
# showing a hint for a missing member.
|
||||
missing-member-max-choices=1
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,
|
||||
_cb
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
||||
# not used).
|
||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore
|
||||
ignored-argument-names=_.*|^ignored_|^unused_
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,past.builtins,future.builtins
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
expected-line-ending-format=
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=100
|
||||
|
||||
# Maximum number of lines in a module
|
||||
max-module-lines=1000
|
||||
|
||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||
# `empty-line` allows space-only lines.
|
||||
no-space-check=trailing-comma,
|
||||
dict-separator
|
||||
|
||||
# Allow the body of a class to be on the same line as the declaration if body
|
||||
# contains single statement.
|
||||
single-line-class-stmt=no
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Naming style matching correct argument names
|
||||
argument-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct argument names. Overrides argument-
|
||||
# naming-style
|
||||
#argument-rgx=
|
||||
|
||||
# Naming style matching correct attribute names
|
||||
attr-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct attribute names. Overrides attr-naming-
|
||||
# style
|
||||
#attr-rgx=
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma
|
||||
bad-names=foo,
|
||||
bar,
|
||||
baz,
|
||||
toto,
|
||||
tutu,
|
||||
tata
|
||||
|
||||
# Naming style matching correct class attribute names
|
||||
class-attribute-naming-style=any
|
||||
|
||||
# Regular expression matching correct class attribute names. Overrides class-
|
||||
# attribute-naming-style
|
||||
#class-attribute-rgx=
|
||||
|
||||
# Naming style matching correct class names
|
||||
class-naming-style=PascalCase
|
||||
|
||||
# Regular expression matching correct class names. Overrides class-naming-style
|
||||
#class-rgx=
|
||||
|
||||
# Naming style matching correct constant names
|
||||
const-naming-style=UPPER_CASE
|
||||
|
||||
# Regular expression matching correct constant names. Overrides const-naming-
|
||||
# style
|
||||
#const-rgx=
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
# Naming style matching correct function names
|
||||
function-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct function names. Overrides function-
|
||||
# naming-style
|
||||
#function-rgx=
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
good-names=i,
|
||||
j,
|
||||
k,
|
||||
ex,
|
||||
Run,
|
||||
_
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name
|
||||
include-naming-hint=no
|
||||
|
||||
# Naming style matching correct inline iteration names
|
||||
inlinevar-naming-style=any
|
||||
|
||||
# Regular expression matching correct inline iteration names. Overrides
|
||||
# inlinevar-naming-style
|
||||
#inlinevar-rgx=
|
||||
|
||||
# Naming style matching correct method names
|
||||
method-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct method names. Overrides method-naming-
|
||||
# style
|
||||
#method-rgx=
|
||||
|
||||
# Naming style matching correct module names
|
||||
module-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct module names. Overrides module-naming-
|
||||
# style
|
||||
#module-rgx=
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Naming style matching correct variable names
|
||||
variable-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct variable names. Overrides variable-
|
||||
# naming-style
|
||||
#variable-rgx=
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method
|
||||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=7
|
||||
|
||||
# Maximum number of boolean expressions in a if statement
|
||||
max-bool-expr=5
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of locals for function / method body
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of statements in function / method body
|
||||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,
|
||||
__new__,
|
||||
setUp
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,
|
||||
_fields,
|
||||
_replace,
|
||||
_source,
|
||||
_make
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=mcs
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# Allow wildcard imports from modules that define __all__.
|
||||
allow-wildcard-with-all=no
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma
|
||||
deprecated-modules=regsub,
|
||||
TERMIOS,
|
||||
Bastion,
|
||||
rexec
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled)
|
||||
import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "Exception"
|
||||
overgeneral-exceptions=Exception
|
|
@ -1,19 +0,0 @@
|
|||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y make python python-pip locales curl git zlib1g-dev libffi-dev bzip2 libssl-dev
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY requirements.txt /tmp/
|
||||
RUN pip install -r /tmp/requirements.txt
|
||||
COPY . /panda
|
|
@ -1,8 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
RESULT=$(python3 -m flake8 --select=F $(find ../../ -type f | grep -v "/boardesp/" | grep -v "/cppcheck/" | grep "\.py$"))
|
||||
if [[ $RESULT ]]; then
|
||||
echo "Pyflakes found errors in the code. Please fix and try again"
|
||||
echo "$RESULT"
|
||||
exit 1
|
||||
fi
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
python3 -m pylint --disable=R,C,W $(find ../../ -type f | grep -v "/boardesp/" | grep -v "/cppcheck/" | grep "\.py$")
|
||||
|
||||
exit_status=$?
|
||||
(( res = exit_status & 3 ))
|
||||
|
||||
if [[ $res != 0 ]]; then
|
||||
echo "Pylint found errors in the code. Please fix and try again"
|
||||
exit 1
|
||||
fi
|
|
@ -1,19 +0,0 @@
|
|||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y clang make python python-pip git curl locales zlib1g-dev libffi-dev bzip2 libssl-dev libbz2-dev libusb-1.0-0
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY requirements.txt /tmp/
|
||||
RUN pip install -r /tmp/requirements.txt
|
||||
COPY . /panda
|
|
@ -1,50 +0,0 @@
|
|||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
autoconf \
|
||||
clang \
|
||||
curl \
|
||||
git \
|
||||
libtool \
|
||||
libssl-dev \
|
||||
libusb-1.0-0 \
|
||||
libzmq3-dev \
|
||||
locales \
|
||||
make \
|
||||
python \
|
||||
python-pip \
|
||||
wget \
|
||||
zlib1g-dev
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY requirements.txt /tmp/
|
||||
RUN pip install -r /tmp/requirements.txt
|
||||
|
||||
WORKDIR /openpilot
|
||||
RUN git clone https://github.com/commaai/opendbc.git || true
|
||||
WORKDIR /openpilot/opendbc
|
||||
RUN git pull && git checkout 7f3b1774dd248d4ebad91cc9de0fb1c561fab54b
|
||||
WORKDIR /openpilot
|
||||
RUN git clone https://github.com/commaai/cereal.git
|
||||
WORKDIR /openpilot/cereal
|
||||
RUN git pull && git checkout e370f79522ff7fc0b16f33f4fef420be48061206
|
||||
RUN /openpilot/cereal/install_capnp.sh
|
||||
|
||||
RUN pip install -r /openpilot/opendbc/requirements.txt
|
||||
|
||||
WORKDIR /openpilot
|
||||
RUN cp /openpilot/opendbc/SConstruct /openpilot
|
||||
COPY . /openpilot/panda
|
||||
|
||||
RUN scons -c && scons -j$(nproc)
|
|
@ -2,7 +2,8 @@ import abc
|
|||
import struct
|
||||
import unittest
|
||||
import numpy as np
|
||||
from opendbc.can.packer import CANPacker # pylint: disable=import-error
|
||||
from typing import Optional, List, Dict
|
||||
from opendbc.can.packer import CANPacker # pylint: disable=import-error
|
||||
from panda.tests.safety import libpandasafety_py
|
||||
|
||||
MAX_WRONG_COUNTERS = 5
|
||||
|
@ -32,8 +33,10 @@ def make_msg(bus, addr, length=8):
|
|||
return package_can_msg([addr, 0, b'\x00'*length, bus])
|
||||
|
||||
class CANPackerPanda(CANPacker):
|
||||
def make_can_msg_panda(self, name_or_addr, bus, values, counter=-1):
|
||||
def make_can_msg_panda(self, name_or_addr, bus, values, counter=-1, fix_checksum=None):
|
||||
msg = self.make_can_msg(name_or_addr, bus, values, counter=-1)
|
||||
if fix_checksum is not None:
|
||||
msg = fix_checksum(msg)
|
||||
return package_can_msg(msg)
|
||||
|
||||
class PandaSafetyTestBase(unittest.TestCase):
|
||||
|
@ -245,13 +248,13 @@ class TorqueSteeringSafetyTest(PandaSafetyTestBase):
|
|||
|
||||
|
||||
class PandaSafetyTest(PandaSafetyTestBase):
|
||||
TX_MSGS = None
|
||||
STANDSTILL_THRESHOLD = None
|
||||
TX_MSGS: Optional[List[List[int]]] = None
|
||||
STANDSTILL_THRESHOLD: Optional[float] = None
|
||||
GAS_PRESSED_THRESHOLD = 0
|
||||
RELAY_MALFUNCTION_ADDR = None
|
||||
RELAY_MALFUNCTION_BUS = None
|
||||
FWD_BLACKLISTED_ADDRS = {} # {bus: [addr]}
|
||||
FWD_BUS_LOOKUP = {}
|
||||
RELAY_MALFUNCTION_ADDR: Optional[int] = None
|
||||
RELAY_MALFUNCTION_BUS: Optional[int] = None
|
||||
FWD_BLACKLISTED_ADDRS: Dict[int, List[int]] = {} # {bus: [addr]}
|
||||
FWD_BUS_LOOKUP: Dict[int, int] = {}
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
@ -396,7 +399,7 @@ class PandaSafetyTest(PandaSafetyTestBase):
|
|||
|
||||
def test_sample_speed(self):
|
||||
self.assertFalse(self.safety.get_vehicle_moving())
|
||||
|
||||
|
||||
# not moving
|
||||
self.safety.safety_rx_hook(self._speed_msg(0))
|
||||
self.assertFalse(self.safety.get_vehicle_moving())
|
||||
|
|
|
@ -50,6 +50,7 @@ int get_torque_driver_min(void);
|
|||
int get_torque_driver_max(void);
|
||||
void set_desired_torque_last(int t);
|
||||
void set_rt_torque_last(int t);
|
||||
void set_desired_angle_last(int t);
|
||||
|
||||
bool get_cruise_engaged_prev(void);
|
||||
bool get_vehicle_moving(void);
|
||||
|
@ -66,15 +67,10 @@ void init_tests(void);
|
|||
void init_tests_honda(void);
|
||||
void set_honda_fwd_brake(bool);
|
||||
void set_honda_alt_brake_msg(bool);
|
||||
void set_honda_bosch_long(bool c);
|
||||
int get_honda_hw(void);
|
||||
|
||||
void init_tests_chrysler(void);
|
||||
|
||||
bool get_subaru_global(void);
|
||||
|
||||
void init_tests_nissan(void);
|
||||
void set_nissan_desired_angle_last(int t);
|
||||
|
||||
""")
|
||||
|
||||
libpandasafety = ffi.dlopen(libpandasafety_fn)
|
||||
|
|
|
@ -71,6 +71,7 @@ void fault_recovered(uint32_t fault) {
|
|||
#define GET_BYTE(msg, b) (((int)(b) > 3) ? (((msg)->RDHR >> (8U * ((unsigned int)(b) % 4U))) & 0XFFU) : (((msg)->RDLR >> (8U * (unsigned int)(b))) & 0xFFU))
|
||||
#define GET_BYTES_04(msg) ((msg)->RDLR)
|
||||
#define GET_BYTES_48(msg) ((msg)->RDHR)
|
||||
#define GET_FLAG(value, mask) (((__typeof__(mask))param & mask) == mask)
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
|
@ -179,10 +180,18 @@ void set_desired_torque_last(int t){
|
|||
desired_torque_last = t;
|
||||
}
|
||||
|
||||
void set_desired_angle_last(int t){
|
||||
desired_angle_last = t;
|
||||
}
|
||||
|
||||
void set_honda_alt_brake_msg(bool c){
|
||||
honda_alt_brake_msg = c;
|
||||
}
|
||||
|
||||
void set_honda_bosch_long(bool c){
|
||||
honda_bosch_long = c;
|
||||
}
|
||||
|
||||
int get_honda_hw(void) {
|
||||
return honda_hw;
|
||||
}
|
||||
|
@ -191,46 +200,19 @@ void set_honda_fwd_brake(bool c){
|
|||
honda_fwd_brake = c;
|
||||
}
|
||||
|
||||
void set_nissan_desired_angle_last(int t){
|
||||
nissan_desired_angle_last = t;
|
||||
}
|
||||
|
||||
void init_tests(void){
|
||||
// get HW_TYPE from env variable set in test.sh
|
||||
hw_type = atoi(getenv("HW_TYPE"));
|
||||
safety_mode_cnt = 2U; // avoid ignoring relay_malfunction logic
|
||||
gas_pressed_prev = false;
|
||||
brake_pressed_prev = false;
|
||||
desired_torque_last = 0;
|
||||
rt_torque_last = 0;
|
||||
ts_last = 0;
|
||||
torque_driver.min = 0;
|
||||
torque_driver.max = 0;
|
||||
torque_meas.min = 0;
|
||||
torque_meas.max = 0;
|
||||
vehicle_moving = false;
|
||||
unsafe_mode = 0;
|
||||
set_timer(0);
|
||||
}
|
||||
|
||||
void init_tests_chrysler(void){
|
||||
init_tests();
|
||||
chrysler_speed = 0;
|
||||
}
|
||||
|
||||
void init_tests_honda(void){
|
||||
init_tests();
|
||||
honda_fwd_brake = false;
|
||||
}
|
||||
|
||||
void init_tests_nissan(void){
|
||||
init_tests();
|
||||
nissan_angle_meas.min = 0;
|
||||
nissan_angle_meas.max = 0;
|
||||
nissan_desired_angle_last = 0;
|
||||
set_timer(0);
|
||||
}
|
||||
|
||||
void set_gmlan_digital_output(int to_set){
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class TestChryslerSafety(common.PandaSafetyTest, common.TorqueSteeringSafetyTest
|
|||
self.packer = CANPackerPanda("chrysler_pacifica_2017_hybrid")
|
||||
self.safety = libpandasafety_py.libpandasafety
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_CHRYSLER, 0)
|
||||
self.safety.init_tests_chrysler()
|
||||
self.safety.init_tests()
|
||||
|
||||
def _button_msg(self, cancel):
|
||||
values = {"ACC_CANCEL": cancel}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
from typing import Dict, List
|
||||
import numpy as np
|
||||
from panda import Panda
|
||||
from panda.tests.safety import libpandasafety_py
|
||||
|
@ -27,8 +28,8 @@ class TestGmSafety(common.PandaSafetyTest):
|
|||
STANDSTILL_THRESHOLD = 0
|
||||
RELAY_MALFUNCTION_ADDR = 384
|
||||
RELAY_MALFUNCTION_BUS = 0
|
||||
FWD_BLACKLISTED_ADDRS = {}
|
||||
FWD_BUS_LOOKUP = {}
|
||||
FWD_BLACKLISTED_ADDRS: Dict[int, List[int]] = {}
|
||||
FWD_BUS_LOOKUP: Dict[int, int] = {}
|
||||
|
||||
def setUp(self):
|
||||
self.packer = CANPackerPanda("gm_global_a_powertrain")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
from typing import Optional
|
||||
import numpy as np
|
||||
from panda import Panda
|
||||
from panda.tests.safety import libpandasafety_py
|
||||
|
@ -7,8 +8,6 @@ import panda.tests.safety.common as common
|
|||
from panda.tests.safety.common import CANPackerPanda, make_msg, \
|
||||
MAX_WRONG_COUNTERS, UNSAFE_MODE
|
||||
|
||||
MAX_BRAKE = 255
|
||||
|
||||
class Btn:
|
||||
CANCEL = 2
|
||||
SET = 3
|
||||
|
@ -20,11 +19,14 @@ HONDA_BH_HW = 2
|
|||
|
||||
|
||||
class TestHondaSafety(common.PandaSafetyTest):
|
||||
MAX_BRAKE: float = 255
|
||||
PT_BUS: Optional[int] = None # must be set when inherited
|
||||
STEER_BUS: Optional[int] = None # must be set when inherited
|
||||
|
||||
cnt_speed = 0
|
||||
cnt_gas = 0
|
||||
cnt_button = 0
|
||||
|
||||
PT_BUS = 0
|
||||
cnt_brake = 0
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
@ -58,15 +60,13 @@ class TestHondaSafety(common.PandaSafetyTest):
|
|||
self.__class__.cnt_gas += 1
|
||||
return self.packer.make_can_msg_panda("POWERTRAIN_DATA", self.PT_BUS, values)
|
||||
|
||||
def _send_brake_msg(self, brake):
|
||||
values = {}
|
||||
if self.safety.get_honda_hw() == HONDA_N_HW:
|
||||
values = {"COMPUTER_BRAKE": brake}
|
||||
return self.packer.make_can_msg_panda("BRAKE_COMMAND", 0, values)
|
||||
|
||||
def _send_steer_msg(self, steer):
|
||||
values = {"STEER_TORQUE": steer}
|
||||
return self.packer.make_can_msg_panda("STEERING_CONTROL", 0, values)
|
||||
return self.packer.make_can_msg_panda("STEERING_CONTROL", self.STEER_BUS, values)
|
||||
|
||||
def _send_brake_msg(self, brake):
|
||||
# must be implemented when inherited
|
||||
raise NotImplementedError()
|
||||
|
||||
def test_resume_button(self):
|
||||
self.safety.set_controls_allowed(0)
|
||||
|
@ -157,13 +157,14 @@ class TestHondaSafety(common.PandaSafetyTest):
|
|||
hw = self.safety.get_honda_hw()
|
||||
if hw == HONDA_N_HW:
|
||||
self.safety.set_honda_fwd_brake(False)
|
||||
self.assertEqual(allow_ctrl, self._tx(self._send_brake_msg(MAX_BRAKE)))
|
||||
self.assertEqual(allow_ctrl, self._tx(self._send_brake_msg(self.MAX_BRAKE)))
|
||||
self.assertEqual(allow_ctrl, self._tx(self._send_steer_msg(0x1000)))
|
||||
|
||||
# reset status
|
||||
self.safety.set_controls_allowed(0)
|
||||
self.safety.set_unsafe_mode(UNSAFE_MODE.DEFAULT)
|
||||
self._tx(self._send_brake_msg(0))
|
||||
if hw == HONDA_N_HW:
|
||||
self._tx(self._send_brake_msg(0))
|
||||
self._tx(self._send_steer_msg(0))
|
||||
if pedal == 'brake':
|
||||
self._rx(self._speed_msg(0))
|
||||
|
@ -181,6 +182,9 @@ class TestHondaNidecSafety(TestHondaSafety, common.InterceptorSafetyTest):
|
|||
FWD_BLACKLISTED_ADDRS = {2: [0xE4, 0x194, 0x33D, 0x30C]}
|
||||
FWD_BUS_LOOKUP = {0: 2, 2: 0}
|
||||
|
||||
PT_BUS = 0
|
||||
STEER_BUS = 0
|
||||
|
||||
INTERCEPTOR_THRESHOLD = 344
|
||||
|
||||
def setUp(self):
|
||||
|
@ -197,6 +201,10 @@ class TestHondaNidecSafety(TestHondaSafety, common.InterceptorSafetyTest):
|
|||
((gas2 & 0xff) << 24) | ((gas2 & 0xff00) << 8)
|
||||
return to_send
|
||||
|
||||
def _send_brake_msg(self, brake):
|
||||
values = {"COMPUTER_BRAKE": brake}
|
||||
return self.packer.make_can_msg_panda("BRAKE_COMMAND", 0, values)
|
||||
|
||||
def test_fwd_hook(self):
|
||||
# normal operation, not forwarding AEB
|
||||
self.FWD_BLACKLISTED_ADDRS[2].append(0x1FA)
|
||||
|
@ -212,13 +220,13 @@ class TestHondaNidecSafety(TestHondaSafety, common.InterceptorSafetyTest):
|
|||
def test_brake_safety_check(self):
|
||||
for fwd_brake in [False, True]:
|
||||
self.safety.set_honda_fwd_brake(fwd_brake)
|
||||
for brake in np.arange(0, MAX_BRAKE + 10, 1):
|
||||
for brake in np.arange(0, self.MAX_BRAKE + 10, 1):
|
||||
for controls_allowed in [True, False]:
|
||||
self.safety.set_controls_allowed(controls_allowed)
|
||||
if fwd_brake:
|
||||
send = False # block openpilot brake msg when fwd'ing stock msg
|
||||
elif controls_allowed:
|
||||
send = MAX_BRAKE >= brake >= 0
|
||||
send = self.MAX_BRAKE >= brake >= 0
|
||||
else:
|
||||
send = brake == 0
|
||||
self.assertEqual(send, self._tx(self._send_brake_msg(brake)))
|
||||
|
@ -234,7 +242,7 @@ class TestHondaNidecSafety(TestHondaSafety, common.InterceptorSafetyTest):
|
|||
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.safety.set_honda_fwd_brake(False)
|
||||
self.assertEqual(allow_ctrl, self._tx(self._send_brake_msg(MAX_BRAKE)))
|
||||
self.assertEqual(allow_ctrl, self._tx(self._send_brake_msg(self.MAX_BRAKE)))
|
||||
self.assertEqual(allow_ctrl, self._tx(self._interceptor_msg(self.INTERCEPTOR_THRESHOLD, 0x200)))
|
||||
self.assertEqual(allow_ctrl, self._tx(self._send_steer_msg(0x1000)))
|
||||
|
||||
|
@ -247,35 +255,35 @@ class TestHondaNidecSafety(TestHondaSafety, common.InterceptorSafetyTest):
|
|||
self.safety.set_gas_interceptor_detected(False)
|
||||
|
||||
|
||||
class TestHondaBoschHarnessSafety(TestHondaSafety):
|
||||
TX_MSGS = [[0xE4, 0], [0xE5, 0], [0x296, 1], [0x33D, 0]] # Bosch Harness
|
||||
class TestHondaBoschSafety(TestHondaSafety):
|
||||
STANDSTILL_THRESHOLD = 0
|
||||
RELAY_MALFUNCTION_ADDR = 0xE4
|
||||
RELAY_MALFUNCTION_BUS = 0
|
||||
FWD_BLACKLISTED_ADDRS = {2: [0xE4, 0xE5, 0x33D]}
|
||||
FWD_BUS_LOOKUP = {0: 2, 2: 0}
|
||||
|
||||
PT_BUS = 1
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
if cls.__name__ == "TestHondaBoschSafety":
|
||||
cls.packer = None
|
||||
cls.safety = None
|
||||
raise unittest.SkipTest
|
||||
|
||||
def setUp(self):
|
||||
self.packer = CANPackerPanda("honda_accord_s2t_2018_can_generated")
|
||||
self.safety = libpandasafety_py.libpandasafety
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_HONDA_BOSCH_HARNESS, 0)
|
||||
self.safety.init_tests_honda()
|
||||
|
||||
def _alt_brake_msg(self, brake):
|
||||
to_send = make_msg(0, 0x1BE)
|
||||
to_send[0].RDLR = 0x10 if brake else 0
|
||||
return to_send
|
||||
values = {"BRAKE_PRESSED": brake, "COUNTER": self.cnt_brake % 4}
|
||||
self.__class__.cnt_brake += 1
|
||||
return self.packer.make_can_msg_panda("BRAKE_MODULE", self.PT_BUS, values)
|
||||
|
||||
def test_spam_cancel_safety_check(self):
|
||||
self.safety.set_controls_allowed(0)
|
||||
self.assertTrue(self._tx(self._button_msg(Btn.CANCEL)))
|
||||
self.assertFalse(self._tx(self._button_msg(Btn.RESUME)))
|
||||
self.assertFalse(self._tx(self._button_msg(Btn.SET)))
|
||||
# do not block resume if we are engaged already
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.assertTrue(self._tx(self._button_msg(Btn.RESUME)))
|
||||
# TODO: add back in once alternative brake checksum/counter validation is added
|
||||
# def test_alt_brake_rx_hook(self):
|
||||
# self.safety.set_honda_alt_brake_msg(1)
|
||||
# self.safety.set_controls_allowed(1)
|
||||
# to_push = self._alt_brake_msg(0)
|
||||
# self.assertTrue(self._rx(to_push))
|
||||
# to_push[0].RDLR = to_push[0].RDLR & 0xFFF0FFFF # invalidate checksum
|
||||
# self.assertFalse(self._rx(to_push))
|
||||
# self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
def test_alt_disengage_on_brake(self):
|
||||
self.safety.set_honda_alt_brake_msg(1)
|
||||
|
@ -289,25 +297,108 @@ class TestHondaBoschHarnessSafety(TestHondaSafety):
|
|||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
|
||||
class TestHondaBoschHarnessSafety(TestHondaBoschSafety):
|
||||
TX_MSGS = [[0xE4, 0], [0xE5, 0], [0x296, 1], [0x33D, 0]] # Bosch Harness
|
||||
RELAY_MALFUNCTION_BUS = 0
|
||||
FWD_BLACKLISTED_ADDRS = {2: [0xE4, 0xE5, 0x33D]}
|
||||
FWD_BUS_LOOKUP = {0: 2, 2: 0}
|
||||
|
||||
PT_BUS = 1
|
||||
STEER_BUS = 0
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_HONDA_BOSCH_HARNESS, 0)
|
||||
self.safety.init_tests_honda()
|
||||
|
||||
def test_spam_cancel_safety_check(self):
|
||||
self.safety.set_controls_allowed(0)
|
||||
self.assertTrue(self._tx(self._button_msg(Btn.CANCEL)))
|
||||
self.assertFalse(self._tx(self._button_msg(Btn.RESUME)))
|
||||
self.assertFalse(self._tx(self._button_msg(Btn.SET)))
|
||||
# do not block resume if we are engaged already
|
||||
self.safety.set_controls_allowed(1)
|
||||
self.assertTrue(self._tx(self._button_msg(Btn.RESUME)))
|
||||
|
||||
|
||||
class TestHondaBoschGiraffeSafety(TestHondaBoschHarnessSafety):
|
||||
TX_MSGS = [[0xE4, 2], [0xE5, 2], [0x296, 0], [0x33D, 2]] # Bosch Giraffe
|
||||
STANDSTILL_THRESHOLD = 0
|
||||
RELAY_MALFUNCTION_ADDR = 0xE4
|
||||
RELAY_MALFUNCTION_BUS = 2
|
||||
FWD_BLACKLISTED_ADDRS = {1: [0xE4, 0xE5, 0x33D]}
|
||||
FWD_BUS_LOOKUP = {1: 2, 2: 1}
|
||||
|
||||
PT_BUS = 0
|
||||
STEER_BUS = 2
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.safety = libpandasafety_py.libpandasafety
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_HONDA_BOSCH_GIRAFFE, 0)
|
||||
self.safety.init_tests_honda()
|
||||
|
||||
def _send_steer_msg(self, steer):
|
||||
values = {"STEER_TORQUE": steer}
|
||||
return self.packer.make_can_msg_panda("STEERING_CONTROL", 2, values)
|
||||
|
||||
class TestHondaBoschLongSafety(TestHondaBoschSafety):
|
||||
NO_GAS = -30000
|
||||
MAX_GAS = 2000
|
||||
MAX_BRAKE = -3.5
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
if cls.__name__ == "TestHondaBoschLongSafety":
|
||||
cls.packer = None
|
||||
cls.safety = None
|
||||
raise unittest.SkipTest
|
||||
|
||||
def _send_gas_brake_msg(self, gas, accel):
|
||||
values = {
|
||||
"GAS_COMMAND": gas,
|
||||
"ACCEL_COMMAND": accel,
|
||||
"BRAKE_REQUEST": accel < 0,
|
||||
}
|
||||
return self.packer.make_can_msg_panda("ACC_CONTROL", self.PT_BUS, values)
|
||||
|
||||
def test_gas_safety_check(self):
|
||||
for controls_allowed in [True, False]:
|
||||
for gas in np.arange(self.NO_GAS, self.MAX_GAS + 2000, 100):
|
||||
accel = 0 if gas < 0 else gas / 1000
|
||||
self.safety.set_controls_allowed(controls_allowed)
|
||||
send = gas <= self.MAX_GAS if controls_allowed else gas == self.NO_GAS
|
||||
self.assertEqual(send, self.safety.safety_tx_hook(self._send_gas_brake_msg(gas, accel)), gas)
|
||||
|
||||
def test_brake_safety_check(self):
|
||||
for controls_allowed in [True, False]:
|
||||
for accel in np.arange(0, self.MAX_BRAKE - 1, -0.1):
|
||||
self.safety.set_controls_allowed(controls_allowed)
|
||||
send = self.MAX_BRAKE <= accel <= 0 if controls_allowed else accel == 0
|
||||
self.assertEqual(send, self._tx(self._send_gas_brake_msg(self.NO_GAS, accel)), (controls_allowed, accel))
|
||||
|
||||
class TestHondaBoschLongHarnessSafety(TestHondaBoschLongSafety):
|
||||
TX_MSGS = [[0xE4, 1], [0x1DF, 1], [0x1EF, 1], [0x1FA, 1], [0x30C, 1], [0x33D, 1], [0x39F, 1], [0x18DAB0F1, 1]] # Bosch Harness w/ gas and brakes
|
||||
RELAY_MALFUNCTION_BUS = 0
|
||||
FWD_BLACKLISTED_ADDRS = {2: [0xE4, 0xE5, 0x33D]}
|
||||
FWD_BUS_LOOKUP = {0: 2, 2: 0}
|
||||
|
||||
PT_BUS = 1
|
||||
STEER_BUS = 1
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_HONDA_BOSCH_HARNESS, 2)
|
||||
self.safety.init_tests_honda()
|
||||
|
||||
|
||||
class TestHondaBoschLongGiraffeSafety(TestHondaBoschLongSafety):
|
||||
TX_MSGS = [[0xE4, 0], [0x1DF, 0], [0x1EF, 0], [0x1FA, 0], [0x30C, 0], [0x33D, 0], [0x39F, 0], [0x18DAB0F1, 0]] # Bosch Giraffe w/ gas and brakes
|
||||
RELAY_MALFUNCTION_BUS = 2
|
||||
FWD_BLACKLISTED_ADDRS = {1: [0xE4, 0xE5, 0x33D]}
|
||||
FWD_BUS_LOOKUP = {1: 2, 2: 1}
|
||||
|
||||
PT_BUS = 0
|
||||
STEER_BUS = 0
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_HONDA_BOSCH_GIRAFFE, 2)
|
||||
self.safety.init_tests_honda()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -16,6 +16,22 @@ RT_INTERVAL = 250000
|
|||
DRIVER_TORQUE_ALLOWANCE = 50
|
||||
DRIVER_TORQUE_FACTOR = 2
|
||||
|
||||
# 4 bit checkusm used in some hyundai messages
|
||||
# lives outside the can packer because we never send this msg
|
||||
def checksum(msg):
|
||||
addr, t, dat, bus = msg
|
||||
|
||||
chksum = 0
|
||||
for i, b in enumerate(dat):
|
||||
if addr in [608, 1057] and i == 7:
|
||||
b &= 0x0F if addr == 1057 else 0xF0
|
||||
elif addr == 916 and i == 6:
|
||||
b &= 0xF0
|
||||
chksum += sum(divmod(b, 16))
|
||||
chksum = (16 - chksum) % 16
|
||||
ret = bytearray(dat)
|
||||
ret[6 if addr == 916 else 7] |= chksum << (4 if addr == 1057 else 0)
|
||||
return addr, t, ret, bus
|
||||
|
||||
class TestHyundaiSafety(common.PandaSafetyTest):
|
||||
TX_MSGS = [[832, 0], [1265, 0], [1157, 0]]
|
||||
|
@ -43,24 +59,25 @@ class TestHyundaiSafety(common.PandaSafetyTest):
|
|||
def _gas_msg(self, val):
|
||||
values = {"CF_Ems_AclAct": val, "AliveCounter": self.cnt_gas % 4}
|
||||
self.__class__.cnt_gas += 1
|
||||
return self.packer.make_can_msg_panda("EMS16", 0, values)
|
||||
return self.packer.make_can_msg_panda("EMS16", 0, values, fix_checksum=checksum)
|
||||
|
||||
def _brake_msg(self, brake):
|
||||
values = {"DriverBraking": brake, "AliveCounterTCS": self.cnt_brake % 8}
|
||||
self.__class__.cnt_brake += 1
|
||||
return self.packer.make_can_msg_panda("TCS13", 0, values)
|
||||
return self.packer.make_can_msg_panda("TCS13", 0, values, fix_checksum=checksum)
|
||||
|
||||
def _speed_msg(self, speed):
|
||||
# panda safety doesn't scale, so undo the scaling
|
||||
values = {"WHL_SPD_%s"%s: speed*0.03125 for s in ["FL", "FR", "RL", "RR"]}
|
||||
values["WHL_SPD_AliveCounter_LSB"] = self.cnt_speed % 4
|
||||
values["WHL_SPD_AliveCounter_LSB"] = (self.cnt_speed % 16) & 0x3
|
||||
values["WHL_SPD_AliveCounter_MSB"] = (self.cnt_speed % 16) >> 2
|
||||
self.__class__.cnt_speed += 1
|
||||
return self.packer.make_can_msg_panda("WHL_SPD11", 0, values)
|
||||
|
||||
def _pcm_status_msg(self, enabled):
|
||||
values = {"ACCMode": enabled, "CR_VSM_Alive": self.cnt_cruise % 16}
|
||||
self.__class__.cnt_cruise += 1
|
||||
return self.packer.make_can_msg_panda("SCC12", 0, values)
|
||||
return self.packer.make_can_msg_panda("SCC12", 0, values, fix_checksum=checksum)
|
||||
|
||||
def _set_prev_torque(self, t):
|
||||
self.safety.set_desired_torque_last(t)
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
from panda import Panda
|
||||
from panda.tests.safety import libpandasafety_py
|
||||
import panda.tests.safety.common as common
|
||||
from panda.tests.safety.common import CANPackerPanda
|
||||
|
||||
MAX_RATE_UP = 10
|
||||
MAX_RATE_DOWN = 25
|
||||
MAX_STEER = 2047
|
||||
|
||||
MAX_RT_DELTA = 940
|
||||
RT_INTERVAL = 250000
|
||||
|
||||
DRIVER_TORQUE_ALLOWANCE = 15
|
||||
DRIVER_TORQUE_FACTOR = 1
|
||||
|
||||
|
||||
class TestMazdaSafety(common.PandaSafetyTest):
|
||||
|
||||
TX_MSGS = [[0x243, 0], [0x09d, 0]]
|
||||
STANDSTILL_THRESHOLD = .1
|
||||
RELAY_MALFUNCTION_ADDR = 0x243
|
||||
RELAY_MALFUNCTION_BUS = 0
|
||||
FWD_BLACKLISTED_ADDRS = {2: [0x243]}
|
||||
FWD_BUS_LOOKUP = {0: 2, 2: 0}
|
||||
LKAS_ENABLE_SPEED = 52
|
||||
LKAS_DISABLE_SPEED = 45
|
||||
|
||||
def setUp(self):
|
||||
self.packer = CANPackerPanda("mazda_cx5_gt_2017")
|
||||
self.safety = libpandasafety_py.libpandasafety
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_MAZDA, 0)
|
||||
self.safety.init_tests()
|
||||
|
||||
def _torque_meas_msg(self, torque):
|
||||
values = {"STEER_TORQUE_MOTOR": torque}
|
||||
return self.packer.make_can_msg_panda("STEER_TORQUE", 0, values)
|
||||
|
||||
# def _torque_driver_msg(self, torque):
|
||||
# values = {"STEER_TORQUE_DRIVER": torque}
|
||||
# return self.packer.make_can_msg_panda("STEER_TORQUE", 0, values)
|
||||
|
||||
def _torque_msg(self, torque):
|
||||
values = {"LKAS_REQUEST": torque}
|
||||
return self.packer.make_can_msg_panda("CAM_LKAS", 0, values)
|
||||
|
||||
def _speed_msg(self, s):
|
||||
values = {"SPEED": s}
|
||||
return self.packer.make_can_msg_panda("ENGINE_DATA", 0, values)
|
||||
|
||||
def _brake_msg(self, pressed):
|
||||
values = {"BRAKE_ON": pressed}
|
||||
return self.packer.make_can_msg_panda("PEDALS", 0, values)
|
||||
|
||||
def _gas_msg(self, pressed):
|
||||
values = {"PEDAL_GAS": pressed}
|
||||
return self.packer.make_can_msg_panda("ENGINE_DATA", 0, values)
|
||||
|
||||
def _pcm_status_msg(self, cruise_on):
|
||||
values = {"CRZ_ACTIVE": cruise_on}
|
||||
return self.packer.make_can_msg_panda("CRZ_CTRL", 0, values)
|
||||
|
||||
def test_enable_control_allowed_from_cruise(self):
|
||||
self._rx(self._pcm_status_msg(False))
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
self._rx(self._speed_msg(self.LKAS_DISABLE_SPEED - 1))
|
||||
self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1))
|
||||
self._rx(self._pcm_status_msg(True))
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
self._rx(self._pcm_status_msg(False))
|
||||
|
||||
self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED + 1))
|
||||
self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1))
|
||||
self._rx(self._pcm_status_msg(True))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED + 1))
|
||||
self._rx(self._pcm_status_msg(True))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
# Enabled going down
|
||||
self._rx(self._speed_msg(self.LKAS_DISABLE_SPEED - 1))
|
||||
self.assertTrue(self.safety.get_controls_allowed())
|
||||
|
||||
self._rx(self._pcm_status_msg(False))
|
||||
|
||||
# Disabled going up
|
||||
self._rx(self._speed_msg(self.LKAS_DISABLE_SPEED + 1))
|
||||
self._rx(self._pcm_status_msg(True))
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
|
||||
def test_cruise_engaged_prev(self):
|
||||
self._rx(self._pcm_status_msg(False))
|
||||
self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED - 1))
|
||||
self._rx(self._pcm_status_msg(True))
|
||||
self.assertFalse(self.safety.get_cruise_engaged_prev())
|
||||
|
||||
self._rx(self._speed_msg(self.LKAS_ENABLE_SPEED + 1))
|
||||
|
||||
for engaged in [True, False]:
|
||||
self._rx(self._pcm_status_msg(engaged))
|
||||
self.assertEqual(engaged, self.safety.get_cruise_engaged_prev())
|
||||
self._rx(self._pcm_status_msg(not engaged))
|
||||
self.assertEqual(not engaged, self.safety.get_cruise_engaged_prev())
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -29,7 +29,7 @@ class TestNissanSafety(common.PandaSafetyTest):
|
|||
self.packer = CANPackerPanda("nissan_x_trail_2017")
|
||||
self.safety = libpandasafety_py.libpandasafety
|
||||
self.safety.set_safety_hooks(Panda.SAFETY_NISSAN, 0)
|
||||
self.safety.init_tests_nissan()
|
||||
self.safety.init_tests()
|
||||
|
||||
def _angle_meas_msg(self, angle):
|
||||
values = {"STEER_ANGLE": angle}
|
||||
|
@ -37,7 +37,7 @@ class TestNissanSafety(common.PandaSafetyTest):
|
|||
|
||||
def _set_prev_angle(self, t):
|
||||
t = int(t * -100)
|
||||
self.safety.set_nissan_desired_angle_last(t)
|
||||
self.safety.set_desired_angle_last(t)
|
||||
|
||||
def _angle_meas_msg_array(self, angle):
|
||||
for i in range(6):
|
||||
|
|
|
@ -82,7 +82,7 @@ class TestVolkswagenPqSafety(common.PandaSafetyTest):
|
|||
|
||||
# Driver steering input torque
|
||||
def _lenkhilfe_3_msg(self, torque):
|
||||
to_send = make_msg(0, MSG_LENKHILFE_3)
|
||||
to_send = make_msg(0, MSG_LENKHILFE_3, 6)
|
||||
t = abs(torque)
|
||||
to_send[0].RDLR = ((t & 0x3FF) << 16)
|
||||
if torque < 0:
|
||||
|
@ -94,7 +94,7 @@ class TestVolkswagenPqSafety(common.PandaSafetyTest):
|
|||
|
||||
# openpilot steering output torque
|
||||
def _hca_1_msg(self, torque):
|
||||
to_send = make_msg(0, MSG_HCA_1)
|
||||
to_send = make_msg(0, MSG_HCA_1, 5)
|
||||
t = abs(torque) << 5 # DBC scale from centi-Nm to PQ network (approximated)
|
||||
to_send[0].RDLR = (t & 0x7FFF) << 16
|
||||
if torque < 0:
|
||||
|
@ -120,7 +120,7 @@ class TestVolkswagenPqSafety(common.PandaSafetyTest):
|
|||
|
||||
# Cruise control buttons
|
||||
def _gra_neu_msg(self, bit):
|
||||
to_send = make_msg(2, MSG_GRA_NEU)
|
||||
to_send = make_msg(2, MSG_GRA_NEU, 4)
|
||||
to_send[0].RDLR = 1 << bit
|
||||
to_send[0].RDLR |= volkswagen_pq_checksum(to_send[0], MSG_GRA_NEU, 8)
|
||||
return to_send
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
bzip2 \
|
||||
clang \
|
||||
curl \
|
||||
git \
|
||||
libarchive-dev \
|
||||
libbz2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libffi-dev \
|
||||
libssl-dev \
|
||||
libusb-1.0-0 \
|
||||
locales \
|
||||
make \
|
||||
python \
|
||||
python-pip \
|
||||
zlib1g-dev
|
||||
|
||||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
|
||||
RUN pyenv install 3.7.3
|
||||
RUN pyenv global 3.7.3
|
||||
RUN pyenv rehash
|
||||
|
||||
COPY requirements.txt /tmp/
|
||||
RUN pip install -r /tmp/requirements.txt
|
||||
COPY tests/safety_replay/requirements_extra.txt requirements_extra.txt
|
||||
RUN pip install -r requirements_extra.txt
|
||||
COPY tests/safety_replay/install_capnp.sh install_capnp.sh
|
||||
RUN ./install_capnp.sh
|
||||
|
||||
RUN git clone https://github.com/commaai/openpilot.git || true
|
||||
WORKDIR /openpilot
|
||||
RUN git pull && git checkout f9257fc75f68c673f9e433985fbe739f23310bb4
|
||||
RUN git submodule update --init cereal
|
||||
|
||||
COPY . /openpilot/panda
|
||||
|
||||
WORKDIR /openpilot/panda/tests/safety_replay
|
|
@ -1,10 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
apt-get install -y autoconf curl libtool
|
||||
curl -O https://capnproto.org/capnproto-c++-0.6.1.tar.gz
|
||||
tar xvf capnproto-c++-0.6.1.tar.gz
|
||||
cd capnproto-c++-0.6.1
|
||||
./configure --prefix=/usr/local CPPFLAGS=-DPIC CFLAGS=-fPIC CXXFLAGS=-fPIC LDFLAGS=-fPIC --disable-shared --enable-static
|
||||
make -j4
|
||||
make install
|
||||
|
|
@ -4,7 +4,6 @@ import os
|
|||
import sys
|
||||
from panda.tests.safety import libpandasafety_py
|
||||
from panda.tests.safety_replay.helpers import package_can_msg, init_segment
|
||||
from tools.lib.logreader import LogReader # pylint: disable=import-error
|
||||
|
||||
# replay a drive to check for safety violations
|
||||
def replay_drive(lr, safety_mode, param):
|
||||
|
@ -65,9 +64,13 @@ def replay_drive(lr, safety_mode, param):
|
|||
return tx_controls_blocked == 0 and rx_invalid == 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
from tools.lib.route import Route
|
||||
from tools.lib.logreader import MultiLogIterator # pylint: disable=import-error
|
||||
|
||||
mode = int(sys.argv[2])
|
||||
param = 0 if len(sys.argv) < 4 else int(sys.argv[3])
|
||||
lr = LogReader(sys.argv[1])
|
||||
r = Route(sys.argv[1])
|
||||
lr = MultiLogIterator(r.log_paths(), wraparound=False)
|
||||
|
||||
print("replaying drive %s with safety mode %d and param %d" % (sys.argv[1], mode, param))
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
aenum
|
||||
subprocess32
|
||||
libarchive
|
||||
pycapnp
|
||||
pycurl
|
||||
tenacity
|
||||
atomicwrites
|
|
@ -37,6 +37,6 @@ if __name__ == "__main__":
|
|||
if not replay_drive(lr, mode, int(param)):
|
||||
failed.append(route)
|
||||
|
||||
for f in failed:
|
||||
print("\n**** failed on %s ****" % f)
|
||||
for f in failed: # type: ignore
|
||||
print(f"\n**** failed on {f} ****")
|
||||
assert len(failed) == 0, "\nfailed on %d logs" % len(failed)
|
||||
|
|
|
@ -19,7 +19,7 @@ if __name__ == "__main__":
|
|||
p_in = Panda("WIFI")
|
||||
print(p_in.get_serial())
|
||||
|
||||
p_in = PandaWifiStreaming()
|
||||
p_in = PandaWifiStreaming() # type: ignore
|
||||
|
||||
#while True:
|
||||
# p_in.can_recv()
|
||||
|
|
Loading…
Reference in New Issue