mirror of
https://github.com/infiniteCable2/openpilot.git
synced 2026-08-01 14:16:47 +08:00
Merge branch 'upstream/openpilot/master' into sync-20250215
# Conflicts: # common/params.cc # opendbc_repo # panda # selfdrive/car/tests/test_models.py # selfdrive/modeld/fill_model_msg.py # selfdrive/test/process_replay/process_replay.py # selfdrive/test/process_replay/ref_commit # selfdrive/ui/qt/offroad/developer_panel.cc # selfdrive/ui/tests/test_ui/run.py # selfdrive/ui/translations/main_ar.ts # selfdrive/ui/translations/main_de.ts # selfdrive/ui/translations/main_es.ts # selfdrive/ui/translations/main_fr.ts # selfdrive/ui/translations/main_ja.ts # selfdrive/ui/translations/main_ko.ts # selfdrive/ui/translations/main_pt-BR.ts # selfdrive/ui/translations/main_th.ts # selfdrive/ui/translations/main_tr.ts # selfdrive/ui/translations/main_zh-CHS.ts # selfdrive/ui/translations/main_zh-CHT.ts # system/athena/athenad.py
This commit is contained in:
@@ -322,7 +322,7 @@ jobs:
|
||||
run: |
|
||||
${{ env.RUN }} "source selfdrive/test/setup_xvfb.sh && \
|
||||
source selfdrive/test/setup_vsound.sh && \
|
||||
CI=1 pytest tools/sim/tests/test_metadrive_bridge.py"
|
||||
CI=1 pytest -s tools/sim/tests/test_metadrive_bridge.py"
|
||||
|
||||
create_ui_report:
|
||||
# This job name needs to be the same as UI_JOB_NAME in ui_preview.yaml
|
||||
|
||||
Vendored
+2
-2
@@ -103,7 +103,7 @@ def deviceStage(String stageName, String deviceType, List extra_env, def steps)
|
||||
def diffPaths = args.diffPaths ?: []
|
||||
def cmdTimeout = args.timeout ?: 9999
|
||||
|
||||
if (branch != "master" && diffPaths && !hasPathChanged(gitDiff, diffPaths)) {
|
||||
if (branch != "master" && !branch.contains("__jenkins_loop_") && diffPaths && !hasPathChanged(gitDiff, diffPaths)) {
|
||||
println "Skipping ${name}: no changes in ${diffPaths}."
|
||||
return
|
||||
} else {
|
||||
@@ -170,7 +170,7 @@ node {
|
||||
'testing-closet*', 'hotfix-*']
|
||||
def excludeRegex = excludeBranches.join('|').replaceAll('\\*', '.*')
|
||||
|
||||
if (env.BRANCH_NAME != 'master') {
|
||||
if (env.BRANCH_NAME != 'master' && !env.BRANCH_NAME.contains('__jenkins_loop_')) {
|
||||
properties([
|
||||
disableConcurrentBuilds(abortPrevious: true)
|
||||
])
|
||||
|
||||
+13
-14
@@ -1,23 +1,22 @@
|
||||
Version 0.9.9 (2025-03-30)
|
||||
Version 0.9.8 (2025-02-27)
|
||||
========================
|
||||
* New driving model
|
||||
* Model now gates applying positive acceleration in Chill mode
|
||||
* New driving monitoring model
|
||||
* Reduced false positives related to passengers
|
||||
* Image processing pipeline moved to the ISP
|
||||
* More GPU time for bigger driving models
|
||||
* Power draw reduced 0.5W, which means your device runs cooler
|
||||
* Added toggle to enable driver monitoring even when openpilot is not engaged
|
||||
* FIREHOSE mode
|
||||
* Allows you to maximize your training data uploads to improve the models
|
||||
* Enable openpilot longitudinal control for Ford Q3 vehicles
|
||||
* New Toyota TSS2 longitudinal tune
|
||||
* Coming soon
|
||||
* Rivian support
|
||||
* F-150 & Mach-E support
|
||||
* Tesla Model 3 support
|
||||
|
||||
Version 0.9.8 (2025-01-30)
|
||||
========================
|
||||
* New driving monitoring model
|
||||
* Reduced false positives related to passengers
|
||||
* Image processing pipeline moved to the ISP
|
||||
* More GPU time for driving models
|
||||
* Power draw reduced 0.5W, which means your device runs cooler
|
||||
* Added toggle to enable driver monitoring even when openpilot is not engaged
|
||||
* Enable openpilot longitudinal control for Ford Q3 vehicles
|
||||
* New Toyota TSS2 longitudinal tune
|
||||
* Coming soon
|
||||
* New driving model with gas gating
|
||||
* Training data upload mode
|
||||
|
||||
Version 0.9.7 (2024-06-13)
|
||||
========================
|
||||
|
||||
+1
-2
@@ -361,7 +361,7 @@ SConscript(['opendbc_repo/SConscript'], exports={'env': env_swaglog})
|
||||
SConscript(['cereal/SConscript'])
|
||||
|
||||
Import('socketmaster', 'msgq')
|
||||
messaging = [socketmaster, msgq, 'zmq', 'capnp', 'kj',]
|
||||
messaging = [socketmaster, msgq, 'capnp', 'kj',]
|
||||
Export('messaging')
|
||||
|
||||
|
||||
@@ -373,7 +373,6 @@ SConscript(['rednose/SConscript'])
|
||||
|
||||
# Build system services
|
||||
SConscript([
|
||||
'system/ui/SConscript',
|
||||
'system/proclogd/SConscript',
|
||||
'system/ubloxd/SConscript',
|
||||
'system/loggerd/SConscript',
|
||||
|
||||
+4
-4
@@ -29,7 +29,7 @@ _services: dict[str, tuple] = {
|
||||
"pandaStates": (True, 10., 1),
|
||||
"peripheralState": (True, 2., 1),
|
||||
"radarState": (True, 20., 5),
|
||||
"roadEncodeIdx": (False, 20., 1),
|
||||
"roadEncodeIdx": (False, 20., 20),
|
||||
"liveTracks": (True, 20.),
|
||||
"sendcan": (True, 100., 139),
|
||||
"logMessage": (True, 0.),
|
||||
@@ -53,15 +53,15 @@ _services: dict[str, tuple] = {
|
||||
"livePose": (True, 20., 4),
|
||||
"liveParameters": (True, 20., 5),
|
||||
"cameraOdometry": (True, 20., 10),
|
||||
"thumbnail": (True, 0.2, 1),
|
||||
"thumbnail": (True, 1 / 60., 1),
|
||||
"onroadEvents": (True, 1., 1),
|
||||
"carParams": (True, 0.02, 1),
|
||||
"roadCameraState": (True, 20., 20),
|
||||
"driverCameraState": (True, 20., 20),
|
||||
"driverEncodeIdx": (False, 20., 1),
|
||||
"driverEncodeIdx": (False, 20., 20),
|
||||
"driverStateV2": (True, 20., 10),
|
||||
"driverMonitoringState": (True, 20., 10),
|
||||
"wideRoadEncodeIdx": (False, 20., 1),
|
||||
"wideRoadEncodeIdx": (False, 20., 20),
|
||||
"wideRoadCameraState": (True, 20., 20),
|
||||
"drivingModelData": (True, 20., 10),
|
||||
"modelV2": (True, 20.),
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import io
|
||||
import os
|
||||
import tempfile
|
||||
import contextlib
|
||||
import zstandard as zstd
|
||||
|
||||
LOG_COMPRESSION_LEVEL = 10 # little benefit up to level 15. level ~17 is a small step change
|
||||
|
||||
|
||||
class CallbackReader:
|
||||
@@ -35,3 +39,20 @@ def atomic_write_in_dir(path: str, mode: str = 'w', buffering: int = -1, encodin
|
||||
yield tmp_file
|
||||
tmp_file_name = tmp_file.name
|
||||
os.replace(tmp_file_name, path)
|
||||
|
||||
|
||||
def get_upload_stream(filepath: str, should_compress: bool) -> tuple[io.BufferedIOBase, int]:
|
||||
if not should_compress:
|
||||
file_size = os.path.getsize(filepath)
|
||||
file_stream = open(filepath, "rb")
|
||||
return file_stream, file_size
|
||||
|
||||
# Compress the file on the fly
|
||||
compressed_stream = io.BytesIO()
|
||||
compressor = zstd.ZstdCompressor(level=LOG_COMPRESSION_LEVEL)
|
||||
|
||||
with open(filepath, "rb") as f:
|
||||
compressor.copy_stream(f, compressed_stream)
|
||||
compressed_size = compressed_stream.tell()
|
||||
compressed_stream.seek(0)
|
||||
return compressed_stream, compressed_size
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
#define DEFAULT_MODEL "Notre Dame (Default)"
|
||||
#define DEFAULT_MODEL "Not Too Shabby (Default)"
|
||||
|
||||
@@ -120,6 +120,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"ExperimentalLongitudinalEnabled", PERSISTENT | DEVELOPMENT_ONLY | BACKUP},
|
||||
{"ExperimentalMode", PERSISTENT | BACKUP},
|
||||
{"ExperimentalModeConfirmed", PERSISTENT | BACKUP},
|
||||
{"FirehoseMode", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"FirmwareQueryDone", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"ForcePowerDown", PERSISTENT},
|
||||
{"GitBranch", PERSISTENT},
|
||||
|
||||
+2
-6
@@ -27,11 +27,6 @@ class Priority:
|
||||
CTRL_HIGH = 53
|
||||
|
||||
|
||||
def set_realtime_priority(level: int) -> None:
|
||||
if not PC:
|
||||
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level))
|
||||
|
||||
|
||||
def set_core_affinity(cores: list[int]) -> None:
|
||||
if not PC:
|
||||
os.sched_setaffinity(0, cores)
|
||||
@@ -39,7 +34,8 @@ def set_core_affinity(cores: list[int]) -> None:
|
||||
|
||||
def config_realtime_process(cores: int | list[int], priority: int) -> None:
|
||||
gc.disable()
|
||||
set_realtime_priority(priority)
|
||||
if not PC:
|
||||
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(priority))
|
||||
c = cores if isinstance(cores, list) else [cores, ]
|
||||
set_core_affinity(c)
|
||||
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ A supported vehicle is one that just works when you install a comma device. All
|
||||
|Lexus|RX Hybrid 2016|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=RX Hybrid 2016">Buy Here</a></sub></details>||
|
||||
|Lexus|RX Hybrid 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=RX Hybrid 2017-19">Buy Here</a></sub></details>||
|
||||
|Lexus|RX Hybrid 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=RX Hybrid 2020-22">Buy Here</a></sub></details>||
|
||||
|Lexus|UX Hybrid 2019-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=UX Hybrid 2019-23">Buy Here</a></sub></details>||
|
||||
|Lexus|UX Hybrid 2019-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=UX Hybrid 2019-24">Buy Here</a></sub></details>||
|
||||
|Lincoln|Aviator 2020-24|Co-Pilot360 Plus|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lincoln&model=Aviator 2020-24">Buy Here</a></sub></details>||
|
||||
|Lincoln|Aviator Plug-in Hybrid 2020-24|Co-Pilot360 Plus|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lincoln&model=Aviator Plug-in Hybrid 2020-24">Buy Here</a></sub></details>||
|
||||
|MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|31 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 angled mount (8 degrees)<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=MAN&model=eTGE 2020-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1
|
||||
export VECLIB_MAXIMUM_THREADS=1
|
||||
|
||||
if [ -z "$AGNOS_VERSION" ]; then
|
||||
export AGNOS_VERSION="11.6"
|
||||
export AGNOS_VERSION="11.8"
|
||||
fi
|
||||
|
||||
export STAGING_ROOT="/data/safe_staging"
|
||||
|
||||
+1
-1
Submodule msgq_repo updated: 102befe731...3705ed0b29
+1
-1
Submodule opendbc_repo updated: cd086f3e5e...29d6e5977f
+1
-1
Submodule panda updated: 4ca963345a...44a9806bfb
@@ -111,6 +111,7 @@ dev = [
|
||||
"tabulate",
|
||||
"types-requests",
|
||||
"types-tabulate",
|
||||
"raylib",
|
||||
]
|
||||
|
||||
tools = [
|
||||
|
||||
Executable
+145
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
YELLOW='\033[0;33m'
|
||||
GREEN='\033[0;32m'
|
||||
UNDERLINE='\033[4m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
|
||||
BRANCH="master"
|
||||
RUNS="20"
|
||||
|
||||
COOKIE_JAR=/tmp/cookies
|
||||
CRUMB=$(curl -s --cookie-jar $COOKIE_JAR 'https://jenkins.comma.life/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
|
||||
|
||||
function loop() {
|
||||
JENKINS_BRANCH="__jenkins_loop_${BRANCH}"
|
||||
API_ROUTE="https://jenkins.comma.life/job/openpilot/job/$JENKINS_BRANCH"
|
||||
|
||||
for run in $(seq 1 $((RUNS / 2))); do
|
||||
|
||||
N=2
|
||||
TEST_BUILDS=()
|
||||
|
||||
# Try to find previous builds
|
||||
ALL_BUILDS=( $(curl -s $API_ROUTE/api/json | jq .builds.[].number 2> /dev/null || :) )
|
||||
|
||||
# No builds. Create branch
|
||||
if [[ ${#ALL_BUILDS[@]} -eq 0 ]]; then
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
GIT_LFS_SKIP_SMUDGE=1 git clone --quiet -b $BRANCH --depth=1 --no-tags git@github.com:commaai/openpilot $TEMP_DIR
|
||||
git -C $TEMP_DIR checkout --quiet -b $JENKINS_BRANCH
|
||||
echo "TESTING" >> $TEMP_DIR/testing_jenkins
|
||||
git -C $TEMP_DIR add testing_jenkins
|
||||
git -C $TEMP_DIR commit --quiet -m "testing"
|
||||
git -C $TEMP_DIR push --quiet -f origin $JENKINS_BRANCH
|
||||
rm -rf $TEMP_DIR
|
||||
FIRST_BUILD=1
|
||||
echo ''
|
||||
echo 'waiting on Jenkins...'
|
||||
echo ''
|
||||
sleep 90
|
||||
else
|
||||
# Found some builds. Wait for them to end if they are still running
|
||||
for i in ${ALL_BUILDS[@]}; do
|
||||
running=$(curl -s $API_ROUTE/$i/api/json/ | jq .inProgress)
|
||||
if [[ $running == "false" ]]; then
|
||||
continue
|
||||
fi
|
||||
TEST_BUILDS=( ${ALL_BUILDS[@]} )
|
||||
N=${#TEST_BUILDS[@]}
|
||||
break
|
||||
done
|
||||
fi
|
||||
|
||||
# No running builds found
|
||||
if [[ ${#TEST_BUILDS[@]} -eq 0 ]]; then
|
||||
FIRST_BUILD=$(curl -s $API_ROUTE/api/json | jq .nextBuildNumber)
|
||||
LAST_BUILD=$((FIRST_BUILD+N-1))
|
||||
TEST_BUILDS=( $(seq $FIRST_BUILD $LAST_BUILD) )
|
||||
|
||||
# Start N new builds
|
||||
for i in ${TEST_BUILDS[@]};
|
||||
do
|
||||
echo "Starting build $i"
|
||||
curl -s --output /dev/null --cookie $COOKIE_JAR -H "$CRUMB" -X POST $API_ROUTE/build?delay=0sec
|
||||
sleep 5
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Wait for all builds to end
|
||||
while true; do
|
||||
sleep 30
|
||||
|
||||
count=0
|
||||
for i in ${TEST_BUILDS[@]};
|
||||
do
|
||||
RES=$(curl -s -w "\n%{http_code}" --cookie $COOKIE_JAR -H "$CRUMB" $API_ROUTE/$i/api/json)
|
||||
HTTP_CODE=$(tail -n1 <<< "$RES")
|
||||
JSON=$(sed '$ d' <<< "$RES")
|
||||
|
||||
if [[ $HTTP_CODE == "200" ]]; then
|
||||
STILL_RUNNING=$(echo $JSON | jq .inProgress)
|
||||
if [[ $STILL_RUNNING == "true" ]]; then
|
||||
echo -e "Build $i: ${YELLOW}still running${NC}"
|
||||
continue
|
||||
else
|
||||
count=$((count+1))
|
||||
echo -e "Build $i: ${GREEN}done${NC}"
|
||||
fi
|
||||
else
|
||||
echo "No status for build $i"
|
||||
fi
|
||||
done
|
||||
echo "See live results: ${API_ROUTE}/buildTimeTrend"
|
||||
echo ""
|
||||
|
||||
if [[ $count -ge $N ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
done
|
||||
}
|
||||
|
||||
function usage() {
|
||||
echo ""
|
||||
echo "Run the Jenkins tests multiple times on a specific branch"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Options:${NC}"
|
||||
echo -e " ${BOLD}-n, --n${NC}"
|
||||
echo -e " Specify how many runs to do (default to ${BOLD}20${NC})"
|
||||
echo -e " ${BOLD}-b, --branch${NC}"
|
||||
echo -e " Specify which branch to run the tests against (default to ${BOLD}master${NC})"
|
||||
echo ""
|
||||
}
|
||||
|
||||
function _looper() {
|
||||
if [[ $# -eq 0 ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# parse Options
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-n | --n ) shift 1; RUNS="$1"; shift 1 ;;
|
||||
-b | --b | --branch | -branch ) shift 1; BRANCH="$1"; shift 1 ;;
|
||||
* ) usage; exit 0 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo -e "You are about to start $RUNS Jenkins builds against the $BRANCH branch."
|
||||
echo -e "If you expect this to run overnight, ${UNDERLINE}${BOLD}unplug the cold reboot power switch${NC} from the testing closet before."
|
||||
echo ""
|
||||
read -p "Press (y/Y) to confirm: " choice
|
||||
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
||||
loop
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
_looper $@
|
||||
@@ -53,7 +53,6 @@ function run_tests() {
|
||||
run "check_shebang_scripts_are_executable" python3 -m pre_commit_hooks.check_shebang_scripts_are_executable $ALL_FILES
|
||||
run "check_shebang_format" $DIR/check_shebang_format.sh $ALL_FILES
|
||||
run "check_nomerge_comments" $DIR/check_nomerge_comments.sh $ALL_FILES
|
||||
run "check_raylib_includes" $DIR/check_raylib_includes.sh $ALL_FILES
|
||||
|
||||
if [[ -z "$FAST" ]]; then
|
||||
run "mypy" mypy $PYTHON_FILES
|
||||
|
||||
@@ -45,9 +45,6 @@ class CarSpecificEvents:
|
||||
if self.CP.brand in ('body', 'mock'):
|
||||
events = Events()
|
||||
|
||||
elif self.CP.brand in ('subaru', 'mazda'):
|
||||
events = self.create_common_events(CS, CS_prev)
|
||||
|
||||
elif self.CP.brand == 'ford':
|
||||
events = self.create_common_events(CS, CS_prev, extra_gears=[GearShifter.manumatic])
|
||||
|
||||
@@ -102,13 +99,9 @@ class CarSpecificEvents:
|
||||
events.add(EventName.manualRestart)
|
||||
|
||||
elif self.CP.brand == 'gm':
|
||||
# The ECM allows enabling on falling edge of set, but only rising edge of resume
|
||||
events = self.create_common_events(CS, CS_prev, extra_gears=[GearShifter.sport, GearShifter.low,
|
||||
GearShifter.eco, GearShifter.manumatic],
|
||||
pcm_enable=self.CP.pcmCruise, enable_buttons=(ButtonType.decelCruise,))
|
||||
if not self.CP.pcmCruise:
|
||||
if any(b.type == ButtonType.accelCruise and b.pressed for b in CS.buttonEvents):
|
||||
events.add(EventName.buttonEnable)
|
||||
pcm_enable=self.CP.pcmCruise)
|
||||
|
||||
# Enabling at a standstill with brake is allowed
|
||||
# TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs
|
||||
@@ -122,8 +115,7 @@ class CarSpecificEvents:
|
||||
|
||||
elif self.CP.brand == 'volkswagen':
|
||||
events = self.create_common_events(CS, CS_prev, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
|
||||
pcm_enable=self.CP.pcmCruise,
|
||||
enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise))
|
||||
pcm_enable=self.CP.pcmCruise)
|
||||
|
||||
# Low speed steer alert hysteresis logic
|
||||
if (self.CP.minSteerSpeed - 1e-3) > VWCarControllerParams.DEFAULT_MIN_STEER_SPEED and CS.vEgo < (self.CP.minSteerSpeed + 1.):
|
||||
@@ -160,12 +152,12 @@ class CarSpecificEvents:
|
||||
events.add(EventName.belowSteerSpeed)
|
||||
|
||||
else:
|
||||
raise ValueError(f"Unsupported car: {self.CP.brand}")
|
||||
events = self.create_common_events(CS, CS_prev)
|
||||
|
||||
return events
|
||||
|
||||
def create_common_events(self, CS: structs.CarState, CS_prev: car.CarState, extra_gears=None, pcm_enable=True,
|
||||
allow_enable=True, allow_button_cancel=True, enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)):
|
||||
allow_enable=True, allow_button_cancel=True):
|
||||
events = Events()
|
||||
|
||||
if CS.doorOpen:
|
||||
@@ -209,12 +201,11 @@ class CarSpecificEvents:
|
||||
events.add(EventName.invalidLkasSetting)
|
||||
if CS.lowSpeedAlert:
|
||||
events.add(EventName.belowSteerSpeed)
|
||||
if CS.buttonEnable:
|
||||
events.add(EventName.buttonEnable)
|
||||
|
||||
# Handle button presses
|
||||
# Handle cancel button presses
|
||||
for b in CS.buttonEvents:
|
||||
# Enable OP long on falling edge of enable buttons (defaults to accelCruise and decelCruise, overridable per-port)
|
||||
if not self.CP.pcmCruise and (b.type in enable_buttons and not b.pressed):
|
||||
events.add(EventName.buttonEnable)
|
||||
# Disable on rising and falling edge of cancel for both stock and OP long
|
||||
# TODO: only check the cancel button with openpilot longitudinal on all brands to match panda safety
|
||||
if b.type == ButtonType.cancel and (allow_button_cancel or not self.CP.pcmCruise):
|
||||
|
||||
@@ -8,17 +8,17 @@ import cereal.messaging as messaging
|
||||
|
||||
from cereal import car, log, custom
|
||||
|
||||
from panda import ALTERNATIVE_EXPERIENCE
|
||||
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper
|
||||
from openpilot.common.swaglog import cloudlog, ForwardingHandler
|
||||
|
||||
from opendbc.car import DT_CTRL, carlog, structs
|
||||
from opendbc.car import DT_CTRL, structs
|
||||
from opendbc.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
|
||||
from opendbc.car.carlog import carlog
|
||||
from opendbc.car.fw_versions import ObdCallback
|
||||
from opendbc.car.car_helpers import get_car, get_radar_interface
|
||||
from opendbc.car.interfaces import CarInterfaceBase, RadarInterfaceBase
|
||||
from opendbc.safety import ALTERNATIVE_EXPERIENCE
|
||||
from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp
|
||||
from openpilot.selfdrive.car.cruise import VCruiseHelper
|
||||
from openpilot.selfdrive.car.car_specific import MockCarState
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import time
|
||||
import capnp
|
||||
import copy
|
||||
import os
|
||||
@@ -10,17 +11,15 @@ import hypothesis.strategies as st
|
||||
from hypothesis import Phase, given, settings
|
||||
from parameterized import parameterized_class
|
||||
|
||||
from cereal import messaging, log, car
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
from opendbc.car import DT_CTRL, gen_empty_fingerprint, structs
|
||||
from opendbc.car.fingerprints import all_known_cars, MIGRATION
|
||||
from opendbc.car.can_definitions import CanData
|
||||
from opendbc.car.car_helpers import FRAME_FINGERPRINT, interfaces
|
||||
from opendbc.car.fingerprints import all_known_cars, MIGRATION
|
||||
from opendbc.car.honda.values import CAR as HONDA, HondaFlags
|
||||
from opendbc.car.values import Platform
|
||||
from opendbc.car.structs import car
|
||||
from opendbc.car.tests.routes import non_tested_cars, routes, CarTestRoute
|
||||
from openpilot.selfdrive.selfdrived.events import ET
|
||||
from openpilot.selfdrive.selfdrived.selfdrived import SelfdriveD
|
||||
from opendbc.car.values import Platform
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.selfdrive.pandad import can_capnp_to_list
|
||||
from openpilot.selfdrive.test.helpers import read_segment_list
|
||||
from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT
|
||||
@@ -30,8 +29,6 @@ from openpilot.tools.lib.route import SegmentName
|
||||
|
||||
from panda.tests.libpanda import libpanda_py
|
||||
|
||||
EventName = log.OnroadEvent.EventName
|
||||
PandaType = log.PandaState.PandaType
|
||||
SafetyModel = car.CarParams.SafetyModel
|
||||
|
||||
NUM_JOBS = int(os.environ.get("NUM_JOBS", "1"))
|
||||
@@ -174,8 +171,6 @@ class TestCarModelBase(unittest.TestCase):
|
||||
self.CI = self.CarInterface(self.CP.copy(), copy.deepcopy(self.CP_SP), self.CarController, self.CarState)
|
||||
assert self.CI
|
||||
|
||||
Params().put_bool("OpenpilotEnabledToggle", self.openpilot_enabled)
|
||||
|
||||
# TODO: check safetyModel is in release panda build
|
||||
self.safety = libpanda_py.libpanda
|
||||
|
||||
@@ -344,10 +339,8 @@ class TestCarModelBase(unittest.TestCase):
|
||||
to_send = libpanda_py.make_CANPacket(address, bus, dat)
|
||||
self.safety.safety_rx_hook(to_send)
|
||||
|
||||
can = messaging.new_message('can', 1)
|
||||
can.can = [log.CanData(address=address, dat=dat, src=bus)]
|
||||
|
||||
CS = self.CI.update(can_capnp_to_list((can.to_bytes(),)))
|
||||
can = [(int(time.monotonic() * 1e9), [CanData(address=address, dat=dat, src=bus)])]
|
||||
CS = self.CI.update(can)
|
||||
|
||||
if self.safety.get_gas_pressed_prev() != prev_panda_gas:
|
||||
self.assertEqual(CS.gasPressed, self.safety.get_gas_pressed_prev())
|
||||
@@ -392,8 +385,6 @@ class TestCarModelBase(unittest.TestCase):
|
||||
controls_allowed_prev = False
|
||||
CS_prev = car.CarState.new_message()
|
||||
checks = defaultdict(int)
|
||||
selfdrived = SelfdriveD(CP=self.CP, CP_SP=self.CP_SP)
|
||||
selfdrived.initialized = True
|
||||
for idx, can in enumerate(self.can_msgs):
|
||||
CS = self.CI.update(can_capnp_to_list((can.as_builder().to_bytes(), ))).as_reader()
|
||||
for msg in filter(lambda m: m.src in range(64), can.can):
|
||||
@@ -437,11 +428,8 @@ class TestCarModelBase(unittest.TestCase):
|
||||
if not self.CP.notCar:
|
||||
checks['cruiseState'] += CS.cruiseState.enabled != self.safety.get_cruise_engaged_prev()
|
||||
else:
|
||||
# Check for enable events on rising edge of controls allowed
|
||||
selfdrived.update_events(CS)
|
||||
selfdrived.CS_prev = CS
|
||||
button_enable = (selfdrived.events.contains(ET.ENABLE) and
|
||||
EventName.pedalPressed not in selfdrived.events.names)
|
||||
# Check for user button enable on rising edge of controls allowed
|
||||
button_enable = CS.buttonEnable and (not CS.brakePressed or CS.standstill)
|
||||
mismatch = button_enable != (self.safety.get_controls_allowed() and not controls_allowed_prev)
|
||||
checks['controlsAllowed'] += mismatch
|
||||
controls_allowed_prev = self.safety.get_controls_allowed()
|
||||
|
||||
@@ -3,7 +3,7 @@ import os
|
||||
import time
|
||||
import numpy as np
|
||||
from cereal import log
|
||||
from opendbc.car.interfaces import ACCEL_MIN
|
||||
from opendbc.car.interfaces import ACCEL_MIN, ACCEL_MAX
|
||||
from openpilot.common.realtime import DT_MDL
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
# WARNING: imports outside of constants will not trigger a rebuild
|
||||
@@ -55,6 +55,8 @@ FCW_IDXS = T_IDXS < 5.0
|
||||
T_DIFFS = np.diff(T_IDXS, prepend=[0.])
|
||||
COMFORT_BRAKE = 2.5
|
||||
STOP_DISTANCE = 6.0
|
||||
CRUISE_MIN_ACCEL = -1.2
|
||||
CRUISE_MAX_ACCEL = 1.6
|
||||
|
||||
def get_jerk_factor(personality=log.LongitudinalPersonality.standard):
|
||||
if personality==log.LongitudinalPersonality.relaxed:
|
||||
@@ -281,7 +283,7 @@ class LongitudinalMpc:
|
||||
elif self.mode == 'blended':
|
||||
a_change_cost = 40.0 if prev_accel_constraint else 0
|
||||
cost_weights = [0., 0.1, 0.2, 5.0, a_change_cost, 1.0]
|
||||
constraint_cost_weights = [LIMIT_COST, LIMIT_COST, LIMIT_COST, 50.0]
|
||||
constraint_cost_weights = [LIMIT_COST, LIMIT_COST, LIMIT_COST, DANGER_ZONE_COST]
|
||||
else:
|
||||
raise NotImplementedError(f'Planner mode {self.mode} not recognized in planner cost set')
|
||||
self.set_cost_weights(cost_weights, constraint_cost_weights)
|
||||
@@ -325,12 +327,6 @@ class LongitudinalMpc:
|
||||
lead_xv = self.extrapolate_lead(x_lead, v_lead, a_lead, a_lead_tau)
|
||||
return lead_xv
|
||||
|
||||
def set_accel_limits(self, min_a, max_a):
|
||||
# TODO this sets a max accel limit, but the minimum limit is only for cruise decel
|
||||
# needs refactor
|
||||
self.cruise_min_a = min_a
|
||||
self.max_a = max_a
|
||||
|
||||
def update(self, radarstate, v_cruise, x, v, a, j, personality=log.LongitudinalPersonality.standard):
|
||||
t_follow = get_T_FOLLOW(personality)
|
||||
v_ego = self.x0[1]
|
||||
@@ -346,8 +342,7 @@ class LongitudinalMpc:
|
||||
lead_1_obstacle = lead_xv_1[:,0] + get_stopped_equivalence_factor(lead_xv_1[:,1])
|
||||
|
||||
self.params[:,0] = ACCEL_MIN
|
||||
# negative accel constraint causes problems because negative speed is not allowed
|
||||
self.params[:,1] = max(0.0, self.max_a)
|
||||
self.params[:,1] = ACCEL_MAX
|
||||
|
||||
# Update in ACC mode or ACC/e2e blend
|
||||
if self.mode == 'acc':
|
||||
@@ -355,9 +350,9 @@ class LongitudinalMpc:
|
||||
|
||||
# Fake an obstacle for cruise, this ensures smooth acceleration to set speed
|
||||
# when the leads are no factor.
|
||||
v_lower = v_ego + (T_IDXS * self.cruise_min_a * 1.05)
|
||||
v_lower = v_ego + (T_IDXS * CRUISE_MIN_ACCEL * 1.05)
|
||||
# TODO does this make sense when max_a is negative?
|
||||
v_upper = v_ego + (T_IDXS * self.max_a * 1.05)
|
||||
v_upper = v_ego + (T_IDXS * CRUISE_MAX_ACCEL * 1.05)
|
||||
v_cruise_clipped = np.clip(v_cruise * np.ones(N+1),
|
||||
v_lower,
|
||||
v_upper)
|
||||
|
||||
@@ -18,7 +18,6 @@ from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPlannerSP
|
||||
|
||||
LON_MPC_STEP = 0.2 # first step is 0.2s
|
||||
A_CRUISE_MIN = -1.2
|
||||
A_CRUISE_MAX_VALS = [1.6, 1.2, 0.8, 0.6]
|
||||
A_CRUISE_MAX_BP = [0., 10.0, 25., 40.]
|
||||
CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N]
|
||||
@@ -79,7 +78,10 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
|
||||
|
||||
self.a_desired = init_a
|
||||
self.v_desired_filter = FirstOrderFilter(init_v, 2.0, self.dt)
|
||||
self.prev_accel_clip = [ACCEL_MIN, ACCEL_MAX]
|
||||
self.v_model_error = 0.0
|
||||
self.output_a_target = 0.0
|
||||
self.output_should_stop = False
|
||||
|
||||
self.v_desired_trajectory = np.zeros(CONTROL_N)
|
||||
self.a_desired_trajectory = np.zeros(CONTROL_N)
|
||||
@@ -134,17 +136,16 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
|
||||
prev_accel_constraint = not (reset_state or sm['carState'].standstill)
|
||||
|
||||
if self.mpc.mode == 'acc':
|
||||
accel_limits = [A_CRUISE_MIN, get_max_accel(v_ego)]
|
||||
accel_clip = [ACCEL_MIN, get_max_accel(v_ego)]
|
||||
steer_angle_without_offset = sm['carState'].steeringAngleDeg - sm['liveParameters'].angleOffsetDeg
|
||||
accel_limits_turns = limit_accel_in_turns(v_ego, steer_angle_without_offset, accel_limits, self.CP)
|
||||
accel_clip = limit_accel_in_turns(v_ego, steer_angle_without_offset, accel_clip, self.CP)
|
||||
else:
|
||||
accel_limits = [ACCEL_MIN, ACCEL_MAX]
|
||||
accel_limits_turns = [ACCEL_MIN, ACCEL_MAX]
|
||||
accel_clip = [ACCEL_MIN, ACCEL_MAX]
|
||||
|
||||
if reset_state:
|
||||
self.v_desired_filter.x = v_ego
|
||||
# Clip aEgo to cruise limits to prevent large accelerations when becoming active
|
||||
self.a_desired = np.clip(sm['carState'].aEgo, accel_limits[0], accel_limits[1])
|
||||
self.a_desired = np.clip(sm['carState'].aEgo, accel_clip[0], accel_clip[1])
|
||||
|
||||
# Prevent divergence, smooth in current v_ego
|
||||
self.v_desired_filter.x = max(0.0, self.v_desired_filter.update(v_ego))
|
||||
@@ -155,18 +156,14 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
|
||||
self.allow_throttle = throttle_prob > ALLOW_THROTTLE_THRESHOLD or v_ego <= MIN_ALLOW_THROTTLE_SPEED
|
||||
|
||||
if not self.allow_throttle:
|
||||
clipped_accel_coast = max(accel_coast, accel_limits_turns[0])
|
||||
clipped_accel_coast_interp = np.interp(v_ego, [MIN_ALLOW_THROTTLE_SPEED, MIN_ALLOW_THROTTLE_SPEED*2], [accel_limits_turns[1], clipped_accel_coast])
|
||||
accel_limits_turns[1] = min(accel_limits_turns[1], clipped_accel_coast_interp)
|
||||
clipped_accel_coast = max(accel_coast, accel_clip[0])
|
||||
clipped_accel_coast_interp = np.interp(v_ego, [MIN_ALLOW_THROTTLE_SPEED, MIN_ALLOW_THROTTLE_SPEED*2], [accel_clip[1], clipped_accel_coast])
|
||||
accel_clip[1] = min(accel_clip[1], clipped_accel_coast_interp)
|
||||
|
||||
if force_slow_decel:
|
||||
v_cruise = 0.0
|
||||
# clip limits, cannot init MPC outside of bounds
|
||||
accel_limits_turns[0] = min(accel_limits_turns[0], self.a_desired + 0.05)
|
||||
accel_limits_turns[1] = max(accel_limits_turns[1], self.a_desired - 0.05)
|
||||
|
||||
self.mpc.set_weights(prev_accel_constraint, personality=sm['selfdriveState'].personality)
|
||||
self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1])
|
||||
self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired)
|
||||
self.mpc.update(sm['radarState'], v_cruise, x, v, a, j, personality=sm['selfdriveState'].personality)
|
||||
|
||||
@@ -184,6 +181,15 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
|
||||
self.a_desired = float(np.interp(self.dt, CONTROL_N_T_IDX, self.a_desired_trajectory))
|
||||
self.v_desired_filter.x = self.v_desired_filter.x + self.dt * (self.a_desired + a_prev) / 2.0
|
||||
|
||||
action_t = self.CP.longitudinalActuatorDelay + DT_MDL
|
||||
output_a_target, self.output_should_stop = get_accel_from_plan(self.v_desired_trajectory, self.a_desired_trajectory,
|
||||
action_t=action_t, vEgoStopping=self.CP.vEgoStopping)
|
||||
|
||||
for idx in range(2):
|
||||
accel_clip[idx] = np.clip(accel_clip[idx], self.prev_accel_clip[idx] - 0.05, self.prev_accel_clip[idx] + 0.05)
|
||||
self.output_a_target = np.clip(output_a_target, accel_clip[0], accel_clip[1])
|
||||
self.prev_accel_clip = accel_clip
|
||||
|
||||
def publish(self, sm, pm):
|
||||
plan_send = messaging.new_message('longitudinalPlan')
|
||||
|
||||
@@ -202,11 +208,8 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
|
||||
longitudinalPlan.longitudinalPlanSource = self.mpc.source
|
||||
longitudinalPlan.fcw = self.fcw
|
||||
|
||||
action_t = self.CP.longitudinalActuatorDelay + DT_MDL
|
||||
a_target, should_stop = get_accel_from_plan(longitudinalPlan.speeds, longitudinalPlan.accels,
|
||||
action_t=action_t, vEgoStopping=self.CP.vEgoStopping)
|
||||
longitudinalPlan.aTarget = float(a_target)
|
||||
longitudinalPlan.shouldStop = bool(should_stop)
|
||||
longitudinalPlan.aTarget = float(self.output_a_target)
|
||||
longitudinalPlan.shouldStop = bool(self.output_should_stop)
|
||||
longitudinalPlan.allowBrake = True
|
||||
longitudinalPlan.allowThrottle = bool(self.allow_throttle)
|
||||
|
||||
|
||||
@@ -11,5 +11,5 @@ if __name__ == "__main__":
|
||||
time.sleep(1)
|
||||
|
||||
# honda bosch radar disable
|
||||
disabled = disable_ecu(*can_callbacks, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03', timeout=0.5, debug=False)
|
||||
disabled = disable_ecu(*can_callbacks, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03', timeout=0.5)
|
||||
print(f"disabled: {disabled}")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import argparse
|
||||
import time
|
||||
import cereal.messaging as messaging
|
||||
from opendbc.car.carlog import carlog
|
||||
from opendbc.car.ecu_addrs import get_all_ecu_addrs
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.car.card import can_comm_callbacks, obd_callback
|
||||
@@ -15,6 +16,9 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--timeout', type=float, default=1.0)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
carlog.setLevel('DEBUG')
|
||||
|
||||
logcan = messaging.sub_sock('can')
|
||||
sendcan = messaging.pub_sock('sendcan')
|
||||
can_callbacks = can_comm_callbacks(logcan, sendcan)
|
||||
@@ -29,7 +33,7 @@ if __name__ == "__main__":
|
||||
obd_callback(params)(not args.no_obd)
|
||||
|
||||
print("Getting ECU addresses ...")
|
||||
ecu_addrs = get_all_ecu_addrs(*can_callbacks, args.bus, args.timeout, debug=args.debug)
|
||||
ecu_addrs = get_all_ecu_addrs(*can_callbacks, args.bus, args.timeout)
|
||||
|
||||
print()
|
||||
print("Found ECUs on rx addresses:")
|
||||
|
||||
@@ -3,6 +3,7 @@ import time
|
||||
import argparse
|
||||
import cereal.messaging as messaging
|
||||
from cereal import car
|
||||
from opendbc.car.carlog import carlog
|
||||
from opendbc.car.fw_versions import get_fw_versions, match_fw_to_car
|
||||
from opendbc.car.vin import get_vin
|
||||
from openpilot.common.params import Params
|
||||
@@ -18,6 +19,9 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--brand', help='Only query addresses/with requests for this brand')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
carlog.setLevel('DEBUG')
|
||||
|
||||
logcan = messaging.sub_sock('can')
|
||||
pandaStates_sock = messaging.sub_sock('pandaStates')
|
||||
sendcan = messaging.pub_sock('sendcan')
|
||||
@@ -46,13 +50,13 @@ if __name__ == "__main__":
|
||||
t = time.time()
|
||||
print("Getting vin...")
|
||||
set_obd_multiplexing(True)
|
||||
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (0, 1), debug=args.debug)
|
||||
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (0, 1))
|
||||
print(f'RX: {hex(vin_rx_addr)}, BUS: {vin_rx_bus}, VIN: {vin}')
|
||||
print(f"Getting VIN took {time.time() - t:.3f} s")
|
||||
print()
|
||||
|
||||
t = time.time()
|
||||
fw_vers = get_fw_versions(*can_callbacks, set_obd_multiplexing, query_brand=args.brand, extra=extra, num_pandas=num_pandas, debug=args.debug, progress=True)
|
||||
fw_vers = get_fw_versions(*can_callbacks, set_obd_multiplexing, query_brand=args.brand, extra=extra, num_pandas=num_pandas, progress=True)
|
||||
_, candidates = match_fw_to_car(fw_vers, vin)
|
||||
|
||||
print()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import argparse
|
||||
import time
|
||||
import cereal.messaging as messaging
|
||||
from opendbc.car.carlog import carlog
|
||||
from opendbc.car.vin import get_vin
|
||||
from openpilot.selfdrive.car.card import can_comm_callbacks
|
||||
|
||||
@@ -13,10 +14,13 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--retry', type=int, default=5)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
carlog.setLevel('DEBUG')
|
||||
|
||||
sendcan = messaging.pub_sock('sendcan')
|
||||
logcan = messaging.sub_sock('can')
|
||||
can_callbacks = can_comm_callbacks(logcan, sendcan)
|
||||
time.sleep(1)
|
||||
|
||||
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (args.bus,), args.timeout, args.retry, debug=args.debug)
|
||||
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (args.bus,), args.timeout, args.retry)
|
||||
print(f'RX: {hex(vin_rx_addr)}, BUS: {vin_rx_bus}, VIN: {vin}')
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
import sys
|
||||
import argparse
|
||||
from subprocess import check_output, CalledProcessError
|
||||
from opendbc.car.carlog import carlog
|
||||
from opendbc.car.uds import UdsClient, MessageTimeoutError, SESSION_TYPE, DTC_GROUP_TYPE
|
||||
from opendbc.safety import Safety
|
||||
from panda import Panda
|
||||
|
||||
parser = argparse.ArgumentParser(description="clear DTC status")
|
||||
@@ -11,6 +13,9 @@ parser.add_argument("--bus", type=int, default=0)
|
||||
parser.add_argument('--debug', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
carlog.setLevel('DEBUG')
|
||||
|
||||
try:
|
||||
check_output(["pidof", "pandad"])
|
||||
print("pandad is running, please kill openpilot before running this script! (aborted)")
|
||||
@@ -20,8 +25,8 @@ except CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
panda = Panda()
|
||||
panda.set_safety_mode(Panda.SAFETY_ELM327)
|
||||
uds_client = UdsClient(panda, args.addr, bus=args.bus, debug=args.debug)
|
||||
panda.set_safety_mode(Safety.SAFETY_ELM327)
|
||||
uds_client = UdsClient(panda, args.addr, bus=args.bus)
|
||||
print("extended diagnostic session ...")
|
||||
try:
|
||||
uds_client.diagnostic_session_control(SESSION_TYPE.EXTENDED_DIAGNOSTIC)
|
||||
|
||||
@@ -16,7 +16,9 @@ import argparse
|
||||
from typing import NamedTuple
|
||||
from subprocess import check_output, CalledProcessError
|
||||
|
||||
from opendbc.car.carlog import carlog
|
||||
from opendbc.car.uds import UdsClient, SESSION_TYPE, DATA_IDENTIFIER_TYPE
|
||||
from opendbc.safety import Safety
|
||||
from panda.python import Panda
|
||||
|
||||
class ConfigValues(NamedTuple):
|
||||
@@ -78,6 +80,9 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--bus', type=int, default=0, help='can bus to use (default: 0)')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
carlog.setLevel('DEBUG')
|
||||
|
||||
try:
|
||||
check_output(["pidof", "pandad"])
|
||||
print("pandad is running, please kill openpilot before running this script! (aborted)")
|
||||
@@ -92,8 +97,8 @@ if __name__ == "__main__":
|
||||
sys.exit(0)
|
||||
|
||||
panda = Panda()
|
||||
panda.set_safety_mode(Panda.SAFETY_ELM327)
|
||||
uds_client = UdsClient(panda, 0x7D0, bus=args.bus, debug=args.debug)
|
||||
panda.set_safety_mode(Safety.SAFETY_ELM327)
|
||||
uds_client = UdsClient(panda, 0x7D0, bus=args.bus)
|
||||
|
||||
print("\n[START DIAGNOSTIC SESSION]")
|
||||
session_type : SESSION_TYPE = 0x07 # type: ignore
|
||||
|
||||
@@ -6,7 +6,7 @@ from collections import defaultdict
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from cereal.services import SERVICE_LIST
|
||||
from openpilot.system.loggerd.uploader import LOG_COMPRESSION_LEVEL
|
||||
from openpilot.common.file_helpers import LOG_COMPRESSION_LEVEL
|
||||
from openpilot.tools.lib.logreader import LogReader
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
import sys
|
||||
import argparse
|
||||
from subprocess import check_output, CalledProcessError
|
||||
from opendbc.car.carlog import carlog
|
||||
from opendbc.car.uds import UdsClient, SESSION_TYPE, DTC_REPORT_TYPE, DTC_STATUS_MASK_TYPE, get_dtc_num_as_str, get_dtc_status_names
|
||||
from opendbc.safety import Safety
|
||||
from panda import Panda
|
||||
|
||||
parser = argparse.ArgumentParser(description="read DTC status")
|
||||
@@ -11,6 +13,9 @@ parser.add_argument("--bus", type=int, default=0)
|
||||
parser.add_argument('--debug', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
carlog.setLevel('DEBUG')
|
||||
|
||||
try:
|
||||
check_output(["pidof", "pandad"])
|
||||
print("pandad is running, please kill openpilot before running this script! (aborted)")
|
||||
@@ -20,8 +25,8 @@ except CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
panda = Panda()
|
||||
panda.set_safety_mode(Panda.SAFETY_ELM327)
|
||||
uds_client = UdsClient(panda, args.addr, bus=args.bus, debug=args.debug)
|
||||
panda.set_safety_mode(Safety.SAFETY_ELM327)
|
||||
uds_client = UdsClient(panda, args.addr, bus=args.bus)
|
||||
print("extended diagnostic session ...")
|
||||
uds_client.diagnostic_session_control(SESSION_TYPE.EXTENDED_DIAGNOSTIC)
|
||||
print("read diagnostic codes ...")
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
import argparse
|
||||
import struct
|
||||
from enum import IntEnum
|
||||
from opendbc.car.carlog import carlog
|
||||
from opendbc.car.uds import UdsClient, MessageTimeoutError, NegativeResponseError, SESSION_TYPE,\
|
||||
DATA_IDENTIFIER_TYPE, ACCESS_TYPE
|
||||
from opendbc.safety import Safety
|
||||
from panda import Panda
|
||||
from datetime import date
|
||||
|
||||
@@ -33,10 +35,13 @@ if __name__ == "__main__":
|
||||
parser.add_argument("action", choices={"show", "enable", "disable"}, help="show or modify current EPS HCA config")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
carlog.setLevel('DEBUG')
|
||||
|
||||
panda = Panda()
|
||||
panda.set_safety_mode(Panda.SAFETY_ELM327)
|
||||
panda.set_safety_mode(Safety.SAFETY_ELM327)
|
||||
bus = 1 if panda.has_obd() else 0
|
||||
uds_client = UdsClient(panda, MQB_EPS_CAN_ADDR, MQB_EPS_CAN_ADDR + RX_OFFSET, bus, timeout=0.2, debug=args.debug)
|
||||
uds_client = UdsClient(panda, MQB_EPS_CAN_ADDR, MQB_EPS_CAN_ADDR + RX_OFFSET, bus, timeout=0.2)
|
||||
|
||||
try:
|
||||
uds_client.diagnostic_session_control(SESSION_TYPE.EXTENDED_DIAGNOSTIC)
|
||||
|
||||
@@ -6,7 +6,6 @@ While the roll calibration is a real value that can be estimated, here we assume
|
||||
and the image input into the neural network is not corrected for roll.
|
||||
'''
|
||||
|
||||
import gc
|
||||
import os
|
||||
import capnp
|
||||
import numpy as np
|
||||
@@ -16,7 +15,7 @@ from cereal import log
|
||||
import cereal.messaging as messaging
|
||||
from openpilot.common.conversions import Conversions as CV
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.realtime import set_realtime_priority
|
||||
from openpilot.common.realtime import config_realtime_process
|
||||
from openpilot.common.transformations.orientation import rot_from_euler, euler_from_rot
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
|
||||
@@ -256,8 +255,7 @@ class Calibrator:
|
||||
|
||||
|
||||
def main() -> NoReturn:
|
||||
gc.disable()
|
||||
set_realtime_priority(1)
|
||||
config_realtime_process([0, 1, 2, 3], 5)
|
||||
|
||||
pm = messaging.PubMaster(['liveCalibration'])
|
||||
sm = messaging.SubMaster(['cameraOdometry', 'carState', 'carParams'], poll='cameraOdometry')
|
||||
|
||||
@@ -12,6 +12,7 @@ from cereal.services import SERVICE_LIST
|
||||
from openpilot.common.transformations.orientation import rot_from_euler
|
||||
from openpilot.common.realtime import config_realtime_process
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.selfdrive.locationd.helpers import rotate_std
|
||||
from openpilot.selfdrive.locationd.models.pose_kf import PoseKalman, States
|
||||
from openpilot.selfdrive.locationd.models.constants import ObservationKind, GENERATED_DIR
|
||||
@@ -78,20 +79,20 @@ class LocationEstimator:
|
||||
# sensor time and log time should be close
|
||||
sensor_time_invalid = abs(sensor_time - t) > MAX_SENSOR_TIME_DIFF
|
||||
if sensor_time_invalid:
|
||||
print("Sensor reading ignored, sensor timestamp more than 100ms off from log time")
|
||||
cloudlog.warning("Sensor reading ignored, sensor timestamp more than 100ms off from log time")
|
||||
return not sensor_time_invalid
|
||||
|
||||
def _validate_timestamp(self, t: float):
|
||||
kf_t = self.kf.t
|
||||
invalid = not np.isnan(kf_t) and (kf_t - t) > MAX_FILTER_REWIND_TIME
|
||||
if invalid:
|
||||
print("Observation timestamp is older than the max rewind threshold of the filter")
|
||||
cloudlog.warning("Observation timestamp is older than the max rewind threshold of the filter")
|
||||
return not invalid
|
||||
|
||||
def _finite_check(self, t: float, new_x: np.ndarray, new_P: np.ndarray):
|
||||
all_finite = np.isfinite(new_x).all() and np.isfinite(new_P).all()
|
||||
if not all_finite:
|
||||
print("Non-finite values detected, kalman reset")
|
||||
cloudlog.error("Non-finite values detected, kalman reset")
|
||||
self.reset(t)
|
||||
|
||||
def handle_log(self, t: float, which: str, msg: capnp._DynamicStructReader) -> HandleLogResult:
|
||||
@@ -308,13 +309,12 @@ def main():
|
||||
continue
|
||||
|
||||
if res == HandleLogResult.TIMING_INVALID:
|
||||
print(f"Observation {which} ignored due to failed timing check")
|
||||
cloudlog.warning(f"Observation {which} ignored due to failed timing check")
|
||||
observation_input_invalid[which] += 1
|
||||
print(observation_input_invalid[which])
|
||||
elif res == HandleLogResult.INPUT_INVALID:
|
||||
print(f"Observation {which} ignored due to failed sanity check")
|
||||
cloudlog.warning(f"Observation {which} ignored due to failed sanity check")
|
||||
observation_input_invalid[which] += 1
|
||||
else:
|
||||
elif res == HandleLogResult.SUCCESS:
|
||||
observation_input_invalid[which] *= input_invalid_decay[which]
|
||||
else:
|
||||
filter_initialized = sm.all_checks() and sensor_all_checks(acc_msgs, gyro_msgs, sensor_valid, sensor_recv_time, sensor_alive, SIMULATION)
|
||||
|
||||
@@ -31,7 +31,6 @@ class ModelConstants:
|
||||
DISENGAGE_WIDTH = 5
|
||||
POSE_WIDTH = 6
|
||||
WIDE_FROM_DEVICE_WIDTH = 3
|
||||
SIM_POSE_WIDTH = 6
|
||||
LEAD_WIDTH = 4
|
||||
LANE_LINES_WIDTH = 2
|
||||
ROAD_EDGES_WIDTH = 2
|
||||
@@ -72,13 +71,14 @@ class Plan:
|
||||
class Meta:
|
||||
ENGAGED = slice(0, 1)
|
||||
# next 2, 4, 6, 8, 10 seconds
|
||||
GAS_DISENGAGE = slice(1, 36, 7)
|
||||
BRAKE_DISENGAGE = slice(2, 36, 7)
|
||||
STEER_OVERRIDE = slice(3, 36, 7)
|
||||
HARD_BRAKE_3 = slice(4, 36, 7)
|
||||
HARD_BRAKE_4 = slice(5, 36, 7)
|
||||
HARD_BRAKE_5 = slice(6, 36, 7)
|
||||
GAS_PRESS = slice(7, 36, 7)
|
||||
GAS_DISENGAGE = slice(1, 31, 6)
|
||||
BRAKE_DISENGAGE = slice(2, 31, 6)
|
||||
STEER_OVERRIDE = slice(3, 31, 6)
|
||||
HARD_BRAKE_3 = slice(4, 31, 6)
|
||||
HARD_BRAKE_4 = slice(5, 31, 6)
|
||||
HARD_BRAKE_5 = slice(6, 31, 6)
|
||||
# next 0, 2, 4, 6, 8, 10 seconds
|
||||
LEFT_BLINKER = slice(36, 48, 2)
|
||||
RIGHT_BLINKER = slice(37, 48, 2)
|
||||
GAS_PRESS = slice(31, 55, 4)
|
||||
BRAKE_PRESS = slice(32, 55, 4)
|
||||
LEFT_BLINKER = slice(33, 55, 4)
|
||||
RIGHT_BLINKER = slice(34, 55, 4)
|
||||
|
||||
@@ -8,7 +8,6 @@ if TICI:
|
||||
os.environ['QCOM'] = '1'
|
||||
else:
|
||||
from openpilot.selfdrive.modeld.runners.ort_helpers import make_onnx_cpu_runner
|
||||
import gc
|
||||
import math
|
||||
import time
|
||||
import pickle
|
||||
@@ -21,7 +20,7 @@ from cereal import messaging
|
||||
from cereal.messaging import PubMaster, SubMaster
|
||||
from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.common.realtime import set_realtime_priority
|
||||
from openpilot.common.realtime import config_realtime_process
|
||||
from openpilot.common.transformations.model import dmonitoringmodel_intrinsics, DM_INPUT_SIZE
|
||||
from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye
|
||||
from openpilot.selfdrive.modeld.models.commonmodel_pyx import CLContext, MonitoringModelFrame
|
||||
@@ -140,9 +139,8 @@ def get_driverstate_packet(model_output: np.ndarray, frame_id: int, location_ts:
|
||||
|
||||
|
||||
def main():
|
||||
gc.disable()
|
||||
setproctitle(PROCESS_NAME)
|
||||
set_realtime_priority(1)
|
||||
config_realtime_process([0, 1, 2, 3], 5)
|
||||
|
||||
sentry.set_tag("daemon", PROCESS_NAME)
|
||||
cloudlog.bind(daemon=PROCESS_NAME)
|
||||
|
||||
@@ -112,10 +112,10 @@ def fill_model_msg(base_msg: capnp._DynamicStructBuilder, extended_msg: capnp._D
|
||||
|
||||
# temporal pose
|
||||
temporal_pose = modelV2.temporalPose
|
||||
temporal_pose.trans = net_output_data['plan'][0,0,Plan.VELOCITY].tolist()
|
||||
temporal_pose.transStd = net_output_data['plan_stds'][0,0,Plan.VELOCITY].tolist()
|
||||
temporal_pose.rot = net_output_data['plan'][0,0,Plan.ORIENTATION_RATE].tolist()
|
||||
temporal_pose.rotStd = net_output_data['plan_stds'][0,0,Plan.ORIENTATION_RATE].tolist()
|
||||
temporal_pose.trans = net_output_data['sim_pose'][0,:ModelConstants.POSE_WIDTH//2].tolist()
|
||||
temporal_pose.transStd = net_output_data['sim_pose_stds'][0,:ModelConstants.POSE_WIDTH//2].tolist()
|
||||
temporal_pose.rot = net_output_data['sim_pose'][0,ModelConstants.POSE_WIDTH//2:].tolist()
|
||||
temporal_pose.rotStd = net_output_data['sim_pose_stds'][0,ModelConstants.POSE_WIDTH//2:].tolist()
|
||||
|
||||
# poly path
|
||||
fill_xyz_poly(driving_model_data.path, ModelConstants.POLY_PATH_DEGREE, *net_output_data['plan'][0,:,Plan.POSITION].T)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:39786068cae1ed8c0dc34ef80c281dfcc67ed18a50e06b90765c49bcfdbf7db4
|
||||
size 51453312
|
||||
oid sha256:d21daa542227ecc5972da45df4e26f018ba113c0461f270e367d57e3ad89221a
|
||||
size 51461700
|
||||
|
||||
@@ -91,6 +91,7 @@ class Parser:
|
||||
self.parse_mdn('road_edges', outs, in_N=0, out_N=0, out_shape=(ModelConstants.NUM_ROAD_EDGES,ModelConstants.IDX_N,ModelConstants.LANE_LINES_WIDTH))
|
||||
self.parse_mdn('pose', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,))
|
||||
self.parse_mdn('road_transform', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,))
|
||||
self.parse_mdn('sim_pose', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,))
|
||||
self.parse_mdn('wide_from_device_euler', outs, in_N=0, out_N=0, out_shape=(ModelConstants.WIDE_FROM_DEVICE_WIDTH,))
|
||||
self.parse_mdn('lead', outs, in_N=ModelConstants.LEAD_MHP_N, out_N=ModelConstants.LEAD_MHP_SELECTION,
|
||||
out_shape=(ModelConstants.LEAD_TRAJ_LEN,ModelConstants.LEAD_WIDTH))
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
import gc
|
||||
|
||||
import cereal.messaging as messaging
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.realtime import set_realtime_priority
|
||||
from openpilot.common.realtime import config_realtime_process
|
||||
from openpilot.selfdrive.monitoring.helpers import DriverMonitoring
|
||||
|
||||
|
||||
def dmonitoringd_thread():
|
||||
gc.disable()
|
||||
set_realtime_priority(2)
|
||||
config_realtime_process([0, 1, 2, 3], 5)
|
||||
|
||||
params = Params()
|
||||
pm = messaging.PubMaster(['driverMonitoringState'])
|
||||
|
||||
@@ -2,10 +2,3 @@
|
||||
from openpilot.selfdrive.pandad.pandad_api_impl import can_list_to_can_capnp, can_capnp_to_list
|
||||
assert can_list_to_can_capnp
|
||||
assert can_capnp_to_list
|
||||
|
||||
def can_capnp_to_can_list(can, src_filter=None):
|
||||
ret = []
|
||||
for msg in can:
|
||||
if src_filter is None or msg.src in src_filter:
|
||||
ret.append((msg.address, msg.dat, msg.src))
|
||||
return ret
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "cereal/messaging/messaging.h"
|
||||
#include "selfdrive/pandad/panda.h"
|
||||
#include "opendbc/can/common.h"
|
||||
|
||||
void can_list_to_can_capnp_cpp(const std::vector<can_frame> &can_list, std::string &out, bool sendcan, bool valid) {
|
||||
void can_list_to_can_capnp_cpp(const std::vector<CanFrame> &can_list, std::string &out, bool sendcan, bool valid) {
|
||||
MessageBuilder msg;
|
||||
auto event = msg.initEvent(valid);
|
||||
|
||||
|
||||
@@ -6,12 +6,6 @@ from libcpp.string cimport string
|
||||
from libcpp cimport bool
|
||||
from libc.stdint cimport uint8_t, uint32_t, uint64_t
|
||||
|
||||
cdef extern from "panda.h":
|
||||
cdef struct can_frame:
|
||||
long address
|
||||
string dat
|
||||
long src
|
||||
|
||||
cdef extern from "opendbc/can/common.h":
|
||||
cdef struct CanFrame:
|
||||
long src
|
||||
@@ -23,12 +17,12 @@ cdef extern from "opendbc/can/common.h":
|
||||
vector[CanFrame] frames
|
||||
|
||||
cdef extern from "can_list_to_can_capnp.cc":
|
||||
void can_list_to_can_capnp_cpp(const vector[can_frame] &can_list, string &out, bool sendcan, bool valid)
|
||||
void can_list_to_can_capnp_cpp(const vector[CanFrame] &can_list, string &out, bool sendcan, bool valid)
|
||||
void can_capnp_to_can_list_cpp(const vector[string] &strings, vector[CanData] &can_data, bool sendcan)
|
||||
|
||||
def can_list_to_can_capnp(can_msgs, msgtype='can', valid=True):
|
||||
cdef can_frame *f
|
||||
cdef vector[can_frame] can_list
|
||||
cdef CanFrame *f
|
||||
cdef vector[CanFrame] can_list
|
||||
|
||||
can_list.reserve(len(can_msgs))
|
||||
for can_msg in can_msgs:
|
||||
|
||||
@@ -7,7 +7,7 @@ import cereal.messaging as messaging
|
||||
|
||||
from cereal import car, log, custom
|
||||
from msgq.visionipc import VisionIpcClient, VisionStreamType
|
||||
from panda import ALTERNATIVE_EXPERIENCE
|
||||
from opendbc.safety import ALTERNATIVE_EXPERIENCE
|
||||
|
||||
|
||||
from openpilot.common.params import Params
|
||||
@@ -31,7 +31,6 @@ from openpilot.sunnypilot.selfdrive.selfdrived.events import EventsSP
|
||||
REPLAY = "REPLAY" in os.environ
|
||||
SIMULATION = "SIMULATION" in os.environ
|
||||
TESTING_CLOSET = "TESTING_CLOSET" in os.environ
|
||||
IGNORE_PROCESSES = {"loggerd", "encoderd", "statsd"}
|
||||
LONGITUDINAL_PERSONALITY_MAP = {v: k for k, v in log.LongitudinalPersonality.schema.enumerants.items()}
|
||||
|
||||
ThermalStatus = log.DeviceState.ThermalStatus
|
||||
@@ -284,7 +283,7 @@ class SelfdriveD(CruiseHelper):
|
||||
if not_running != self.not_running_prev:
|
||||
cloudlog.event("process_not_running", not_running=not_running, error=True)
|
||||
self.not_running_prev = not_running
|
||||
if self.sm.recv_frame['managerState'] and (not_running - IGNORE_PROCESSES):
|
||||
if self.sm.recv_frame['managerState'] and not_running:
|
||||
self.events.add(EventName.processNotRunning)
|
||||
else:
|
||||
if not SIMULATION and not self.rk.lagging:
|
||||
|
||||
@@ -66,7 +66,7 @@ class Maneuver:
|
||||
print("Crashed!!!!")
|
||||
valid = False
|
||||
|
||||
if self.ensure_start and log['v_rel'] > 0 and log['speeds'][-1] <= 0.1:
|
||||
if self.ensure_start and log['v_rel'] > 0 and log['acceleration'] < 1e-3:
|
||||
print('LongitudinalPlanner not starting!')
|
||||
valid = False
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ class Plant:
|
||||
|
||||
self.distance = 0.
|
||||
self.speed = speed
|
||||
self.should_stop = False
|
||||
self.acceleration = 0.0
|
||||
self.speeds = []
|
||||
|
||||
# lead car
|
||||
self.lead_relevancy = lead_relevancy
|
||||
@@ -134,9 +134,9 @@ class Plant:
|
||||
'liveParameters': lp.liveParameters,
|
||||
'modelV2': model.modelV2}
|
||||
self.planner.update(sm)
|
||||
self.speed = self.planner.v_desired_filter.x
|
||||
self.acceleration = self.planner.a_desired
|
||||
self.speeds = self.planner.v_desired_trajectory.tolist()
|
||||
self.acceleration = self.planner.output_a_target
|
||||
self.speed = self.speed + self.acceleration * self.ts
|
||||
self.should_stop = self.planner.output_should_stop
|
||||
fcw = self.planner.fcw
|
||||
self.distance_lead = self.distance_lead + v_lead * self.ts
|
||||
|
||||
@@ -168,7 +168,7 @@ class Plant:
|
||||
"distance": self.distance,
|
||||
"speed": self.speed,
|
||||
"acceleration": self.acceleration,
|
||||
"speeds": self.speeds,
|
||||
"should_stop": self.should_stop,
|
||||
"distance_lead": self.distance_lead,
|
||||
"fcw": fcw,
|
||||
}
|
||||
|
||||
@@ -150,10 +150,7 @@ def create_maneuvers(kwargs):
|
||||
enabled=False,
|
||||
**kwargs,
|
||||
),
|
||||
]
|
||||
if not kwargs['e2e']:
|
||||
# allow_throttle won't trigger with e2e
|
||||
maneuvers.append(Maneuver(
|
||||
Maneuver(
|
||||
"slow to 5m/s with allow_throttle = False and pitch = +0.1",
|
||||
duration=30.,
|
||||
initial_speed=20.,
|
||||
@@ -164,7 +161,7 @@ def create_maneuvers(kwargs):
|
||||
breakpoints=[0.0, 2., 2.01],
|
||||
ensure_slowdown=True,
|
||||
**kwargs,
|
||||
))
|
||||
)]
|
||||
if not kwargs['force_decel']:
|
||||
# controls relies on planner commanding to move for stock-ACC resume spamming
|
||||
maneuvers.append(Maneuver(
|
||||
|
||||
@@ -6,15 +6,15 @@ import traceback
|
||||
|
||||
from cereal import messaging, car, log
|
||||
from opendbc.car.fingerprints import MIGRATION
|
||||
from opendbc.car.toyota.values import EPS_SCALE
|
||||
from opendbc.car.ford.values import CAR as FORD, FordFlags
|
||||
from opendbc.car.toyota.values import EPS_SCALE, ToyotaSafetyFlags
|
||||
from opendbc.car.ford.values import CAR as FORD, FordFlags, FordSafetyFlags
|
||||
from opendbc.car.hyundai.values import HyundaiSafetyFlags
|
||||
from openpilot.selfdrive.modeld.constants import ModelConstants
|
||||
from openpilot.selfdrive.modeld.fill_model_msg import fill_xyz_poly, fill_lane_line_meta
|
||||
from openpilot.selfdrive.test.process_replay.vision_meta import meta_from_encode_index
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_planner import get_accel_from_plan
|
||||
from openpilot.system.manager.process_config import managed_processes
|
||||
from openpilot.tools.lib.logreader import LogIterable
|
||||
from panda import Panda
|
||||
|
||||
MessageWithIndex = tuple[int, capnp.lib.capnp._DynamicStructReader]
|
||||
MigrationOps = tuple[list[tuple[int, capnp.lib.capnp._DynamicStructReader]], list[capnp.lib.capnp._DynamicStructReader], list[int]]
|
||||
@@ -269,19 +269,19 @@ def migrate_carOutput(msgs):
|
||||
def migrate_pandaStates(msgs):
|
||||
# TODO: safety param migration should be handled automatically
|
||||
safety_param_migration = {
|
||||
"TOYOTA_PRIUS": EPS_SCALE["TOYOTA_PRIUS"] | Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL,
|
||||
"TOYOTA_RAV4": EPS_SCALE["TOYOTA_RAV4"] | Panda.FLAG_TOYOTA_ALT_BRAKE,
|
||||
"KIA_EV6": Panda.FLAG_HYUNDAI_EV_GAS | Panda.FLAG_HYUNDAI_CANFD_HDA2,
|
||||
"TOYOTA_PRIUS": EPS_SCALE["TOYOTA_PRIUS"] | ToyotaSafetyFlags.FLAG_TOYOTA_STOCK_LONGITUDINAL,
|
||||
"TOYOTA_RAV4": EPS_SCALE["TOYOTA_RAV4"] | ToyotaSafetyFlags.FLAG_TOYOTA_ALT_BRAKE,
|
||||
"KIA_EV6": HyundaiSafetyFlags.FLAG_HYUNDAI_EV_GAS | HyundaiSafetyFlags.FLAG_HYUNDAI_CANFD_HDA2,
|
||||
}
|
||||
# TODO: get new Ford route
|
||||
safety_param_migration |= {car: Panda.FLAG_FORD_LONG_CONTROL for car in (set(FORD) - FORD.with_flags(FordFlags.CANFD))}
|
||||
safety_param_migration |= {car: FordSafetyFlags.FLAG_FORD_LONG_CONTROL for car in (set(FORD) - FORD.with_flags(FordFlags.CANFD))}
|
||||
|
||||
# Migrate safety param base on carParams
|
||||
CP = next((m.carParams for _, m in msgs if m.which() == 'carParams'), None)
|
||||
assert CP is not None, "carParams message not found"
|
||||
fingerprint = MIGRATION.get(CP.carFingerprint, CP.carFingerprint)
|
||||
if fingerprint in safety_param_migration:
|
||||
safety_param = safety_param_migration[fingerprint]
|
||||
safety_param = safety_param_migration[fingerprint].value
|
||||
elif len(CP.safetyConfigs):
|
||||
safety_param = CP.safetyConfigs[0].safetyParam
|
||||
if CP.safetyConfigs[0].safetyParamDEPRECATED != 0:
|
||||
|
||||
@@ -33,7 +33,7 @@ GITHUB = GithubUtils(API_TOKEN, DATA_TOKEN)
|
||||
|
||||
EXEC_TIMINGS = [
|
||||
# model, instant max, average max
|
||||
("modelV2", 0.03, 0.025),
|
||||
("modelV2", 0.035, 0.025),
|
||||
("driverStateV2", 0.02, 0.015),
|
||||
]
|
||||
|
||||
@@ -57,21 +57,24 @@ def get_event(logs, event):
|
||||
def zl(array, fill):
|
||||
return zip_longest(array, [], fillvalue=fill)
|
||||
|
||||
def get_idx_if_non_empty(l, idx=None):
|
||||
return l if idx is None else (l[idx] if len(l) > 0 else None)
|
||||
|
||||
def generate_report(proposed, master, tmp, commit):
|
||||
ModelV2_Plots = zl([
|
||||
(lambda x: x.velocity.x[0], "velocity.x"),
|
||||
(lambda x: x.action.desiredCurvature, "desiredCurvature"),
|
||||
(lambda x: x.leadsV3[0].x[0], "leadsV3.x"),
|
||||
(lambda x: x.laneLines[1].y[0], "laneLines.y"),
|
||||
#(lambda x: x.meta.disengagePredictions.gasPressProbs[1], "gasPressProbs")
|
||||
(lambda x: get_idx_if_non_empty(x.velocity.x, 0), "velocity.x"),
|
||||
(lambda x: get_idx_if_non_empty(x.action.desiredCurvature), "desiredCurvature"),
|
||||
(lambda x: get_idx_if_non_empty(x.leadsV3[0].x, 0), "leadsV3.x"),
|
||||
(lambda x: get_idx_if_non_empty(x.laneLines[1].y, 0), "laneLines.y"),
|
||||
(lambda x: get_idx_if_non_empty(x.meta.disengagePredictions.gasPressProbs, 1), "gasPressProbs")
|
||||
], "modelV2")
|
||||
DriverStateV2_Plots = zl([
|
||||
(lambda x: x.wheelOnRightProb, "wheelOnRightProb"),
|
||||
(lambda x: x.leftDriverData.faceProb, "leftDriverData.faceProb"),
|
||||
(lambda x: x.leftDriverData.faceOrientation[0], "leftDriverData.faceOrientation0"),
|
||||
(lambda x: x.leftDriverData.leftBlinkProb, "leftDriverData.leftBlinkProb"),
|
||||
(lambda x: x.leftDriverData.notReadyProb[0], "leftDriverData.notReadyProb0"),
|
||||
(lambda x: x.rightDriverData.faceProb, "rightDriverData.faceProb"),
|
||||
(lambda x: get_idx_if_non_empty(x.wheelOnRightProb), "wheelOnRightProb"),
|
||||
(lambda x: get_idx_if_non_empty(x.leftDriverData.faceProb), "leftDriverData.faceProb"),
|
||||
(lambda x: get_idx_if_non_empty(x.leftDriverData.faceOrientation, 0), "leftDriverData.faceOrientation0"),
|
||||
(lambda x: get_idx_if_non_empty(x.leftDriverData.leftBlinkProb), "leftDriverData.leftBlinkProb"),
|
||||
(lambda x: get_idx_if_non_empty(x.leftDriverData.notReadyProb, 0), "leftDriverData.notReadyProb0"),
|
||||
(lambda x: get_idx_if_non_empty(x.rightDriverData.faceProb), "rightDriverData.faceProb"),
|
||||
], "driverStateV2")
|
||||
|
||||
return [plot(map(v[0], get_event(proposed, event)), \
|
||||
|
||||
@@ -18,11 +18,11 @@ from cereal import car
|
||||
from cereal.services import SERVICE_LIST
|
||||
from msgq.visionipc import VisionIpcServer, get_endpoint_name as vipc_get_endpoint_name
|
||||
from opendbc.car.car_helpers import get_car, interfaces
|
||||
from opendbc.safety import ALTERNATIVE_EXPERIENCE
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.prefix import OpenpilotPrefix
|
||||
from openpilot.common.timeout import Timeout
|
||||
from openpilot.common.realtime import DT_CTRL
|
||||
from panda.python import ALTERNATIVE_EXPERIENCE
|
||||
from openpilot.selfdrive.car.card import can_comm_callbacks, convert_to_capnp
|
||||
from openpilot.system.manager.process_config import managed_processes
|
||||
from openpilot.selfdrive.test.process_replay.vision_meta import meta_from_camera_state, available_streams
|
||||
|
||||
@@ -8,7 +8,6 @@ import shutil
|
||||
import subprocess
|
||||
import time
|
||||
import numpy as np
|
||||
import zstandard as zstd
|
||||
from collections import Counter, defaultdict
|
||||
from pathlib import Path
|
||||
from tabulate import tabulate
|
||||
@@ -23,7 +22,6 @@ from openpilot.selfdrive.selfdrived.events import EVENTS, ET
|
||||
from openpilot.selfdrive.test.helpers import set_params_enabled, release_only
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.hardware.hw import Paths
|
||||
from openpilot.system.loggerd.uploader import LOG_COMPRESSION_LEVEL
|
||||
from openpilot.tools.lib.logreader import LogReader
|
||||
|
||||
"""
|
||||
@@ -36,7 +34,7 @@ CPU usage budget
|
||||
TEST_DURATION = 25
|
||||
LOG_OFFSET = 8
|
||||
|
||||
MAX_TOTAL_CPU = 275. # total for all 8 cores
|
||||
MAX_TOTAL_CPU = 280. # total for all 8 cores
|
||||
PROCS = {
|
||||
# Baseline CPU usage by process
|
||||
"selfdrive.controls.controlsd": 16.0,
|
||||
@@ -44,7 +42,7 @@ PROCS = {
|
||||
"selfdrive.car.card": 26.0,
|
||||
"./loggerd": 14.0,
|
||||
"./encoderd": 17.0,
|
||||
"./camerad": 14.5,
|
||||
"./camerad": 10.0,
|
||||
"selfdrive.controls.plannerd": 9.0,
|
||||
"./ui": 18.0,
|
||||
"selfdrive.locationd.paramsd": 9.0,
|
||||
@@ -101,12 +99,12 @@ TIMINGS = {
|
||||
"wideRoadCameraState": [1.5, 0.35],
|
||||
}
|
||||
|
||||
LOGS_SIZE_RATE = {
|
||||
"qlog": 0.0083,
|
||||
"rlog": 0.135,
|
||||
"qcamera.ts": 0.03828,
|
||||
LOGS_SIZE = { # MB per segment
|
||||
"qlog.zst": 0.5,
|
||||
"rlog.zst": 8.1,
|
||||
"qcamera.ts": 2.3,
|
||||
}
|
||||
LOGS_SIZE_RATE.update(dict.fromkeys(['ecamera.hevc', 'fcamera.hevc'], 1.2740))
|
||||
LOGS_SIZE.update(dict.fromkeys(['ecamera.hevc', 'fcamera.hevc', 'dcamera.hevc'], 76.5))
|
||||
|
||||
|
||||
def cputime_total(ct):
|
||||
@@ -119,15 +117,16 @@ class TestOnroad:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
if "DEBUG" in os.environ:
|
||||
segs = filter(lambda x: os.path.exists(os.path.join(x, "rlog")), Path(Paths.log_root()).iterdir())
|
||||
segs = filter(lambda x: os.path.exists(os.path.join(x, "rlog.zst")), Path(Paths.log_root()).iterdir())
|
||||
segs = sorted(segs, key=lambda x: x.stat().st_mtime)
|
||||
print(segs[-3])
|
||||
cls.lr = list(LogReader(os.path.join(segs[-3], "rlog")))
|
||||
cls.lr = list(LogReader(os.path.join(segs[-3], "rlog.zst")))
|
||||
return
|
||||
|
||||
# setup env
|
||||
params = Params()
|
||||
params.remove("CurrentRoute")
|
||||
params.put_bool("RecordFront", True)
|
||||
set_params_enabled()
|
||||
os.environ['REPLAY'] = '1'
|
||||
os.environ['TESTING_CLOSET'] = '1'
|
||||
@@ -173,18 +172,15 @@ class TestOnroad:
|
||||
if proc.wait(60) is None:
|
||||
proc.kill()
|
||||
|
||||
cls.lrs = [list(LogReader(os.path.join(str(s), "rlog"))) for s in cls.segments]
|
||||
cls.lrs = [list(LogReader(os.path.join(str(s), "rlog.zst"))) for s in cls.segments]
|
||||
|
||||
cls.lr = list(LogReader(os.path.join(str(cls.segments[0]), "rlog")))
|
||||
cls.lr = list(LogReader(os.path.join(str(cls.segments[0]), "rlog.zst")))
|
||||
cls.log_path = cls.segments[0]
|
||||
|
||||
cls.log_sizes = {}
|
||||
for f in cls.log_path.iterdir():
|
||||
assert f.is_file()
|
||||
cls.log_sizes[f] = f.stat().st_size / 1e6
|
||||
if f.name in ("qlog", "rlog"):
|
||||
with open(f, 'rb') as ff:
|
||||
cls.log_sizes[f] = len(zstd.compress(ff.read(), LOG_COMPRESSION_LEVEL)) / 1e6
|
||||
|
||||
cls.msgs = defaultdict(list)
|
||||
for m in cls.lr:
|
||||
@@ -217,12 +213,14 @@ class TestOnroad:
|
||||
big_logs = [f for f, n in cnt.most_common(3) if n / sum(cnt.values()) > 30.]
|
||||
assert len(big_logs) == 0, f"Log spam: {big_logs}"
|
||||
|
||||
def test_log_sizes(self):
|
||||
def test_log_sizes(self, subtests):
|
||||
# TODO: this isn't super stable between different devices
|
||||
for f, sz in self.log_sizes.items():
|
||||
rate = LOGS_SIZE_RATE[f.name]
|
||||
minn = rate * TEST_DURATION * 0.8
|
||||
maxx = rate * TEST_DURATION * 1.2
|
||||
assert minn < sz < maxx
|
||||
rate = LOGS_SIZE[f.name]/60.
|
||||
minn = rate * TEST_DURATION * 0.5
|
||||
maxx = rate * TEST_DURATION * 1.5
|
||||
with subtests.test(file=f.name):
|
||||
assert minn < sz < maxx
|
||||
|
||||
def test_ui_timings(self):
|
||||
result = "\n"
|
||||
@@ -316,37 +314,21 @@ class TestOnroad:
|
||||
def test_gpu_usage(self):
|
||||
assert self.gpu_procs == {"weston", "ui", "camerad", "selfdrive.modeld.modeld", "selfdrive.modeld.dmonitoringmodeld"}
|
||||
|
||||
def test_camera_processing_time(self):
|
||||
def test_camera_frame_timings(self, subtests):
|
||||
result = "\n"
|
||||
result += "------------------------------------------------\n"
|
||||
result += "-------------- ImgProc Timing ------------------\n"
|
||||
result += "------------------------------------------------\n"
|
||||
|
||||
ts = []
|
||||
for s in ['roadCameraState', 'driverCameraState', 'wideCameraState']:
|
||||
ts.extend(getattr(m, s).processingTime for m in self.msgs[s])
|
||||
assert min(ts) < 0.025, f"high execution time: {min(ts)}"
|
||||
result += f"execution time: min {min(ts):.5f}s\n"
|
||||
result += f"execution time: max {max(ts):.5f}s\n"
|
||||
result += f"execution time: mean {np.mean(ts):.5f}s\n"
|
||||
result += "------------------------------------------------\n"
|
||||
print(result)
|
||||
|
||||
@pytest.mark.skip("TODO: enable once timings are fixed")
|
||||
def test_camera_frame_timings(self):
|
||||
result = "\n"
|
||||
result += "------------------------------------------------\n"
|
||||
result += "----------------- SoF Timing ------------------\n"
|
||||
result += "----------------- SOF Timing ------------------\n"
|
||||
result += "------------------------------------------------\n"
|
||||
for name in ['roadCameraState', 'wideRoadCameraState', 'driverCameraState']:
|
||||
ts = [getattr(m, m.which()).timestampSof for m in self.lr if name in m.which()]
|
||||
d_ms = np.diff(ts) / 1e6
|
||||
d50 = np.abs(d_ms-50)
|
||||
assert max(d50) < 1.0, f"high sof delta vs 50ms: {max(d50)}"
|
||||
result += f"{name} sof delta vs 50ms: min {min(d50):.5f}s\n"
|
||||
result += f"{name} sof delta vs 50ms: max {max(d50):.5f}s\n"
|
||||
result += f"{name} sof delta vs 50ms: mean {d50.mean():.5f}s\n"
|
||||
result += "------------------------------------------------\n"
|
||||
result += f"{name} sof delta vs 50ms: min {min(d50):.2f}ms\n"
|
||||
result += f"{name} sof delta vs 50ms: max {max(d50):.2f}ms\n"
|
||||
result += f"{name} sof delta vs 50ms: mean {d50.mean():.2f}ms\n"
|
||||
with subtests.test(camera=name):
|
||||
assert max(d50) < 5.0, f"high SOF delta vs 50ms: {max(d50)}"
|
||||
result += "------------------------------------------------\n"
|
||||
print(result)
|
||||
|
||||
def test_mpc_execution_timings(self):
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
#include <QDebug>
|
||||
#include <QProcess>
|
||||
|
||||
#include "selfdrive/ui/qt/offroad/developer_panel.h"
|
||||
#include "selfdrive/ui/qt/widgets/ssh_keys.h"
|
||||
#include "common/util.h"
|
||||
|
||||
#ifdef SUNNYPILOT
|
||||
#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h"
|
||||
@@ -114,6 +110,7 @@ void DeveloperPanel::updateToggles(bool _offroad) {
|
||||
experimentalLongitudinalToggle->setVisible(false);
|
||||
hyundaiRadarTracksToggle->setVisible(false);
|
||||
}
|
||||
experimentalLongitudinalToggle->refresh();
|
||||
|
||||
offroad = _offroad;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ private:
|
||||
ParamControl* experimentalLongitudinalToggle;
|
||||
ParamControl* hyundaiRadarTracksToggle;
|
||||
bool is_release;
|
||||
bool offroad;
|
||||
bool offroad = false;
|
||||
|
||||
private slots:
|
||||
void updateToggles(bool _offroad);
|
||||
|
||||
@@ -42,6 +42,20 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
|
||||
tr("When enabled, pressing the accelerator pedal will disengage openpilot."),
|
||||
"../assets/offroad/icon_disengage_on_accelerator.svg",
|
||||
},
|
||||
{
|
||||
"FirehoseMode",
|
||||
tr("FIREHOSE Mode"),
|
||||
tr("Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>"
|
||||
"Follow these steps to get your device ready:<br>"
|
||||
" 1. Bring your device inside and connect to a good USB-C adapter<br>"
|
||||
" 2. Connect to Wi-Fi<br>"
|
||||
" 3. Enable this toggle<br>"
|
||||
" 4. Leave it connected for at least 30 minutes<br>"
|
||||
"<br>"
|
||||
"This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness."
|
||||
""),
|
||||
"../assets/offroad/icon_warning.png",
|
||||
},
|
||||
{
|
||||
"IsLdwEnabled",
|
||||
tr("Enable Lane Departure Warnings"),
|
||||
|
||||
Regular → Executable
@@ -1553,6 +1553,14 @@ This may take up to a minute.</source>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1537,6 +1537,14 @@ This may take up to a minute.</source>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1537,6 +1537,14 @@ Esto puede tardar un minuto.</translation>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1537,6 +1537,14 @@ Cela peut prendre jusqu'à une minute.</translation>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1533,6 +1533,14 @@ This may take up to a minute.</source>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1533,6 +1533,14 @@ This may take up to a minute.</source>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1537,6 +1537,14 @@ Isso pode levar até um minuto.</translation>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1533,6 +1533,14 @@ This may take up to a minute.</source>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1531,6 +1531,14 @@ This may take up to a minute.</source>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1533,6 +1533,14 @@ This may take up to a minute.</source>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -1533,6 +1533,14 @@ This may take up to a minute.</source>
|
||||
<source>Enable toggle to allow the model to determine when to use sunnypilot ACC or sunnypilot End to End Longitudinal.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FIREHOSE Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable <b>FIREHOSE Mode</b> to get your driving data in the training set.<br><br>Follow these steps to get your device ready:<br> 1. Bring your device inside and connect to a good USB-C adapter<br> 2. Connect to Wi-Fi<br> 3. Enable this toggle<br> 4. Leave it connected for at least 30 minutes<br><br>This toggle turns off once you restart your device. Repeat once a week for maximum effectiveness.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Updater</name>
|
||||
|
||||
@@ -24,10 +24,10 @@ THE SOFTWARE.
|
||||
Last updated: July 29, 2024
|
||||
"""
|
||||
|
||||
from panda import Panda, ALTERNATIVE_EXPERIENCE
|
||||
|
||||
from openpilot.common.params import Params
|
||||
|
||||
from opendbc.safety import ALTERNATIVE_EXPERIENCE
|
||||
from opendbc.car.hyundai.values import HyundaiSafetyFlags
|
||||
from opendbc.sunnypilot.car.hyundai.values import HyundaiFlagsSP
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class MadsParams:
|
||||
hyundai_cruise_main_toggleable = True
|
||||
if hyundai_cruise_main_toggleable:
|
||||
CP_SP.flags |= HyundaiFlagsSP.LONGITUDINAL_MAIN_CRUISE_TOGGLEABLE.value
|
||||
CP.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_LONG_MAIN_CRUISE_TOGGLEABLE
|
||||
CP.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.FLAG_HYUNDAI_LONG_MAIN_CRUISE_TOGGLEABLE.value
|
||||
|
||||
# MADS is currently not supported in Tesla due to lack of consistent states to engage controls
|
||||
# TODO-SP: To enable MADS for Tesla, identify consistent signals for MADS toggling
|
||||
|
||||
@@ -1 +1 @@
|
||||
39786068cae1ed8c0dc34ef80c281dfcc67ed18a50e06b90765c49bcfdbf7db4
|
||||
d21daa542227ecc5972da45df4e26f018ba113c0461f270e367d57e3ad89221a
|
||||
+18
-14
@@ -15,7 +15,6 @@ import tempfile
|
||||
import threading
|
||||
import time
|
||||
import gzip
|
||||
import zstandard as zstd
|
||||
from dataclasses import asdict, dataclass, replace
|
||||
from datetime import datetime
|
||||
from functools import partial
|
||||
@@ -32,11 +31,10 @@ import cereal.messaging as messaging
|
||||
from cereal import log
|
||||
from cereal.services import SERVICE_LIST
|
||||
from openpilot.common.api import Api
|
||||
from openpilot.common.file_helpers import CallbackReader
|
||||
from openpilot.common.file_helpers import CallbackReader, get_upload_stream
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.realtime import set_core_affinity
|
||||
from openpilot.system.hardware import HARDWARE, PC
|
||||
from openpilot.system.loggerd.uploader import LOG_COMPRESSION_LEVEL
|
||||
from openpilot.system.loggerd.xattr_cache import getxattr, setxattr
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.system.version import get_build_metadata
|
||||
@@ -147,6 +145,9 @@ def handle_long_poll(ws: WebSocket, exit_event: threading.Event | None) -> None:
|
||||
threading.Thread(target=ws_recv, args=(ws, end_event), name='ws_recv'),
|
||||
threading.Thread(target=ws_send, args=(ws, end_event), name='ws_send'),
|
||||
threading.Thread(target=upload_handler, args=(end_event,), name='upload_handler'),
|
||||
threading.Thread(target=upload_handler, args=(end_event,), name='upload_handler2'),
|
||||
threading.Thread(target=upload_handler, args=(end_event,), name='upload_handler3'),
|
||||
threading.Thread(target=upload_handler, args=(end_event,), name='upload_handler4'),
|
||||
threading.Thread(target=log_handler, args=(end_event,), name='log_handler'),
|
||||
threading.Thread(target=stat_handler, args=(end_event,), name='stat_handler'),
|
||||
] + [
|
||||
@@ -293,17 +294,17 @@ def _do_upload(upload_item: UploadItem, callback: Callable = None) -> requests.R
|
||||
path = strip_zst_extension(path)
|
||||
compress = True
|
||||
|
||||
with open(path, "rb") as f:
|
||||
content = f.read()
|
||||
if compress:
|
||||
cloudlog.event("athena.upload_handler.compress", fn=path, fn_orig=upload_item.path)
|
||||
content = zstd.compress(content, LOG_COMPRESSION_LEVEL)
|
||||
|
||||
with io.BytesIO(content) as data:
|
||||
return requests.put(upload_item.url,
|
||||
data=CallbackReader(data, callback, len(content)) if callback else data,
|
||||
headers={**upload_item.headers, 'Content-Length': str(len(content))},
|
||||
timeout=30)
|
||||
stream = None
|
||||
try:
|
||||
stream, content_length = get_upload_stream(path, compress)
|
||||
response = requests.put(upload_item.url,
|
||||
data=CallbackReader(stream, callback, content_length) if callback else stream,
|
||||
headers={**upload_item.headers, 'Content-Length': str(content_length)},
|
||||
timeout=30)
|
||||
return response
|
||||
finally:
|
||||
if stream:
|
||||
stream.close()
|
||||
|
||||
|
||||
# security: user should be able to request any message from their car
|
||||
@@ -522,6 +523,9 @@ def getSshAuthorizedKeys() -> str:
|
||||
def getGithubUsername() -> str:
|
||||
return Params().get("GithubUsername", encoding='utf8') or ''
|
||||
|
||||
@dispatcher.add_method
|
||||
def getFirehoseMode() -> bool:
|
||||
return Params().get_bool("FirehoseMode") or False
|
||||
|
||||
@dispatcher.add_method
|
||||
def getSimInfo():
|
||||
|
||||
@@ -138,7 +138,7 @@ class TestAthenadMethods:
|
||||
route = '2021-03-29--13-32-47'
|
||||
segments = [0, 1, 2, 3, 11]
|
||||
|
||||
filenames = ['qlog', 'qcamera.ts', 'rlog', 'fcamera.hevc', 'ecamera.hevc', 'dcamera.hevc']
|
||||
filenames = ['qlog.zst', 'qcamera.ts', 'rlog.zst', 'fcamera.hevc', 'ecamera.hevc', 'dcamera.hevc']
|
||||
files = [f'{route}--{s}/{f}' for s in segments for f in filenames]
|
||||
for file in files:
|
||||
self._create_file(file)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Import('env', 'arch', 'messaging', 'common', 'gpucommon', 'visionipc')
|
||||
|
||||
libs = ['pthread', common, 'jpeg', 'OpenCL', messaging, visionipc, gpucommon]
|
||||
libs = ['pthread', common, 'OpenCL', messaging, visionipc, gpucommon]
|
||||
|
||||
if arch != "Darwin":
|
||||
camera_obj = env.Object(['cameras/camera_qcom2.cc', 'cameras/camera_common.cc', 'cameras/spectra.cc',
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -3,8 +3,6 @@
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
#include <jpeglib.h>
|
||||
|
||||
#include "common/clutil.h"
|
||||
#include "common/swaglog.h"
|
||||
|
||||
@@ -64,11 +62,11 @@ void CameraBuf::init(cl_device_id device_id, cl_context context, SpectraCamera *
|
||||
|
||||
const SensorInfo *sensor = cam->sensor.get();
|
||||
|
||||
is_raw = cam->is_raw;
|
||||
is_raw = cam->output_type == ISP_RAW_OUTPUT;
|
||||
frame_metadata = std::make_unique<FrameMetadata[]>(frame_buf_count);
|
||||
|
||||
// RAW frames from ISP
|
||||
if (is_raw) {
|
||||
if (cam->output_type != ISP_IFE_PROCESSED) {
|
||||
camera_bufs_raw = std::make_unique<VisionBuf[]>(frame_buf_count);
|
||||
|
||||
const int raw_frame_size = (sensor->frame_height + sensor->extra_height) * sensor->frame_stride;
|
||||
@@ -150,95 +148,6 @@ kj::Array<uint8_t> get_raw_frame_image(const CameraBuf *b) {
|
||||
return kj::mv(frame_image);
|
||||
}
|
||||
|
||||
static kj::Array<capnp::byte> yuv420_to_jpeg(const CameraBuf *b, int thumbnail_width, int thumbnail_height) {
|
||||
int downscale = b->cur_yuv_buf->width / thumbnail_width;
|
||||
assert(downscale * thumbnail_height == b->cur_yuv_buf->height);
|
||||
int in_stride = b->cur_yuv_buf->stride;
|
||||
|
||||
// make the buffer big enough. jpeg_write_raw_data requires 16-pixels aligned height to be used.
|
||||
std::unique_ptr<uint8_t[]> buf(new uint8_t[(thumbnail_width * ((thumbnail_height + 15) & ~15) * 3) / 2]);
|
||||
uint8_t *y_plane = buf.get();
|
||||
uint8_t *u_plane = y_plane + thumbnail_width * thumbnail_height;
|
||||
uint8_t *v_plane = u_plane + (thumbnail_width * thumbnail_height) / 4;
|
||||
{
|
||||
// subsampled conversion from nv12 to yuv
|
||||
for (int hy = 0; hy < thumbnail_height/2; hy++) {
|
||||
for (int hx = 0; hx < thumbnail_width/2; hx++) {
|
||||
int ix = hx * downscale + (downscale-1)/2;
|
||||
int iy = hy * downscale + (downscale-1)/2;
|
||||
y_plane[(hy*2 + 0)*thumbnail_width + (hx*2 + 0)] = b->cur_yuv_buf->y[(iy*2 + 0) * in_stride + ix*2 + 0];
|
||||
y_plane[(hy*2 + 0)*thumbnail_width + (hx*2 + 1)] = b->cur_yuv_buf->y[(iy*2 + 0) * in_stride + ix*2 + 1];
|
||||
y_plane[(hy*2 + 1)*thumbnail_width + (hx*2 + 0)] = b->cur_yuv_buf->y[(iy*2 + 1) * in_stride + ix*2 + 0];
|
||||
y_plane[(hy*2 + 1)*thumbnail_width + (hx*2 + 1)] = b->cur_yuv_buf->y[(iy*2 + 1) * in_stride + ix*2 + 1];
|
||||
u_plane[hy*thumbnail_width/2 + hx] = b->cur_yuv_buf->uv[iy*in_stride + ix*2 + 0];
|
||||
v_plane[hy*thumbnail_width/2 + hx] = b->cur_yuv_buf->uv[iy*in_stride + ix*2 + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
uint8_t *thumbnail_buffer = nullptr;
|
||||
size_t thumbnail_len = 0;
|
||||
jpeg_mem_dest(&cinfo, &thumbnail_buffer, &thumbnail_len);
|
||||
|
||||
cinfo.image_width = thumbnail_width;
|
||||
cinfo.image_height = thumbnail_height;
|
||||
cinfo.input_components = 3;
|
||||
|
||||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_colorspace(&cinfo, JCS_YCbCr);
|
||||
// configure sampling factors for yuv420.
|
||||
cinfo.comp_info[0].h_samp_factor = 2; // Y
|
||||
cinfo.comp_info[0].v_samp_factor = 2;
|
||||
cinfo.comp_info[1].h_samp_factor = 1; // U
|
||||
cinfo.comp_info[1].v_samp_factor = 1;
|
||||
cinfo.comp_info[2].h_samp_factor = 1; // V
|
||||
cinfo.comp_info[2].v_samp_factor = 1;
|
||||
cinfo.raw_data_in = TRUE;
|
||||
|
||||
jpeg_set_quality(&cinfo, 50, TRUE);
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
JSAMPROW y[16], u[8], v[8];
|
||||
JSAMPARRAY planes[3]{y, u, v};
|
||||
|
||||
for (int line = 0; line < cinfo.image_height; line += 16) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
y[i] = y_plane + (line + i) * cinfo.image_width;
|
||||
if (i % 2 == 0) {
|
||||
int offset = (cinfo.image_width / 2) * ((i + line) / 2);
|
||||
u[i / 2] = u_plane + offset;
|
||||
v[i / 2] = v_plane + offset;
|
||||
}
|
||||
}
|
||||
jpeg_write_raw_data(&cinfo, planes, 16);
|
||||
}
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
kj::Array<capnp::byte> dat = kj::heapArray<capnp::byte>(thumbnail_buffer, thumbnail_len);
|
||||
free(thumbnail_buffer);
|
||||
return dat;
|
||||
}
|
||||
|
||||
void publish_thumbnail(PubMaster *pm, const CameraBuf *b) {
|
||||
auto thumbnail = yuv420_to_jpeg(b, b->out_img_width / 4, b->out_img_height / 4);
|
||||
if (thumbnail.size() == 0) return;
|
||||
|
||||
MessageBuilder msg;
|
||||
auto thumbnaild = msg.initEvent().initThumbnail();
|
||||
thumbnaild.setFrameId(b->cur_frame_data.frame_id);
|
||||
thumbnaild.setTimestampEof(b->cur_frame_data.timestamp_eof);
|
||||
thumbnaild.setThumbnail(thumbnail);
|
||||
|
||||
pm->send("thumbnail", msg);
|
||||
}
|
||||
|
||||
float set_exposure_target(const CameraBuf *b, Rect ae_xywh, int x_skip, int y_skip) {
|
||||
int lum_med;
|
||||
uint32_t lum_binning[256] = {0};
|
||||
|
||||
@@ -52,5 +52,4 @@ public:
|
||||
void camerad_thread();
|
||||
kj::Array<uint8_t> get_raw_frame_image(const CameraBuf *b);
|
||||
float set_exposure_target(const CameraBuf *b, Rect ae_xywh, int x_skip, int y_skip);
|
||||
void publish_thumbnail(PubMaster *pm, const CameraBuf *b);
|
||||
int open_v4l_by_name_and_index(const char name[], int index = 0, int flags = O_RDWR | O_NONBLOCK);
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
float fl_pix = 0;
|
||||
|
||||
CameraState(SpectraMaster *master, const CameraConfig &config) : camera(master, config, true /*config.stream_type == VISION_STREAM_ROAD*/) {};
|
||||
CameraState(SpectraMaster *master, const CameraConfig &config) : camera(master, config, config.stream_type == VISION_STREAM_DRIVER ? ISP_BPS_PROCESSED : ISP_IFE_PROCESSED) {};
|
||||
~CameraState();
|
||||
void init(VisionIpcServer *v, cl_device_id device_id, cl_context ctx);
|
||||
void update_exposure_score(float desired_ev, int exp_t, int exp_g_idx, float exp_gain);
|
||||
@@ -231,9 +231,7 @@ void CameraState::set_camera_exposure(float grey_frac) {
|
||||
void CameraState::run() {
|
||||
util::set_thread_name(camera.cc.publish_name);
|
||||
|
||||
std::vector<const char*> pubs = {camera.cc.publish_name};
|
||||
if (camera.cc.stream_type == VISION_STREAM_ROAD) pubs.push_back("thumbnail");
|
||||
PubMaster pm(pubs);
|
||||
PubMaster pm(std::vector{camera.cc.publish_name});
|
||||
|
||||
for (uint32_t cnt = 0; !do_exit; ++cnt) {
|
||||
// Acquire the buffer; continue if acquisition fails
|
||||
@@ -263,17 +261,10 @@ void CameraState::run() {
|
||||
framed.setImage(get_raw_frame_image(&camera.buf));
|
||||
}
|
||||
|
||||
// Process camera registers and set camera exposure
|
||||
if (camera.is_raw) {
|
||||
camera.sensor->processRegisters((uint8_t *)camera.buf.cur_camera_buf->addr, framed);
|
||||
}
|
||||
set_camera_exposure(set_exposure_target(&camera.buf, ae_xywh, 2, camera.cc.stream_type != VISION_STREAM_DRIVER ? 2 : 4));
|
||||
|
||||
// Send the message
|
||||
pm.send(camera.cc.publish_name, msg);
|
||||
if (camera.cc.stream_type == VISION_STREAM_ROAD && cnt % 100 == 3) {
|
||||
publish_thumbnail(&pm, &camera.buf); // this takes 10ms???
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +283,7 @@ void camerad_thread() {
|
||||
|
||||
// *** per-cam init ***
|
||||
std::vector<std::unique_ptr<CameraState>> cams;
|
||||
for (const auto &config : {WIDE_ROAD_CAMERA_CONFIG, DRIVER_CAMERA_CONFIG, ROAD_CAMERA_CONFIG}) {
|
||||
for (const auto &config : {WIDE_ROAD_CAMERA_CONFIG, ROAD_CAMERA_CONFIG, DRIVER_CAMERA_CONFIG}) {
|
||||
auto cam = std::make_unique<CameraState>(&m, config);
|
||||
cam->init(&v, device_id, ctx);
|
||||
cams.emplace_back(std::move(cam));
|
||||
|
||||
@@ -16,6 +16,7 @@ struct CameraConfig {
|
||||
cereal::FrameData::Builder (cereal::Event::Builder::*init_camera_state)();
|
||||
bool enabled;
|
||||
uint32_t phy;
|
||||
bool vignetting_correction;
|
||||
};
|
||||
|
||||
// NOTE: to be able to disable road and wide road, we still have to configure the sensor over i2c
|
||||
@@ -28,6 +29,7 @@ const CameraConfig WIDE_ROAD_CAMERA_CONFIG = {
|
||||
.init_camera_state = &cereal::Event::Builder::initWideRoadCameraState,
|
||||
.enabled = !getenv("DISABLE_WIDE_ROAD"),
|
||||
.phy = CAM_ISP_IFE_IN_RES_PHY_0,
|
||||
.vignetting_correction = false,
|
||||
};
|
||||
|
||||
const CameraConfig ROAD_CAMERA_CONFIG = {
|
||||
@@ -38,6 +40,7 @@ const CameraConfig ROAD_CAMERA_CONFIG = {
|
||||
.init_camera_state = &cereal::Event::Builder::initRoadCameraState,
|
||||
.enabled = !getenv("DISABLE_ROAD"),
|
||||
.phy = CAM_ISP_IFE_IN_RES_PHY_1,
|
||||
.vignetting_correction = true,
|
||||
};
|
||||
|
||||
const CameraConfig DRIVER_CAMERA_CONFIG = {
|
||||
@@ -48,4 +51,5 @@ const CameraConfig DRIVER_CAMERA_CONFIG = {
|
||||
.init_camera_state = &cereal::Event::Builder::initDriverCameraState,
|
||||
.enabled = !getenv("DISABLE_DRIVER"),
|
||||
.phy = CAM_ISP_IFE_IN_RES_PHY_2,
|
||||
.vignetting_correction = false,
|
||||
};
|
||||
@@ -2,13 +2,46 @@
|
||||
|
||||
#include "cdm.h"
|
||||
|
||||
#include "system/camerad/cameras/tici.h"
|
||||
#include "system/camerad/cameras/hw.h"
|
||||
#include "system/camerad/sensors/sensor.h"
|
||||
|
||||
|
||||
int build_update(uint8_t *dst, const SensorInfo *s, std::vector<uint32_t> &patches, int camera_num) {
|
||||
int build_common_ife_bps(uint8_t *dst, const CameraConfig cam, const SensorInfo *s, std::vector<uint32_t> &patches, bool ife) {
|
||||
uint8_t *start = dst;
|
||||
|
||||
/*
|
||||
Common between IFE and BPS.
|
||||
*/
|
||||
|
||||
// IFE -> BPS addresses
|
||||
/*
|
||||
std::map<uint32_t, uint32_t> addrs = {
|
||||
{0xf30, 0x3468},
|
||||
};
|
||||
*/
|
||||
|
||||
// YUV
|
||||
dst += write_cont(dst, ife ? 0xf30 : 0x3468, {
|
||||
0x00680208,
|
||||
0x00000108,
|
||||
0x00400000,
|
||||
0x03ff0000,
|
||||
0x01c01ed8,
|
||||
0x00001f68,
|
||||
0x02000000,
|
||||
0x03ff0000,
|
||||
0x1fb81e88,
|
||||
0x000001c0,
|
||||
0x02000000,
|
||||
0x03ff0000,
|
||||
});
|
||||
|
||||
return dst - start;
|
||||
}
|
||||
|
||||
int build_update(uint8_t *dst, const CameraConfig cam, const SensorInfo *s, std::vector<uint32_t> &patches) {
|
||||
uint8_t *start = dst;
|
||||
|
||||
// init sequence
|
||||
dst += write_random(dst, {
|
||||
0x2c, 0xffffffff,
|
||||
0x30, 0xffffffff,
|
||||
@@ -17,6 +50,7 @@ int build_update(uint8_t *dst, const SensorInfo *s, std::vector<uint32_t> &patch
|
||||
0x3c, 0xffffffff,
|
||||
});
|
||||
|
||||
// demux cfg
|
||||
dst += write_cont(dst, 0x560, {
|
||||
0x00000001,
|
||||
0x04440444,
|
||||
@@ -35,36 +69,29 @@ int build_update(uint8_t *dst, const SensorInfo *s, std::vector<uint32_t> &patch
|
||||
0x00000000,
|
||||
});
|
||||
|
||||
// module config/enables (e.g. enable debayer, white balance, etc.)
|
||||
dst += write_cont(dst, 0x40, {
|
||||
0x00000c06 | ((uint32_t)(camera_num == 1) << 8),
|
||||
0x00000c06 | ((uint32_t)(cam.vignetting_correction) << 8),
|
||||
});
|
||||
|
||||
dst += write_cont(dst, 0x48, {
|
||||
(1 << 3) | (1 << 1),
|
||||
});
|
||||
|
||||
dst += write_cont(dst, 0x4c, {
|
||||
0x00000019,
|
||||
});
|
||||
|
||||
dst += write_cont(dst, 0xe0c, {
|
||||
0x00000e00,
|
||||
});
|
||||
|
||||
dst += write_cont(dst, 0xe2c, {
|
||||
0x00000e00,
|
||||
});
|
||||
|
||||
dst += write_cont(dst, 0x44, {
|
||||
0x00000000,
|
||||
});
|
||||
|
||||
dst += write_cont(dst, 0xaac, {
|
||||
dst += write_cont(dst, 0x48, {
|
||||
(1 << 3) | (1 << 1),
|
||||
});
|
||||
dst += write_cont(dst, 0x4c, {
|
||||
0x00000019,
|
||||
});
|
||||
dst += write_cont(dst, 0xf00, {
|
||||
0x00000000,
|
||||
});
|
||||
|
||||
dst += write_cont(dst, 0xf00, {
|
||||
0x00000000,
|
||||
// cropping
|
||||
dst += write_cont(dst, 0xe0c, {
|
||||
0x00000e00,
|
||||
});
|
||||
dst += write_cont(dst, 0xe2c, {
|
||||
0x00000e00,
|
||||
});
|
||||
|
||||
// black level scale + offset
|
||||
@@ -78,11 +105,11 @@ int build_update(uint8_t *dst, const SensorInfo *s, std::vector<uint32_t> &patch
|
||||
}
|
||||
|
||||
|
||||
int build_initial_config(uint8_t *dst, const SensorInfo *s, std::vector<uint32_t> &patches, int camera_num) {
|
||||
int build_initial_config(uint8_t *dst, const CameraConfig cam, const SensorInfo *s, std::vector<uint32_t> &patches) {
|
||||
uint8_t *start = dst;
|
||||
|
||||
// start with the every frame config
|
||||
dst += build_update(dst, s, patches, camera_num);
|
||||
dst += build_update(dst, cam, s, patches);
|
||||
|
||||
uint64_t addr;
|
||||
|
||||
@@ -115,15 +142,6 @@ int build_initial_config(uint8_t *dst, const SensorInfo *s, std::vector<uint32_t
|
||||
// TODO: this is DMI64 in the dump, does that matter?
|
||||
dst += write_dmi(dst, &addr, s->linearization_lut.size()*sizeof(uint32_t), 0xc24, 9);
|
||||
patches.push_back(addr - (uint64_t)start);
|
||||
/* TODO
|
||||
cdm_dmi_cmd_t 248
|
||||
.length = 287
|
||||
.reserved = 33
|
||||
.cmd = 11
|
||||
.addr = 0
|
||||
.DMIAddr = 3108
|
||||
.DMISel = 9
|
||||
*/
|
||||
|
||||
// vignetting correction
|
||||
dst += write_cont(dst, 0x6bc, {
|
||||
@@ -164,23 +182,7 @@ int build_initial_config(uint8_t *dst, const SensorInfo *s, std::vector<uint32_t
|
||||
dst += write_dmi(dst, &addr, s->gamma_lut_rgb.size()*sizeof(uint32_t), 0xc24, 30); // R
|
||||
patches.push_back(addr - (uint64_t)start);
|
||||
|
||||
// YUV
|
||||
dst += write_cont(dst, 0xf30, {
|
||||
0x00680208,
|
||||
0x00000108,
|
||||
0x00400000,
|
||||
0x03ff0000,
|
||||
0x01c01ed8,
|
||||
0x00001f68,
|
||||
0x02000000,
|
||||
0x03ff0000,
|
||||
0x1fb81e88,
|
||||
0x000001c0,
|
||||
0x02000000,
|
||||
0x03ff0000,
|
||||
});
|
||||
|
||||
// TODO: remove this
|
||||
// output size/scaling
|
||||
dst += write_cont(dst, 0xa3c, {
|
||||
0x00000003,
|
||||
((s->frame_width - 1) << 16) | (s->frame_width - 1),
|
||||
@@ -226,6 +228,8 @@ int build_initial_config(uint8_t *dst, const SensorInfo *s, std::vector<uint32_t
|
||||
0x00000017,
|
||||
});
|
||||
|
||||
dst += build_common_ife_bps(dst, cam, s, patches, true);
|
||||
|
||||
return dst - start;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
#include "common/swaglog.h"
|
||||
#include "system/camerad/cameras/ife.h"
|
||||
#include "system/camerad/cameras/spectra.h"
|
||||
#include "system/camerad/cameras/bps_blobs.h"
|
||||
#include "third_party/linux/include/msm_media_info.h"
|
||||
|
||||
// For debugging:
|
||||
// echo "4294967295" > /sys/module/cam_debug_util/parameters/debug_mdl
|
||||
|
||||
// ************** low level camera helpers ****************
|
||||
|
||||
@@ -194,11 +193,11 @@ void SpectraMaster::init() {
|
||||
// looks like there's only one of these
|
||||
isp_fd = open_v4l_by_name_and_index("cam-isp");
|
||||
assert(isp_fd >= 0);
|
||||
LOGD("opened isp");
|
||||
LOGD("opened isp %d", (int)isp_fd);
|
||||
|
||||
icp_fd = open_v4l_by_name_and_index("cam-icp");
|
||||
assert(icp_fd >= 0);
|
||||
LOGD("opened icp");
|
||||
LOGD("opened icp %d", (int)icp_fd);
|
||||
|
||||
// query ISP for MMU handles
|
||||
LOG("-- Query for MMU handles");
|
||||
@@ -234,14 +233,14 @@ void SpectraMaster::init() {
|
||||
|
||||
// *** SpectraCamera ***
|
||||
|
||||
SpectraCamera::SpectraCamera(SpectraMaster *master, const CameraConfig &config, bool raw)
|
||||
SpectraCamera::SpectraCamera(SpectraMaster *master, const CameraConfig &config, SpectraOutputType out)
|
||||
: m(master),
|
||||
enabled(config.enabled),
|
||||
cc(config),
|
||||
is_raw(raw) {
|
||||
output_type(out) {
|
||||
mm.init(m->video0_fd);
|
||||
|
||||
ife_buf_depth = is_raw ? 4 : VIPC_BUFFER_COUNT;
|
||||
ife_buf_depth = (out != ISP_IFE_PROCESSED) ? 4 : VIPC_BUFFER_COUNT;
|
||||
assert(ife_buf_depth < MAX_IFE_BUFS);
|
||||
}
|
||||
|
||||
@@ -257,11 +256,22 @@ int SpectraCamera::clear_req_queue() {
|
||||
req_mgr_flush_request.link_hdl = link_handle;
|
||||
req_mgr_flush_request.flush_type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
|
||||
int ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_FLUSH_REQ, &req_mgr_flush_request, sizeof(req_mgr_flush_request));
|
||||
// LOGD("flushed all req: %d", ret);
|
||||
LOGD("flushed all req: %d", ret);
|
||||
|
||||
if (icp_dev_handle) {
|
||||
struct cam_flush_dev_cmd cmd = {
|
||||
.session_handle = session_handle,
|
||||
.dev_handle = icp_dev_handle,
|
||||
.flush_type = CAM_FLUSH_TYPE_ALL,
|
||||
};
|
||||
int err = do_cam_control(m->icp_fd, CAM_FLUSH_REQ, &cmd, sizeof(cmd));
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_IFE_BUFS; ++i) {
|
||||
destroySyncObjectAt(i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -279,7 +289,7 @@ void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_c
|
||||
uv_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12, sensor->frame_height);
|
||||
uv_offset = stride*y_height;
|
||||
yuv_size = uv_offset + stride*uv_height;
|
||||
if (!is_raw) {
|
||||
if (output_type != ISP_RAW_OUTPUT) {
|
||||
uv_offset = ALIGNED_SIZE(uv_offset, 0x1000);
|
||||
yuv_size = uv_offset + ALIGNED_SIZE(stride*uv_height, 0x1000);
|
||||
}
|
||||
@@ -288,7 +298,7 @@ void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_c
|
||||
|
||||
open = true;
|
||||
configISP();
|
||||
//configICP(); // needs the new AGNOS kernel
|
||||
if (output_type == ISP_BPS_PROCESSED) configICP();
|
||||
configCSIPHY();
|
||||
linkDevices();
|
||||
|
||||
@@ -300,8 +310,9 @@ void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_c
|
||||
|
||||
void SpectraCamera::enqueue_req_multi(uint64_t start, int n, bool dp) {
|
||||
for (uint64_t i = start; i < start + n; ++i) {
|
||||
request_ids[(i - 1) % ife_buf_depth] = i;
|
||||
enqueue_buffer((i - 1) % ife_buf_depth, dp);
|
||||
uint64_t idx = (i - 1) % ife_buf_depth;
|
||||
request_ids[idx] = i;
|
||||
enqueue_buffer(idx, dp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,22 +465,245 @@ int SpectraCamera::sensors_init() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void add_patch(struct cam_packet *pkt, int32_t dst_hdl, uint32_t dst_offset, int32_t src_hdl, uint32_t src_offset) {
|
||||
void *ptr = (char*)&pkt->payload + pkt->patch_offset;
|
||||
struct cam_patch_desc *p = (struct cam_patch_desc *)((unsigned char*)ptr + sizeof(struct cam_patch_desc)*pkt->num_patches);
|
||||
p->dst_buf_hdl = dst_hdl;
|
||||
p->src_buf_hdl = src_hdl;
|
||||
p->dst_offset = dst_offset;
|
||||
p->src_offset = src_offset;
|
||||
pkt->num_patches++;
|
||||
};
|
||||
|
||||
void SpectraCamera::config_bps(int idx, int request_id) {
|
||||
/*
|
||||
Handles per-frame BPS config.
|
||||
* BPS = Bayer Processing Segment
|
||||
*/
|
||||
(void)idx;
|
||||
(void)request_id;
|
||||
}
|
||||
|
||||
void add_patch(void *ptr, int n, int32_t dst_hdl, uint32_t dst_offset, int32_t src_hdl, uint32_t src_offset) {
|
||||
struct cam_patch_desc *p = (struct cam_patch_desc *)((unsigned char*)ptr + sizeof(struct cam_patch_desc)*n);
|
||||
p->dst_buf_hdl = dst_hdl;
|
||||
p->src_buf_hdl = src_hdl;
|
||||
p->dst_offset = dst_offset;
|
||||
p->src_offset = src_offset;
|
||||
};
|
||||
int size = sizeof(struct cam_packet) + sizeof(struct cam_cmd_buf_desc)*2 + sizeof(struct cam_buf_io_cfg)*2;
|
||||
size += sizeof(struct cam_patch_desc)*9;
|
||||
|
||||
uint32_t cam_packet_handle = 0;
|
||||
auto pkt = mm.alloc<struct cam_packet>(size, &cam_packet_handle);
|
||||
|
||||
pkt->header.op_code = CSLDeviceTypeBPS | CAM_ICP_OPCODE_BPS_UPDATE;
|
||||
pkt->header.request_id = request_id;
|
||||
pkt->header.size = size;
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
uint32_t ptr[2];
|
||||
uint32_t unknown[2];
|
||||
} frames[9];
|
||||
|
||||
uint32_t unknown1;
|
||||
uint32_t unknown2;
|
||||
uint32_t unknown3;
|
||||
uint32_t unknown4;
|
||||
|
||||
uint32_t cdm_addr;
|
||||
uint32_t cdm_size;
|
||||
uint32_t settings_addr;
|
||||
uint32_t striping_addr;
|
||||
uint32_t cdm_addr2;
|
||||
|
||||
uint32_t req_id;
|
||||
uint64_t handle;
|
||||
} bps_tmp;
|
||||
|
||||
typedef struct {
|
||||
uint32_t a;
|
||||
uint32_t n;
|
||||
unsigned base : 32;
|
||||
unsigned unused : 12;
|
||||
unsigned length : 20;
|
||||
uint32_t p;
|
||||
uint32_t u;
|
||||
uint32_t h;
|
||||
uint32_t b;
|
||||
} cdm_tmp;
|
||||
|
||||
// *** cmd buf ***
|
||||
std::vector<uint32_t> patches;
|
||||
struct cam_cmd_buf_desc *buf_desc = (struct cam_cmd_buf_desc *)&pkt->payload;
|
||||
{
|
||||
pkt->num_cmd_buf = 2;
|
||||
pkt->kmd_cmd_buf_index = -1;
|
||||
pkt->kmd_cmd_buf_offset = 0;
|
||||
|
||||
buf_desc[0].meta_data = 0;
|
||||
buf_desc[0].mem_handle = bps_cmd.handle;
|
||||
buf_desc[0].type = CAM_CMD_BUF_FW;
|
||||
buf_desc[0].offset = bps_cmd.aligned_size()*idx;
|
||||
|
||||
buf_desc[0].length = sizeof(bps_tmp) + sizeof(cdm_tmp);
|
||||
buf_desc[0].size = buf_desc[0].length;
|
||||
|
||||
// rest gets patched in
|
||||
bps_tmp *fp = (bps_tmp *)((unsigned char *)bps_cmd.ptr + buf_desc[0].offset);
|
||||
memset(fp, 0, buf_desc[0].length);
|
||||
fp->handle = (uint64_t)icp_dev_handle;
|
||||
fp->cdm_size = bps_cdm_striping_bl.size; // this comes from the striping lib create call
|
||||
fp->req_id = 0; // why always 0?
|
||||
|
||||
cdm_tmp *pa = (cdm_tmp *)((unsigned char *)fp + sizeof(bps_tmp));
|
||||
pa->a = 0;
|
||||
pa->n = 1;
|
||||
pa->p = 20; // GENERIC
|
||||
pa->u = 0;
|
||||
pa->h = 0;
|
||||
pa->b = 0;
|
||||
pa->unused = 0;
|
||||
pa->base = 0; // this gets patched
|
||||
|
||||
int cdm_len = 0;
|
||||
|
||||
if (bps_lin_reg.size() == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
bps_lin_reg.push_back(((sensor->linearization_pts[i] & 0xffff) << 0x10) | (sensor->linearization_pts[i] >> 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (bps_ccm_reg.size() == 0) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
bps_ccm_reg.push_back(sensor->color_correct_matrix[i] | (sensor->color_correct_matrix[i+3] << 0x10));
|
||||
bps_ccm_reg.push_back(sensor->color_correct_matrix[i+6]);
|
||||
}
|
||||
}
|
||||
|
||||
// white balance
|
||||
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x2868, {
|
||||
0x04000400,
|
||||
0x00000400,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
});
|
||||
// debayer
|
||||
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x2878, {
|
||||
0x00000080,
|
||||
0x00800066,
|
||||
});
|
||||
// linearization, EN=0
|
||||
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x1868, bps_lin_reg);
|
||||
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x1878, bps_lin_reg);
|
||||
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x1888, bps_lin_reg);
|
||||
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x1898, bps_lin_reg);
|
||||
/*
|
||||
uint8_t *start = (unsigned char *)bps_cdm_program_array.ptr + cdm_len;
|
||||
uint64_t addr;
|
||||
cdm_len += write_dmi((unsigned char *)bps_cdm_program_array.ptr + cdm_len, &addr, sensor->linearization_lut.size()*sizeof(uint32_t), 0x1808, 1);
|
||||
patches.push_back(addr - (uint64_t)start);
|
||||
*/
|
||||
// color correction
|
||||
cdm_len += write_cont((unsigned char *)bps_cdm_program_array.ptr + cdm_len, 0x2e68, bps_ccm_reg);
|
||||
|
||||
cdm_len += build_common_ife_bps((unsigned char *)bps_cdm_program_array.ptr + cdm_len, cc, sensor.get(), patches, false);
|
||||
|
||||
pa->length = cdm_len - 1;
|
||||
|
||||
// *** second command ***
|
||||
// parsed by cam_icp_packet_generic_blob_handler
|
||||
struct isp_packet {
|
||||
uint32_t header;
|
||||
struct cam_icp_clk_bw_request clk;
|
||||
} __attribute__((packed)) tmp;
|
||||
tmp.header = CAM_ICP_CMD_GENERIC_BLOB_CLK;
|
||||
tmp.header |= (sizeof(cam_icp_clk_bw_request)) << 8;
|
||||
tmp.clk.budget_ns = 0x1fca058;
|
||||
tmp.clk.frame_cycles = 2329024; // comes from the striping lib
|
||||
tmp.clk.rt_flag = 0x0;
|
||||
tmp.clk.uncompressed_bw = 0x38512180;
|
||||
tmp.clk.compressed_bw = 0x38512180;
|
||||
|
||||
buf_desc[1].size = sizeof(tmp);
|
||||
buf_desc[1].offset = 0;
|
||||
buf_desc[1].length = buf_desc[1].size - buf_desc[1].offset;
|
||||
buf_desc[1].type = CAM_CMD_BUF_GENERIC;
|
||||
buf_desc[1].meta_data = CAM_ICP_CMD_META_GENERIC_BLOB;
|
||||
auto buf2 = mm.alloc<uint32_t>(buf_desc[1].size, (uint32_t*)&buf_desc[1].mem_handle);
|
||||
memcpy(buf2.get(), &tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
// *** io config ***
|
||||
pkt->num_io_configs = 2;
|
||||
pkt->io_configs_offset = sizeof(struct cam_cmd_buf_desc)*pkt->num_cmd_buf;
|
||||
struct cam_buf_io_cfg *io_cfg = (struct cam_buf_io_cfg *)((char*)&pkt->payload + pkt->io_configs_offset);
|
||||
{
|
||||
// input frame
|
||||
io_cfg[0].offsets[0] = 0;
|
||||
io_cfg[0].mem_handle[0] = buf_handle_raw[idx];
|
||||
|
||||
io_cfg[0].planes[0] = (struct cam_plane_cfg){
|
||||
.width = sensor->frame_width,
|
||||
.height = sensor->frame_height + sensor->extra_height,
|
||||
.plane_stride = sensor->frame_stride,
|
||||
.slice_height = sensor->frame_height + sensor->extra_height,
|
||||
};
|
||||
io_cfg[0].format = sensor->mipi_format;
|
||||
io_cfg[0].color_space = CAM_COLOR_SPACE_BASE;
|
||||
io_cfg[0].color_pattern = 0x5;
|
||||
io_cfg[0].bpp = (sensor->mipi_format == CAM_FORMAT_MIPI_RAW_10 ? 0xa : 0xc);
|
||||
io_cfg[0].resource_type = CAM_ICP_BPS_INPUT_IMAGE;
|
||||
io_cfg[0].fence = sync_objs_ife[idx];
|
||||
io_cfg[0].direction = CAM_BUF_INPUT;
|
||||
io_cfg[0].subsample_pattern = 0x1;
|
||||
io_cfg[0].framedrop_pattern = 0x1;
|
||||
|
||||
// output frame
|
||||
io_cfg[1].mem_handle[0] = buf_handle_yuv[idx];
|
||||
io_cfg[1].mem_handle[1] = buf_handle_yuv[idx];
|
||||
io_cfg[1].planes[0] = (struct cam_plane_cfg){
|
||||
.width = sensor->frame_width,
|
||||
.height = sensor->frame_height,
|
||||
.plane_stride = stride,
|
||||
.slice_height = y_height,
|
||||
};
|
||||
io_cfg[1].planes[1] = (struct cam_plane_cfg){
|
||||
.width = sensor->frame_width,
|
||||
.height = sensor->frame_height/2,
|
||||
.plane_stride = stride,
|
||||
.slice_height = uv_height,
|
||||
};
|
||||
io_cfg[1].offsets[1] = ALIGNED_SIZE(io_cfg[1].planes[0].plane_stride*io_cfg[1].planes[0].slice_height, 0x1000);
|
||||
assert(io_cfg[1].offsets[1] == uv_offset);
|
||||
|
||||
io_cfg[1].format = CAM_FORMAT_NV12; // TODO: why is this 21 in the dump? should be 12
|
||||
io_cfg[1].color_space = CAM_COLOR_SPACE_BT601_FULL;
|
||||
io_cfg[1].resource_type = CAM_ICP_BPS_OUTPUT_IMAGE_FULL;
|
||||
io_cfg[1].fence = sync_objs_bps[idx];
|
||||
io_cfg[1].direction = CAM_BUF_OUTPUT;
|
||||
io_cfg[1].subsample_pattern = 0x1;
|
||||
io_cfg[1].framedrop_pattern = 0x1;
|
||||
}
|
||||
|
||||
// *** patches ***
|
||||
{
|
||||
assert(patches.size() == 0 | patches.size() == 1);
|
||||
pkt->patch_offset = sizeof(struct cam_cmd_buf_desc)*pkt->num_cmd_buf + sizeof(struct cam_buf_io_cfg)*pkt->num_io_configs;
|
||||
|
||||
if (patches.size() > 0) {
|
||||
add_patch(pkt.get(), bps_cmd.handle, patches[0], bps_linearization_lut.handle, 0);
|
||||
}
|
||||
|
||||
// input frame
|
||||
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[0].ptr[0]), buf_handle_raw[idx], 0);
|
||||
|
||||
// output frame
|
||||
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[1].ptr[0]), buf_handle_yuv[idx], 0);
|
||||
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, frames[1].ptr[1]), buf_handle_yuv[idx], io_cfg[1].offsets[1]);
|
||||
|
||||
// rest of buffers
|
||||
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, settings_addr), bps_iq.handle, 0);
|
||||
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, cdm_addr2), bps_cmd.handle, sizeof(bps_tmp));
|
||||
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + 0xc8, bps_cdm_program_array.handle, 0);
|
||||
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, striping_addr), bps_striping.handle, 0);
|
||||
add_patch(pkt.get(), bps_cmd.handle, buf_desc[0].offset + offsetof(bps_tmp, cdm_addr), bps_cdm_striping_bl.handle, 0);
|
||||
}
|
||||
|
||||
int ret = device_config(m->icp_fd, session_handle, icp_dev_handle, cam_packet_handle);
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
void SpectraCamera::config_ife(int idx, int request_id, bool init) {
|
||||
/*
|
||||
@@ -509,11 +743,12 @@ void SpectraCamera::config_ife(int idx, int request_id, bool init) {
|
||||
buf_desc[0].offset = ife_cmd.aligned_size()*idx;
|
||||
|
||||
// stream of IFE register writes
|
||||
bool is_raw = output_type != ISP_IFE_PROCESSED;
|
||||
if (!is_raw) {
|
||||
if (init) {
|
||||
buf_desc[0].length = build_initial_config((unsigned char*)ife_cmd.ptr + buf_desc[0].offset, sensor.get(), patches, cc.camera_num);
|
||||
buf_desc[0].length = build_initial_config((unsigned char*)ife_cmd.ptr + buf_desc[0].offset, cc, sensor.get(), patches);
|
||||
} else {
|
||||
buf_desc[0].length = build_update((unsigned char*)ife_cmd.ptr + buf_desc[0].offset, sensor.get(), patches, cc.camera_num);
|
||||
buf_desc[0].length = build_update((unsigned char*)ife_cmd.ptr + buf_desc[0].offset, cc, sensor.get(), patches);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,8 +832,7 @@ void SpectraCamera::config_ife(int idx, int request_id, bool init) {
|
||||
pkt->io_configs_offset = sizeof(struct cam_cmd_buf_desc)*pkt->num_cmd_buf;
|
||||
|
||||
struct cam_buf_io_cfg *io_cfg = (struct cam_buf_io_cfg *)((char*)&pkt->payload + pkt->io_configs_offset);
|
||||
|
||||
if (is_raw) {
|
||||
if (output_type != ISP_IFE_PROCESSED) {
|
||||
io_cfg[0].mem_handle[0] = buf_handle_raw[idx];
|
||||
io_cfg[0].planes[0] = (struct cam_plane_cfg){
|
||||
.width = sensor->frame_width,
|
||||
@@ -611,7 +845,7 @@ void SpectraCamera::config_ife(int idx, int request_id, bool init) {
|
||||
io_cfg[0].color_pattern = 0x5;
|
||||
io_cfg[0].bpp = (sensor->mipi_format == CAM_FORMAT_MIPI_RAW_10 ? 0xa : 0xc);
|
||||
io_cfg[0].resource_type = CAM_ISP_IFE_OUT_RES_RDI_0;
|
||||
io_cfg[0].fence = sync_objs[idx];
|
||||
io_cfg[0].fence = sync_objs_ife[idx];
|
||||
io_cfg[0].direction = CAM_BUF_OUTPUT;
|
||||
io_cfg[0].subsample_pattern = 0x1;
|
||||
io_cfg[0].framedrop_pattern = 0x1;
|
||||
@@ -636,7 +870,7 @@ void SpectraCamera::config_ife(int idx, int request_id, bool init) {
|
||||
io_cfg[0].color_pattern = 0x0;
|
||||
io_cfg[0].bpp = 0;
|
||||
io_cfg[0].resource_type = CAM_ISP_IFE_OUT_RES_FULL;
|
||||
io_cfg[0].fence = sync_objs[idx];
|
||||
io_cfg[0].fence = sync_objs_ife[idx];
|
||||
io_cfg[0].direction = CAM_BUF_OUTPUT;
|
||||
io_cfg[0].subsample_pattern = 0x1;
|
||||
io_cfg[0].framedrop_pattern = 0x1;
|
||||
@@ -649,21 +883,18 @@ void SpectraCamera::config_ife(int idx, int request_id, bool init) {
|
||||
// order here corresponds to the one in build_initial_config
|
||||
assert(patches.size() == 6 || patches.size() == 0);
|
||||
|
||||
pkt->num_patches = patches.size();
|
||||
pkt->patch_offset = sizeof(struct cam_cmd_buf_desc)*pkt->num_cmd_buf + sizeof(struct cam_buf_io_cfg)*pkt->num_io_configs;
|
||||
if (pkt->num_patches > 0) {
|
||||
void *p = (char*)&pkt->payload + pkt->patch_offset;
|
||||
|
||||
if (patches.size() > 0) {
|
||||
// linearization LUT
|
||||
add_patch(p, 0, ife_cmd.handle, patches[0], ife_linearization_lut.handle, 0);
|
||||
add_patch(pkt.get(), ife_cmd.handle, patches[0], ife_linearization_lut.handle, 0);
|
||||
|
||||
// vignetting correction LUTs
|
||||
add_patch(p, 1, ife_cmd.handle, patches[1], ife_vignetting_lut.handle, 0);
|
||||
add_patch(p, 2, ife_cmd.handle, patches[2], ife_vignetting_lut.handle, ife_vignetting_lut.size);
|
||||
add_patch(pkt.get(), ife_cmd.handle, patches[1], ife_vignetting_lut.handle, 0);
|
||||
add_patch(pkt.get(), ife_cmd.handle, patches[2], ife_vignetting_lut.handle, ife_vignetting_lut.size);
|
||||
|
||||
// gamma LUTs
|
||||
for (int i = 0; i < 3; i++) {
|
||||
add_patch(p, i+3, ife_cmd.handle, patches[i+3], ife_gamma_lut.handle, ife_gamma_lut.size*i);
|
||||
add_patch(pkt.get(), ife_cmd.handle, patches[i+3], ife_gamma_lut.handle, ife_gamma_lut.size*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -676,23 +907,46 @@ void SpectraCamera::enqueue_buffer(int i, bool dp) {
|
||||
int ret;
|
||||
uint64_t request_id = request_ids[i];
|
||||
|
||||
if (sync_objs[i]) {
|
||||
// SOF has come in, wait until readout is complete
|
||||
// Before queuing up a new frame, wait for the
|
||||
// previous one in this slot (index) to come in.
|
||||
if (sync_objs_ife[i]) {
|
||||
// TODO: write a test to stress test w/ a low timeout and check camera frame ids match
|
||||
|
||||
struct cam_sync_wait sync_wait = {0};
|
||||
sync_wait.sync_obj = sync_objs[i];
|
||||
|
||||
// *** Wait for IFE ***
|
||||
// in RAW_OUTPUT mode, this is just the frame readout from the sensor
|
||||
// in IFE_PROCESSED mode, this is both frame readout and image processing (~1ms)
|
||||
sync_wait.sync_obj = sync_objs_ife[i];
|
||||
sync_wait.timeout_ms = 100;
|
||||
ret = do_sync_control(m->cam_sync_fd, CAM_SYNC_WAIT, &sync_wait, sizeof(sync_wait));
|
||||
if (ret != 0) {
|
||||
// TODO: handle frame drop cleanly
|
||||
// when this happens, it messes up future frames
|
||||
LOGE("failed to wait for sync: %d %d", ret, sync_wait.sync_obj);
|
||||
LOGE("failed to wait for IFE sync: %d %d", ret, sync_wait.sync_obj);
|
||||
}
|
||||
buf.frame_metadata[i].timestamp_end_of_isp = (uint64_t)nanos_since_boot();
|
||||
|
||||
// *** Wait for BPS ***
|
||||
if (ret == 0 && sync_objs_bps[i]) {
|
||||
sync_wait.sync_obj = sync_objs_bps[i];
|
||||
sync_wait.timeout_ms = 50; // typically 7ms
|
||||
ret = do_sync_control(m->cam_sync_fd, CAM_SYNC_WAIT, &sync_wait, sizeof(sync_wait));
|
||||
if (ret != 0) {
|
||||
LOGE("failed to wait for BPS sync: %d %d", ret, sync_wait.sync_obj);
|
||||
}
|
||||
}
|
||||
|
||||
// in IFE_PROCESSED mode, we can't know the true EOF, so recover it with sensor readout time
|
||||
buf.frame_metadata[i].timestamp_eof = buf.frame_metadata[i].timestamp_sof + sensor->readout_time_ns;
|
||||
if (dp) {
|
||||
buf.frame_metadata[i].timestamp_end_of_isp = (uint64_t)nanos_since_boot();
|
||||
|
||||
// all good, hand off frame
|
||||
if (dp && ret == 0) {
|
||||
buf.queue(i);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
clear_req_queue();
|
||||
}
|
||||
|
||||
destroySyncObjectAt(i);
|
||||
}
|
||||
|
||||
@@ -703,14 +957,14 @@ void SpectraCamera::enqueue_buffer(int i, bool dp) {
|
||||
if (ret != 0) {
|
||||
LOGE("failed to create fence: %d %d", ret, sync_create.sync_obj);
|
||||
}
|
||||
sync_objs[i] = sync_create.sync_obj;
|
||||
sync_objs_ife[i] = sync_create.sync_obj;
|
||||
|
||||
if (icp_dev_handle > 0) {
|
||||
ret = do_cam_control(m->cam_sync_fd, CAM_SYNC_CREATE, &sync_create, sizeof(sync_create));
|
||||
if (ret != 0) {
|
||||
LOGE("failed to create fence: %d %d", ret, sync_create.sync_obj);
|
||||
}
|
||||
sync_objs_bps_out[i] = sync_create.sync_obj;
|
||||
sync_objs_bps[i] = sync_create.sync_obj;
|
||||
}
|
||||
|
||||
// schedule request with camera request manager
|
||||
@@ -728,7 +982,7 @@ void SpectraCamera::enqueue_buffer(int i, bool dp) {
|
||||
|
||||
// submit request to IFE and BPS
|
||||
config_ife(i, request_id);
|
||||
config_bps(i, request_id);
|
||||
if (output_type == ISP_BPS_PROCESSED) config_bps(i, request_id);
|
||||
}
|
||||
|
||||
void SpectraCamera::destroySyncObjectAt(int index) {
|
||||
@@ -744,14 +998,14 @@ void SpectraCamera::destroySyncObjectAt(int index) {
|
||||
sync_obj = 0; // Reset the sync object to 0
|
||||
};
|
||||
|
||||
destroy_sync_obj(m->cam_sync_fd, sync_objs[index]);
|
||||
destroy_sync_obj(m->cam_sync_fd, sync_objs_bps_out[index]);
|
||||
destroy_sync_obj(m->cam_sync_fd, sync_objs_ife[index]);
|
||||
destroy_sync_obj(m->cam_sync_fd, sync_objs_bps[index]);
|
||||
}
|
||||
|
||||
void SpectraCamera::camera_map_bufs() {
|
||||
int ret;
|
||||
for (int i = 0; i < ife_buf_depth; i++) {
|
||||
// configure ISP to put the image in place
|
||||
// map our VisionIPC bufs into ISP memory
|
||||
struct cam_mem_mgr_map_cmd mem_mgr_map_cmd = {0};
|
||||
mem_mgr_map_cmd.flags = CAM_MEM_FLAG_HW_READ_WRITE;
|
||||
mem_mgr_map_cmd.mmu_hdls[0] = m->device_iommu;
|
||||
@@ -761,14 +1015,16 @@ void SpectraCamera::camera_map_bufs() {
|
||||
mem_mgr_map_cmd.mmu_hdls[1] = m->icp_device_iommu;
|
||||
}
|
||||
|
||||
if (is_raw) {
|
||||
if (output_type != ISP_IFE_PROCESSED) {
|
||||
// RAW bayer images
|
||||
mem_mgr_map_cmd.fd = buf.camera_bufs_raw[i].fd;
|
||||
ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_MAP_BUF, &mem_mgr_map_cmd, sizeof(mem_mgr_map_cmd));
|
||||
assert(ret == 0);
|
||||
LOGD("map buf req: (fd: %d) 0x%x %d", buf.camera_bufs_raw[i].fd, mem_mgr_map_cmd.out.buf_handle, ret);
|
||||
buf_handle_raw[i] = mem_mgr_map_cmd.out.buf_handle;
|
||||
} else {
|
||||
}
|
||||
|
||||
if (output_type != ISP_RAW_OUTPUT) {
|
||||
// final processed images
|
||||
VisionBuf *vb = buf.vipc_server->get_buffer(buf.stream_type, i);
|
||||
mem_mgr_map_cmd.fd = vb->fd;
|
||||
@@ -865,7 +1121,7 @@ void SpectraCamera::configISP() {
|
||||
},
|
||||
};
|
||||
|
||||
if (is_raw) {
|
||||
if (output_type != ISP_IFE_PROCESSED) {
|
||||
in_port_info.line_start = 0;
|
||||
in_port_info.line_stop = sensor->frame_height + sensor->extra_height - 1;
|
||||
in_port_info.height = sensor->frame_height + sensor->extra_height;
|
||||
@@ -890,7 +1146,7 @@ void SpectraCamera::configISP() {
|
||||
ife_cmd.init(m, 67984, 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE,
|
||||
m->device_iommu, m->cdm_iommu, ife_buf_depth);
|
||||
if (!is_raw) {
|
||||
if (output_type == ISP_IFE_PROCESSED) {
|
||||
assert(sensor->gamma_lut_rgb.size() == 64);
|
||||
ife_gamma_lut.init(m, sensor->gamma_lut_rgb.size()*sizeof(uint32_t), 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE,
|
||||
@@ -920,11 +1176,19 @@ void SpectraCamera::configICP() {
|
||||
Configures both the ICP and BPS.
|
||||
*/
|
||||
|
||||
int cfg_handle;
|
||||
|
||||
uint32_t cfg_size = sizeof(bps_cfg[0]) / sizeof(bps_cfg[0][0]);
|
||||
void *cfg = alloc_w_mmu_hdl(m->video0_fd, cfg_size, (uint32_t*)&cfg_handle, 0x1,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_HW_SHARED_ACCESS,
|
||||
m->icp_device_iommu);
|
||||
memcpy(cfg, bps_cfg[sensor->num()], cfg_size);
|
||||
|
||||
struct cam_icp_acquire_dev_info icp_info = {
|
||||
.scratch_mem_size = 0x0,
|
||||
.dev_type = 0x1, // BPS
|
||||
.io_config_cmd_size = 0,
|
||||
.io_config_cmd_handle = 0,
|
||||
.dev_type = CAM_ICP_RES_TYPE_BPS,
|
||||
.io_config_cmd_size = cfg_size,
|
||||
.io_config_cmd_handle = cfg_handle,
|
||||
.secure_mode = 0,
|
||||
.num_out_res = 1,
|
||||
.in_res = (struct cam_icp_res_info){
|
||||
@@ -945,26 +1209,45 @@ void SpectraCamera::configICP() {
|
||||
icp_dev_handle = *h;
|
||||
LOGD("acquire icp dev");
|
||||
|
||||
// BPS CMD buffer
|
||||
unsigned char striping_out[] = "\x00";
|
||||
bps_cmd.init(m, ife_buf_depth*ALIGNED_SIZE(464, 0x20), 0x20,
|
||||
release(m->video0_fd, cfg_handle);
|
||||
|
||||
// BPS has a lot of buffers to init
|
||||
bps_cmd.init(m, 464, 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE | CAM_MEM_FLAG_HW_SHARED_ACCESS,
|
||||
m->icp_device_iommu);
|
||||
m->icp_device_iommu, 0, ife_buf_depth);
|
||||
|
||||
bps_iq.init(m, 560, 0x20,
|
||||
// BPSIQSettings struct
|
||||
uint32_t settings_size = sizeof(bps_settings[0]) / sizeof(bps_settings[0][0]);
|
||||
bps_iq.init(m, settings_size, 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE | CAM_MEM_FLAG_HW_SHARED_ACCESS,
|
||||
m->icp_device_iommu);
|
||||
bps_cdm_program_array.init(m, 0x40, 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE | CAM_MEM_FLAG_HW_SHARED_ACCESS,
|
||||
m->icp_device_iommu);
|
||||
bps_striping.init(m, sizeof(striping_out), 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE | CAM_MEM_FLAG_HW_SHARED_ACCESS,
|
||||
m->icp_device_iommu);
|
||||
memcpy(bps_striping.ptr, striping_out, sizeof(striping_out));
|
||||
memcpy(bps_iq.ptr, bps_settings[sensor->num()], settings_size);
|
||||
|
||||
bps_cdm_striping_bl.init(m, 65216, 0x20,
|
||||
// for cdm register writes, just make it bigger than you need
|
||||
bps_cdm_program_array.init(m, 0x1000, 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE | CAM_MEM_FLAG_HW_SHARED_ACCESS,
|
||||
m->icp_device_iommu);
|
||||
|
||||
// striping lib output
|
||||
uint32_t striping_size = sizeof(bps_striping_output[0]) / sizeof(bps_striping_output[0][0]);
|
||||
bps_striping.init(m, striping_size, 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE | CAM_MEM_FLAG_HW_SHARED_ACCESS,
|
||||
m->icp_device_iommu);
|
||||
memcpy(bps_striping.ptr, bps_striping_output[sensor->num()], striping_size);
|
||||
|
||||
// used internally by the BPS, we just allocate it.
|
||||
// size comes from the BPSStripingLib
|
||||
bps_cdm_striping_bl.init(m, 0xa100, 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE | CAM_MEM_FLAG_HW_SHARED_ACCESS,
|
||||
m->icp_device_iommu);
|
||||
|
||||
// LUTs
|
||||
/*
|
||||
bps_linearization_lut.init(m, sensor->linearization_lut.size()*sizeof(uint32_t), 0x20,
|
||||
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE | CAM_MEM_FLAG_HW_SHARED_ACCESS,
|
||||
m->icp_device_iommu);
|
||||
memcpy(bps_linearization_lut.ptr, sensor->linearization_lut.data(), bps_linearization_lut.size);
|
||||
*/
|
||||
}
|
||||
|
||||
void SpectraCamera::configCSIPHY() {
|
||||
@@ -1015,6 +1298,7 @@ void SpectraCamera::linkDevices() {
|
||||
req_mgr_link_info.dev_hdls[0] = isp_dev_handle;
|
||||
req_mgr_link_info.dev_hdls[1] = sensor_dev_handle;
|
||||
int ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_LINK, &req_mgr_link_info, sizeof(req_mgr_link_info));
|
||||
assert(ret == 0);
|
||||
link_handle = req_mgr_link_info.link_hdl;
|
||||
LOGD("link: %d session: 0x%X isp: 0x%X sensors: 0x%X link: 0x%X", ret, session_handle, isp_dev_handle, sensor_dev_handle, link_handle);
|
||||
|
||||
@@ -1028,9 +1312,15 @@ void SpectraCamera::linkDevices() {
|
||||
|
||||
ret = device_control(csiphy_fd, CAM_START_DEV, session_handle, csiphy_dev_handle);
|
||||
LOGD("start csiphy: %d", ret);
|
||||
assert(ret == 0);
|
||||
ret = device_control(m->isp_fd, CAM_START_DEV, session_handle, isp_dev_handle);
|
||||
LOGD("start isp: %d", ret);
|
||||
assert(ret == 0);
|
||||
if (output_type == ISP_BPS_PROCESSED) {
|
||||
ret = device_control(m->icp_fd, CAM_START_DEV, session_handle, icp_dev_handle);
|
||||
LOGD("start icp: %d", ret);
|
||||
assert(ret == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void SpectraCamera::camera_close() {
|
||||
@@ -1041,8 +1331,13 @@ void SpectraCamera::camera_close() {
|
||||
// LOGD("stop sensor: %d", ret);
|
||||
int ret = device_control(m->isp_fd, CAM_STOP_DEV, session_handle, isp_dev_handle);
|
||||
LOGD("stop isp: %d", ret);
|
||||
if (output_type == ISP_BPS_PROCESSED) {
|
||||
ret = device_control(m->icp_fd, CAM_STOP_DEV, session_handle, icp_dev_handle);
|
||||
LOGD("stop icp: %d", ret);
|
||||
}
|
||||
ret = device_control(csiphy_fd, CAM_STOP_DEV, session_handle, csiphy_dev_handle);
|
||||
LOGD("stop csiphy: %d", ret);
|
||||
|
||||
// link control stop
|
||||
LOG("-- Stop link control");
|
||||
struct cam_req_mgr_link_control req_mgr_link_control = {0};
|
||||
@@ -1063,17 +1358,22 @@ void SpectraCamera::camera_close() {
|
||||
|
||||
// release devices
|
||||
LOGD("-- Release devices");
|
||||
if (icp_dev_handle > 0) {
|
||||
ret = device_control(m->isp_fd, CAM_RELEASE_DEV, session_handle, isp_dev_handle);
|
||||
LOGD("release isp: %d", ret);
|
||||
if (output_type == ISP_BPS_PROCESSED) {
|
||||
ret = device_control(m->icp_fd, CAM_RELEASE_DEV, session_handle, icp_dev_handle);
|
||||
LOGD("release icp: %d", ret);
|
||||
}
|
||||
ret = device_control(m->isp_fd, CAM_RELEASE_DEV, session_handle, isp_dev_handle);
|
||||
LOGD("release isp: %d", ret);
|
||||
ret = device_control(csiphy_fd, CAM_RELEASE_DEV, session_handle, csiphy_dev_handle);
|
||||
LOGD("release csiphy: %d", ret);
|
||||
|
||||
for (int i = 0; i < ife_buf_depth; i++) {
|
||||
release(m->video0_fd, is_raw ? buf_handle_raw[i] : buf_handle_yuv[i]);
|
||||
if (buf_handle_raw[i]) {
|
||||
release(m->video0_fd, buf_handle_raw[i]);
|
||||
}
|
||||
if (buf_handle_yuv[i]) {
|
||||
release(m->video0_fd, buf_handle_yuv[i]);
|
||||
}
|
||||
}
|
||||
LOGD("released buffers");
|
||||
}
|
||||
@@ -1095,7 +1395,9 @@ void SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) {
|
||||
uint64_t real_id = event_data->u.frame_msg.request_id;
|
||||
|
||||
if (real_id != 0) { // next ready
|
||||
if (real_id == 1) {idx_offset = main_id;}
|
||||
if (real_id == 1) {
|
||||
idx_offset = main_id;
|
||||
}
|
||||
int buf_idx = (real_id - 1) % ife_buf_depth;
|
||||
|
||||
// check for skipped frames
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "media/cam_req_mgr.h"
|
||||
|
||||
#include "common/util.h"
|
||||
#include "system/camerad/cameras/tici.h"
|
||||
#include "system/camerad/cameras/hw.h"
|
||||
#include "system/camerad/cameras/camera_common.h"
|
||||
#include "system/camerad/sensors/sensor.h"
|
||||
|
||||
@@ -29,6 +29,12 @@ const int MIPI_SETTLE_CNT = 33; // Calculated by camera_freqs.py
|
||||
#define OpcodesIFEInitialConfig 0x0
|
||||
#define OpcodesIFEUpdate 0x1
|
||||
|
||||
typedef enum {
|
||||
ISP_RAW_OUTPUT, // raw frame from sensor
|
||||
ISP_IFE_PROCESSED, // fully processed image through the IFE
|
||||
ISP_BPS_PROCESSED, // fully processed image through the BPS
|
||||
} SpectraOutputType;
|
||||
|
||||
std::optional<int32_t> device_acquire(int fd, int32_t session_handle, void *data, uint32_t num_resources=1);
|
||||
int device_config(int fd, int32_t session_handle, int32_t dev_handle, uint64_t packet_handle);
|
||||
int device_control(int fd, int op_code, int session_handle, int dev_handle);
|
||||
@@ -103,7 +109,7 @@ public:
|
||||
|
||||
class SpectraCamera {
|
||||
public:
|
||||
SpectraCamera(SpectraMaster *master, const CameraConfig &config, bool raw);
|
||||
SpectraCamera(SpectraMaster *master, const CameraConfig &config, SpectraOutputType out);
|
||||
~SpectraCamera();
|
||||
|
||||
void camera_open(VisionIpcServer *v, cl_device_id device_id, cl_context ctx);
|
||||
@@ -166,18 +172,21 @@ public:
|
||||
SpectraBuf bps_cdm_striping_bl;
|
||||
SpectraBuf bps_iq;
|
||||
SpectraBuf bps_striping;
|
||||
SpectraBuf bps_linearization_lut;
|
||||
std::vector<uint32_t> bps_lin_reg;
|
||||
std::vector<uint32_t> bps_ccm_reg;
|
||||
|
||||
int buf_handle_yuv[MAX_IFE_BUFS] = {};
|
||||
int buf_handle_raw[MAX_IFE_BUFS] = {};
|
||||
int sync_objs[MAX_IFE_BUFS] = {};
|
||||
int sync_objs_bps_out[MAX_IFE_BUFS] = {};
|
||||
int sync_objs_ife[MAX_IFE_BUFS] = {};
|
||||
int sync_objs_bps[MAX_IFE_BUFS] = {};
|
||||
uint64_t request_ids[MAX_IFE_BUFS] = {};
|
||||
uint64_t request_id_last = 0;
|
||||
uint64_t frame_id_last = 0;
|
||||
uint64_t idx_offset = 0;
|
||||
bool skipped = true;
|
||||
|
||||
bool is_raw;
|
||||
SpectraOutputType output_type;
|
||||
|
||||
CameraBuf buf;
|
||||
MemoryManager mm;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
#include "common/swaglog.h"
|
||||
#include "system/camerad/sensors/sensor.h"
|
||||
|
||||
namespace {
|
||||
@@ -16,64 +15,6 @@ const float sensor_analog_gains_AR0231[] = {
|
||||
5.0 / 4.0, 6.0 / 4.0, 6.0 / 3.0, 7.0 / 3.0, // 8, 9, 10, 11
|
||||
7.0 / 2.0, 8.0 / 2.0, 8.0 / 1.0}; // 12, 13, 14, 15 = bypass
|
||||
|
||||
std::map<uint16_t, std::pair<int, int>> ar0231_build_register_lut(const AR0231 *s, uint8_t *data) {
|
||||
// This function builds a lookup table from register address, to a pair of indices in the
|
||||
// buffer where to read this address. The buffer contains padding bytes,
|
||||
// as well as markers to indicate the type of the next byte.
|
||||
//
|
||||
// 0xAA is used to indicate the MSB of the address, 0xA5 for the LSB of the address.
|
||||
// Every byte of data (MSB and LSB) is preceded by 0x5A. Specifying an address is optional
|
||||
// for contiguous ranges. See page 27-29 of the AR0231 Developer guide for more information.
|
||||
|
||||
int max_i[] = {1828 / 2 * 3, 1500 / 2 * 3};
|
||||
auto get_next_idx = [](int cur_idx) {
|
||||
return (cur_idx % 3 == 1) ? cur_idx + 2 : cur_idx + 1; // Every third byte is padding
|
||||
};
|
||||
|
||||
std::map<uint16_t, std::pair<int, int>> registers;
|
||||
for (int register_row = 0; register_row < 2; register_row++) {
|
||||
uint8_t *registers_raw = data + s->frame_stride * register_row;
|
||||
assert(registers_raw[0] == 0x0a); // Start of line
|
||||
|
||||
int value_tag_count = 0;
|
||||
int first_val_idx = 0;
|
||||
uint16_t cur_addr = 0;
|
||||
|
||||
for (int i = 1; i <= max_i[register_row]; i = get_next_idx(get_next_idx(i))) {
|
||||
int val_idx = get_next_idx(i);
|
||||
|
||||
uint8_t tag = registers_raw[i];
|
||||
uint16_t val = registers_raw[val_idx];
|
||||
|
||||
if (tag == 0xAA) { // Register MSB tag
|
||||
cur_addr = val << 8;
|
||||
} else if (tag == 0xA5) { // Register LSB tag
|
||||
cur_addr |= val;
|
||||
cur_addr -= 2; // Next value tag will increment address again
|
||||
} else if (tag == 0x5A) { // Value tag
|
||||
|
||||
// First tag
|
||||
if (value_tag_count % 2 == 0) {
|
||||
cur_addr += 2;
|
||||
first_val_idx = val_idx;
|
||||
} else {
|
||||
registers[cur_addr] = std::make_pair(first_val_idx + s->frame_stride * register_row, val_idx + s->frame_stride * register_row);
|
||||
}
|
||||
|
||||
value_tag_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return registers;
|
||||
}
|
||||
|
||||
float ar0231_parse_temp_sensor(uint16_t calib1, uint16_t calib2, uint16_t data_reg) {
|
||||
// See AR0231 Developer Guide - page 36
|
||||
float slope = (125.0 - 55.0) / ((float)calib1 - (float)calib2);
|
||||
float t0 = 55.0 - slope * (float)calib2;
|
||||
return t0 + slope * (float)data_reg;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AR0231::AR0231() {
|
||||
@@ -169,33 +110,6 @@ AR0231::AR0231() {
|
||||
};
|
||||
}
|
||||
|
||||
void AR0231::processRegisters(uint8_t *cur_buf, cereal::FrameData::Builder &framed) const {
|
||||
const uint8_t expected_preamble[] = {0x0a, 0xaa, 0x55, 0x20, 0xa5, 0x55};
|
||||
uint8_t *data = cur_buf + registers_offset;
|
||||
|
||||
if (memcmp(data, expected_preamble, std::size(expected_preamble)) != 0) {
|
||||
LOGE("unexpected register data found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ar0231_register_lut.empty()) {
|
||||
ar0231_register_lut = ar0231_build_register_lut(this, data);
|
||||
}
|
||||
std::map<uint16_t, uint16_t> registers;
|
||||
for (uint16_t addr : {0x2000, 0x2002, 0x20b0, 0x20b2, 0x30c6, 0x30c8, 0x30ca, 0x30cc}) {
|
||||
auto offset = ar0231_register_lut[addr];
|
||||
registers[addr] = ((uint16_t)data[offset.first] << 8) | data[offset.second];
|
||||
}
|
||||
|
||||
uint32_t frame_id = ((uint32_t)registers[0x2000] << 16) | registers[0x2002];
|
||||
framed.setFrameIdSensor(frame_id);
|
||||
|
||||
float temp_0 = ar0231_parse_temp_sensor(registers[0x30c6], registers[0x30c8], registers[0x20b0]);
|
||||
float temp_1 = ar0231_parse_temp_sensor(registers[0x30ca], registers[0x30cc], registers[0x20b2]);
|
||||
framed.setTemperaturesC({temp_0, temp_1});
|
||||
}
|
||||
|
||||
|
||||
std::vector<i2c_random_wr_payload> AR0231::getExposureRegisters(int exposure_time, int new_exp_g, bool dc_gain_enabled) const {
|
||||
uint16_t analog_gain_reg = 0xFF00 | (new_exp_g << 4) | new_exp_g;
|
||||
return {
|
||||
|
||||
@@ -22,7 +22,6 @@ public:
|
||||
virtual std::vector<i2c_random_wr_payload> getExposureRegisters(int exposure_time, int new_exp_g, bool dc_gain_enabled) const { return {}; }
|
||||
virtual float getExposureScore(float desired_ev, int exp_t, int exp_g_idx, float exp_gain, int gain_idx) const {return 0; }
|
||||
virtual int getSlaveAddress(int port) const { assert(0); }
|
||||
virtual void processRegisters(uint8_t *cur_buf, cereal::FrameData::Builder &framed) const {}
|
||||
|
||||
cereal::FrameData::ImageSensor image_sensor = cereal::FrameData::ImageSensor::UNKNOWN;
|
||||
float pixel_size_mm;
|
||||
@@ -82,6 +81,10 @@ public:
|
||||
std::vector<uint32_t> linearization_lut; // length 36
|
||||
std::vector<uint32_t> linearization_pts; // length 4
|
||||
std::vector<uint32_t> vignetting_lut; // length 221
|
||||
|
||||
const int num() const {
|
||||
return static_cast<int>(image_sensor);
|
||||
};
|
||||
};
|
||||
|
||||
class AR0231 : public SensorInfo {
|
||||
@@ -90,7 +93,6 @@ public:
|
||||
std::vector<i2c_random_wr_payload> getExposureRegisters(int exposure_time, int new_exp_g, bool dc_gain_enabled) const override;
|
||||
float getExposureScore(float desired_ev, int exp_t, int exp_g_idx, float exp_gain, int gain_idx) const override;
|
||||
int getSlaveAddress(int port) const override;
|
||||
void processRegisters(uint8_t *cur_buf, cereal::FrameData::Builder &framed) const override;
|
||||
|
||||
private:
|
||||
mutable std::map<uint16_t, std::pair<int, int>> ar0231_register_lut;
|
||||
|
||||
@@ -5,7 +5,7 @@ set -e
|
||||
|
||||
# no CCI and UTIL, very spammy
|
||||
echo 0xfffdbfff | sudo tee /sys/module/cam_debug_util/parameters/debug_mdl
|
||||
echo 0 | sudo tee /sys/module/cam_debug_util/parameters/debug_mdl
|
||||
#echo 0 | sudo tee /sys/module/cam_debug_util/parameters/debug_mdl
|
||||
|
||||
sudo dmesg -C
|
||||
scons -u -j8 --minimal .
|
||||
|
||||
@@ -1,24 +1,4 @@
|
||||
[
|
||||
{
|
||||
"name": "boot",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/boot-5679a04c7cb08ab2f6bdb26b7f807d2a5819d2055151a9d3c89e65c7f24a85d8.img.xz",
|
||||
"hash": "5679a04c7cb08ab2f6bdb26b7f807d2a5819d2055151a9d3c89e65c7f24a85d8",
|
||||
"hash_raw": "5679a04c7cb08ab2f6bdb26b7f807d2a5819d2055151a9d3c89e65c7f24a85d8",
|
||||
"size": 16422912,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true
|
||||
},
|
||||
{
|
||||
"name": "system",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/system-5a11d6b2588ddb562b69cf2c27d7a8feae2ef0693f73a01cf6536b2cd9a09a29.img.xz",
|
||||
"hash": "5a11d6b2588ddb562b69cf2c27d7a8feae2ef0693f73a01cf6536b2cd9a09a29",
|
||||
"hash_raw": "5a11d6b2588ddb562b69cf2c27d7a8feae2ef0693f73a01cf6536b2cd9a09a29",
|
||||
"size": 4404019200,
|
||||
"sparse": false,
|
||||
"full_check": false,
|
||||
"has_ab": true
|
||||
},
|
||||
{
|
||||
"name": "xbl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl-468f1ad6ab55e198647ff9191f91bd2918db9c0a3e27bae5673b4c5575c1254c.img.xz",
|
||||
@@ -27,17 +7,8 @@
|
||||
"size": 3282256,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true
|
||||
},
|
||||
{
|
||||
"name": "abl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz",
|
||||
"hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||
"hash_raw": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||
"size": 274432,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "d35a86e7b8ddd9279b513a6f27da1521aa0f89fb93987ea74d57d0f0bbbbd247"
|
||||
},
|
||||
{
|
||||
"name": "xbl_config",
|
||||
@@ -47,17 +18,19 @@
|
||||
"size": 98124,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "623f1568072ee2d687ba8449a3d894c1c83dc4131b2e79eff35696885f70a419"
|
||||
},
|
||||
{
|
||||
"name": "devcfg",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-225b24ea7b1d2fee7f7d2da21386920ddacac2e33e9e938168436292f4eae180.img.xz",
|
||||
"hash": "225b24ea7b1d2fee7f7d2da21386920ddacac2e33e9e938168436292f4eae180",
|
||||
"hash_raw": "225b24ea7b1d2fee7f7d2da21386920ddacac2e33e9e938168436292f4eae180",
|
||||
"size": 40336,
|
||||
"name": "abl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz",
|
||||
"hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||
"hash_raw": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||
"size": 274432,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6"
|
||||
},
|
||||
{
|
||||
"name": "aop",
|
||||
@@ -67,6 +40,45 @@
|
||||
"size": 184364,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "bf74feca486f650589f6b7c90eab73274e35a68b5e00bfc1de0ed5f5484d4b3d"
|
||||
},
|
||||
{
|
||||
"name": "devcfg",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-225b24ea7b1d2fee7f7d2da21386920ddacac2e33e9e938168436292f4eae180.img.xz",
|
||||
"hash": "225b24ea7b1d2fee7f7d2da21386920ddacac2e33e9e938168436292f4eae180",
|
||||
"hash_raw": "225b24ea7b1d2fee7f7d2da21386920ddacac2e33e9e938168436292f4eae180",
|
||||
"size": 40336,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "70f682b59ca0fe2f197d1486bd8be7b9b7e560798ad40ddef83b9f0a2f497938"
|
||||
},
|
||||
{
|
||||
"name": "boot",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/boot-c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170.img.xz",
|
||||
"hash": "c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170",
|
||||
"hash_raw": "c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170",
|
||||
"size": 18475008,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "6a9a71bf01f2013f35bda9594cefe3cb4a3835402a6cb0e95306fe4decf261c5"
|
||||
},
|
||||
{
|
||||
"name": "system",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/system-cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625.img.xz",
|
||||
"hash": "990ff7005a5bee8e759c96ddba23f1258f043fb038cf74083bf7d2d9c9a29e39",
|
||||
"hash_raw": "cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625",
|
||||
"size": 4404019200,
|
||||
"sparse": true,
|
||||
"full_check": false,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "d922fffe1b5f02898465a2d6625294abb70d22643ebf2d6a94f5d7512291d1a4",
|
||||
"alt": {
|
||||
"hash": "cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/system-cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625.img",
|
||||
"size": 4404019200
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,400 @@
|
||||
[
|
||||
{
|
||||
"name": "gpt_main_0",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/gpt_main_0-8928a31fd9ee20f8703649f89833eba9b55e84b6415e67799c777b163c95a0bd.img.xz",
|
||||
"hash": "8928a31fd9ee20f8703649f89833eba9b55e84b6415e67799c777b163c95a0bd",
|
||||
"hash_raw": "8928a31fd9ee20f8703649f89833eba9b55e84b6415e67799c777b163c95a0bd",
|
||||
"size": 24576,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "8928a31fd9ee20f8703649f89833eba9b55e84b6415e67799c777b163c95a0bd",
|
||||
"gpt": {
|
||||
"lun": 0,
|
||||
"start_sector": 0,
|
||||
"num_sectors": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gpt_main_1",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/gpt_main_1-fe8ef7653db588d7420a625920ca06927dfcb0ed8aff3e3a1c74a52a24398ba6.img.xz",
|
||||
"hash": "fe8ef7653db588d7420a625920ca06927dfcb0ed8aff3e3a1c74a52a24398ba6",
|
||||
"hash_raw": "fe8ef7653db588d7420a625920ca06927dfcb0ed8aff3e3a1c74a52a24398ba6",
|
||||
"size": 24576,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "fe8ef7653db588d7420a625920ca06927dfcb0ed8aff3e3a1c74a52a24398ba6",
|
||||
"gpt": {
|
||||
"lun": 1,
|
||||
"start_sector": 0,
|
||||
"num_sectors": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gpt_main_2",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/gpt_main_2-5ccfc7240c8cbfa2f1a018a2e376cf274a6baf858c9bfe71951d8e28cab53c21.img.xz",
|
||||
"hash": "5ccfc7240c8cbfa2f1a018a2e376cf274a6baf858c9bfe71951d8e28cab53c21",
|
||||
"hash_raw": "5ccfc7240c8cbfa2f1a018a2e376cf274a6baf858c9bfe71951d8e28cab53c21",
|
||||
"size": 24576,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "5ccfc7240c8cbfa2f1a018a2e376cf274a6baf858c9bfe71951d8e28cab53c21",
|
||||
"gpt": {
|
||||
"lun": 2,
|
||||
"start_sector": 0,
|
||||
"num_sectors": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gpt_main_3",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/gpt_main_3-c707979fa21e89519328f4f30c2b21c9c453401ca8303f914c1873d410a95159.img.xz",
|
||||
"hash": "c707979fa21e89519328f4f30c2b21c9c453401ca8303f914c1873d410a95159",
|
||||
"hash_raw": "c707979fa21e89519328f4f30c2b21c9c453401ca8303f914c1873d410a95159",
|
||||
"size": 24576,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "c707979fa21e89519328f4f30c2b21c9c453401ca8303f914c1873d410a95159",
|
||||
"gpt": {
|
||||
"lun": 3,
|
||||
"start_sector": 0,
|
||||
"num_sectors": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gpt_main_4",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/gpt_main_4-e9405dcd785dbe79412184e1894a9c51ab7deb33bb612166c4c42a3d2bf42a0e.img.xz",
|
||||
"hash": "e9405dcd785dbe79412184e1894a9c51ab7deb33bb612166c4c42a3d2bf42a0e",
|
||||
"hash_raw": "e9405dcd785dbe79412184e1894a9c51ab7deb33bb612166c4c42a3d2bf42a0e",
|
||||
"size": 24576,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "e9405dcd785dbe79412184e1894a9c51ab7deb33bb612166c4c42a3d2bf42a0e",
|
||||
"gpt": {
|
||||
"lun": 4,
|
||||
"start_sector": 0,
|
||||
"num_sectors": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "gpt_main_5",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/gpt_main_5-21ae965f05b2fa8d02e04f1eb74718f9779864f6eacdeb859757d6435e8ccce3.img.xz",
|
||||
"hash": "21ae965f05b2fa8d02e04f1eb74718f9779864f6eacdeb859757d6435e8ccce3",
|
||||
"hash_raw": "21ae965f05b2fa8d02e04f1eb74718f9779864f6eacdeb859757d6435e8ccce3",
|
||||
"size": 24576,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "21ae965f05b2fa8d02e04f1eb74718f9779864f6eacdeb859757d6435e8ccce3",
|
||||
"gpt": {
|
||||
"lun": 5,
|
||||
"start_sector": 0,
|
||||
"num_sectors": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "persist",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/persist-9814b07851292f510f3794b767489f38ab379a99f0ea75dc620ad2d3a496d54d.img.xz",
|
||||
"hash": "9814b07851292f510f3794b767489f38ab379a99f0ea75dc620ad2d3a496d54d",
|
||||
"hash_raw": "9814b07851292f510f3794b767489f38ab379a99f0ea75dc620ad2d3a496d54d",
|
||||
"size": 33554432,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "9814b07851292f510f3794b767489f38ab379a99f0ea75dc620ad2d3a496d54d"
|
||||
},
|
||||
{
|
||||
"name": "systemrw",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/systemrw-8ce150ca38ef64a0885fc2fe816e5b63bae8adb4df5d809c5b318e6996366c7e.img.xz",
|
||||
"hash": "8ce150ca38ef64a0885fc2fe816e5b63bae8adb4df5d809c5b318e6996366c7e",
|
||||
"hash_raw": "8ce150ca38ef64a0885fc2fe816e5b63bae8adb4df5d809c5b318e6996366c7e",
|
||||
"size": 16777216,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "8ce150ca38ef64a0885fc2fe816e5b63bae8adb4df5d809c5b318e6996366c7e"
|
||||
},
|
||||
{
|
||||
"name": "cache",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/cache-ebfbaaa2f96dc4e5fea4f126364e5bf5b3b44c12cbc753b62fdd8baab82f70b4.img.xz",
|
||||
"hash": "ebfbaaa2f96dc4e5fea4f126364e5bf5b3b44c12cbc753b62fdd8baab82f70b4",
|
||||
"hash_raw": "ebfbaaa2f96dc4e5fea4f126364e5bf5b3b44c12cbc753b62fdd8baab82f70b4",
|
||||
"size": 134217728,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "ebfbaaa2f96dc4e5fea4f126364e5bf5b3b44c12cbc753b62fdd8baab82f70b4"
|
||||
},
|
||||
{
|
||||
"name": "xbl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl-468f1ad6ab55e198647ff9191f91bd2918db9c0a3e27bae5673b4c5575c1254c.img.xz",
|
||||
"hash": "468f1ad6ab55e198647ff9191f91bd2918db9c0a3e27bae5673b4c5575c1254c",
|
||||
"hash_raw": "468f1ad6ab55e198647ff9191f91bd2918db9c0a3e27bae5673b4c5575c1254c",
|
||||
"size": 3282256,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "d35a86e7b8ddd9279b513a6f27da1521aa0f89fb93987ea74d57d0f0bbbbd247"
|
||||
},
|
||||
{
|
||||
"name": "xbl_config",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-92b675dc2862ed15c732d91d9eb307d7e852e349217db8bee8f8829db543686b.img.xz",
|
||||
"hash": "92b675dc2862ed15c732d91d9eb307d7e852e349217db8bee8f8829db543686b",
|
||||
"hash_raw": "92b675dc2862ed15c732d91d9eb307d7e852e349217db8bee8f8829db543686b",
|
||||
"size": 98124,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "623f1568072ee2d687ba8449a3d894c1c83dc4131b2e79eff35696885f70a419"
|
||||
},
|
||||
{
|
||||
"name": "abl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz",
|
||||
"hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||
"hash_raw": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||
"size": 274432,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6"
|
||||
},
|
||||
{
|
||||
"name": "aop",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/aop-f0fcf7611d0890a72984f15a516dd37fa532dfcb70d428a8406838cf74ce23d5.img.xz",
|
||||
"hash": "f0fcf7611d0890a72984f15a516dd37fa532dfcb70d428a8406838cf74ce23d5",
|
||||
"hash_raw": "f0fcf7611d0890a72984f15a516dd37fa532dfcb70d428a8406838cf74ce23d5",
|
||||
"size": 184364,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "bf74feca486f650589f6b7c90eab73274e35a68b5e00bfc1de0ed5f5484d4b3d"
|
||||
},
|
||||
{
|
||||
"name": "bluetooth",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/bluetooth-9bb766d2d2ce0cc4491664b3010fe1ef62f8ffc1e362d55f78e48c4141f75533.img.xz",
|
||||
"hash": "9bb766d2d2ce0cc4491664b3010fe1ef62f8ffc1e362d55f78e48c4141f75533",
|
||||
"hash_raw": "9bb766d2d2ce0cc4491664b3010fe1ef62f8ffc1e362d55f78e48c4141f75533",
|
||||
"size": 1048576,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "9bb766d2d2ce0cc4491664b3010fe1ef62f8ffc1e362d55f78e48c4141f75533"
|
||||
},
|
||||
{
|
||||
"name": "cmnlib64",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/cmnlib64-1a876bd151bb9635f18719c4a17f953079de6e11d3eaec800968fc75669e0dc3.img.xz",
|
||||
"hash": "1a876bd151bb9635f18719c4a17f953079de6e11d3eaec800968fc75669e0dc3",
|
||||
"hash_raw": "1a876bd151bb9635f18719c4a17f953079de6e11d3eaec800968fc75669e0dc3",
|
||||
"size": 524288,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "1a876bd151bb9635f18719c4a17f953079de6e11d3eaec800968fc75669e0dc3"
|
||||
},
|
||||
{
|
||||
"name": "cmnlib",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/cmnlib-63df823e8a5fae01d66cb2b8c20f0d2ddb5c5f2425e5d0992a64676273ba1c82.img.xz",
|
||||
"hash": "63df823e8a5fae01d66cb2b8c20f0d2ddb5c5f2425e5d0992a64676273ba1c82",
|
||||
"hash_raw": "63df823e8a5fae01d66cb2b8c20f0d2ddb5c5f2425e5d0992a64676273ba1c82",
|
||||
"size": 524288,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "63df823e8a5fae01d66cb2b8c20f0d2ddb5c5f2425e5d0992a64676273ba1c82"
|
||||
},
|
||||
{
|
||||
"name": "devcfg",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-225b24ea7b1d2fee7f7d2da21386920ddacac2e33e9e938168436292f4eae180.img.xz",
|
||||
"hash": "225b24ea7b1d2fee7f7d2da21386920ddacac2e33e9e938168436292f4eae180",
|
||||
"hash_raw": "225b24ea7b1d2fee7f7d2da21386920ddacac2e33e9e938168436292f4eae180",
|
||||
"size": 40336,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "70f682b59ca0fe2f197d1486bd8be7b9b7e560798ad40ddef83b9f0a2f497938"
|
||||
},
|
||||
{
|
||||
"name": "devinfo",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/devinfo-143869c499a7e878fbeab756e9c53074195770cc41d6d0d10e45c043141389a3.img.xz",
|
||||
"hash": "143869c499a7e878fbeab756e9c53074195770cc41d6d0d10e45c043141389a3",
|
||||
"hash_raw": "143869c499a7e878fbeab756e9c53074195770cc41d6d0d10e45c043141389a3",
|
||||
"size": 4096,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "143869c499a7e878fbeab756e9c53074195770cc41d6d0d10e45c043141389a3"
|
||||
},
|
||||
{
|
||||
"name": "dsp",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/dsp-4b15fbd2f45581f1553f33f01649e450b24aa19d5deff2ac7dcb16a534d9c248.img.xz",
|
||||
"hash": "4b15fbd2f45581f1553f33f01649e450b24aa19d5deff2ac7dcb16a534d9c248",
|
||||
"hash_raw": "4b15fbd2f45581f1553f33f01649e450b24aa19d5deff2ac7dcb16a534d9c248",
|
||||
"size": 33554432,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "4b15fbd2f45581f1553f33f01649e450b24aa19d5deff2ac7dcb16a534d9c248"
|
||||
},
|
||||
{
|
||||
"name": "hyp",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/hyp-ff5ece6a4e3d2b4d898c77ffe193fc8bbc8acebe78263996ecf52373d8088927.img.xz",
|
||||
"hash": "ff5ece6a4e3d2b4d898c77ffe193fc8bbc8acebe78263996ecf52373d8088927",
|
||||
"hash_raw": "ff5ece6a4e3d2b4d898c77ffe193fc8bbc8acebe78263996ecf52373d8088927",
|
||||
"size": 524288,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "ff5ece6a4e3d2b4d898c77ffe193fc8bbc8acebe78263996ecf52373d8088927"
|
||||
},
|
||||
{
|
||||
"name": "keymaster",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/keymaster-5c968c76f29b9a4d66fbe57e639bac6b7a2c83b1758e25abbaf5d276b8a6af04.img.xz",
|
||||
"hash": "5c968c76f29b9a4d66fbe57e639bac6b7a2c83b1758e25abbaf5d276b8a6af04",
|
||||
"hash_raw": "5c968c76f29b9a4d66fbe57e639bac6b7a2c83b1758e25abbaf5d276b8a6af04",
|
||||
"size": 524288,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "5c968c76f29b9a4d66fbe57e639bac6b7a2c83b1758e25abbaf5d276b8a6af04"
|
||||
},
|
||||
{
|
||||
"name": "limits",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/limits-94951a0f7aa55fb6cb975535ce4ebbfe6d695f04cb5424677b01c10dfa2e94e1.img.xz",
|
||||
"hash": "94951a0f7aa55fb6cb975535ce4ebbfe6d695f04cb5424677b01c10dfa2e94e1",
|
||||
"hash_raw": "94951a0f7aa55fb6cb975535ce4ebbfe6d695f04cb5424677b01c10dfa2e94e1",
|
||||
"size": 4096,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "94951a0f7aa55fb6cb975535ce4ebbfe6d695f04cb5424677b01c10dfa2e94e1"
|
||||
},
|
||||
{
|
||||
"name": "logfs",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/logfs-b8b5ac87f3d954404fc7ecbdd9ee3b5b0cf5691e5006e6ec55db4c899ff61220.img.xz",
|
||||
"hash": "b8b5ac87f3d954404fc7ecbdd9ee3b5b0cf5691e5006e6ec55db4c899ff61220",
|
||||
"hash_raw": "b8b5ac87f3d954404fc7ecbdd9ee3b5b0cf5691e5006e6ec55db4c899ff61220",
|
||||
"size": 8388608,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "b8b5ac87f3d954404fc7ecbdd9ee3b5b0cf5691e5006e6ec55db4c899ff61220"
|
||||
},
|
||||
{
|
||||
"name": "modem",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/modem-a3d014f0896d77a2df7e5a80a70f43a51a047b9d03cfc675b6f0e31a6ecc4994.img.xz",
|
||||
"hash": "a3d014f0896d77a2df7e5a80a70f43a51a047b9d03cfc675b6f0e31a6ecc4994",
|
||||
"hash_raw": "a3d014f0896d77a2df7e5a80a70f43a51a047b9d03cfc675b6f0e31a6ecc4994",
|
||||
"size": 125829120,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "a3d014f0896d77a2df7e5a80a70f43a51a047b9d03cfc675b6f0e31a6ecc4994"
|
||||
},
|
||||
{
|
||||
"name": "qupfw",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/qupfw-64cc7c29d5d69b04267452b8b4ddba9f4809e68f476fc162ca283f58537afe4a.img.xz",
|
||||
"hash": "64cc7c29d5d69b04267452b8b4ddba9f4809e68f476fc162ca283f58537afe4a",
|
||||
"hash_raw": "64cc7c29d5d69b04267452b8b4ddba9f4809e68f476fc162ca283f58537afe4a",
|
||||
"size": 65536,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "64cc7c29d5d69b04267452b8b4ddba9f4809e68f476fc162ca283f58537afe4a"
|
||||
},
|
||||
{
|
||||
"name": "splash",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/splash-5c61260048f22ede6e6343fabb27f6ff73f9271f4751a01aaf7abf097afc1f08.img.xz",
|
||||
"hash": "5c61260048f22ede6e6343fabb27f6ff73f9271f4751a01aaf7abf097afc1f08",
|
||||
"hash_raw": "5c61260048f22ede6e6343fabb27f6ff73f9271f4751a01aaf7abf097afc1f08",
|
||||
"size": 34226176,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "5c61260048f22ede6e6343fabb27f6ff73f9271f4751a01aaf7abf097afc1f08"
|
||||
},
|
||||
{
|
||||
"name": "storsec",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/storsec-4494d86f68b125fbf2c004c824b1c6dbe71e61a65d2a1cc7db13c553edcb3fce.img.xz",
|
||||
"hash": "4494d86f68b125fbf2c004c824b1c6dbe71e61a65d2a1cc7db13c553edcb3fce",
|
||||
"hash_raw": "4494d86f68b125fbf2c004c824b1c6dbe71e61a65d2a1cc7db13c553edcb3fce",
|
||||
"size": 131072,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "4494d86f68b125fbf2c004c824b1c6dbe71e61a65d2a1cc7db13c553edcb3fce"
|
||||
},
|
||||
{
|
||||
"name": "tz",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/tz-e9443bf187641661bfa6c96702b9ab0156e72fb7482500f8799ba9ee2503cb16.img.xz",
|
||||
"hash": "e9443bf187641661bfa6c96702b9ab0156e72fb7482500f8799ba9ee2503cb16",
|
||||
"hash_raw": "e9443bf187641661bfa6c96702b9ab0156e72fb7482500f8799ba9ee2503cb16",
|
||||
"size": 2097152,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "e9443bf187641661bfa6c96702b9ab0156e72fb7482500f8799ba9ee2503cb16"
|
||||
},
|
||||
{
|
||||
"name": "boot",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/boot-c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170.img.xz",
|
||||
"hash": "c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170",
|
||||
"hash_raw": "c7cba1ce64bf85384241fa063971855c5ffcb4d90a0d07bed4733d46b94d4170",
|
||||
"size": 18475008,
|
||||
"sparse": false,
|
||||
"full_check": true,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "6a9a71bf01f2013f35bda9594cefe3cb4a3835402a6cb0e95306fe4decf261c5"
|
||||
},
|
||||
{
|
||||
"name": "system",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/system-cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625.img.xz",
|
||||
"hash": "990ff7005a5bee8e759c96ddba23f1258f043fb038cf74083bf7d2d9c9a29e39",
|
||||
"hash_raw": "cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625",
|
||||
"size": 4404019200,
|
||||
"sparse": true,
|
||||
"full_check": false,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "d922fffe1b5f02898465a2d6625294abb70d22643ebf2d6a94f5d7512291d1a4",
|
||||
"alt": {
|
||||
"hash": "cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/system-cd03486f6c7333dee21f59af771f9992ea90a9a04271c1506a663d658f391625.img",
|
||||
"size": 4404019200
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "userdata_90",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/userdata_90-554a22697b356cb150c2c803b4cb1de79403849e9be451c844d218d38b5bc236.img.xz",
|
||||
"hash": "4f0a862e3aff4980e697ece63afaef6f9869d013ac2ca4c45193e41089ee4f5c",
|
||||
"hash_raw": "554a22697b356cb150c2c803b4cb1de79403849e9be451c844d218d38b5bc236",
|
||||
"size": 96636764160,
|
||||
"sparse": true,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "5d780092d51c569e6b8a28ab73f4029bcc3517698f496af5801f863c9865060f"
|
||||
},
|
||||
{
|
||||
"name": "userdata_89",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/userdata_89-6045b9a3f1ae6e0ee09b95da039b697ab8d8447cdd0796fa31afa9c7d324ee80.img.xz",
|
||||
"hash": "ba49fef48573e9befdfb6334181753855cb83d3e1d8c6d4d83d510ea0141ec3f",
|
||||
"hash_raw": "6045b9a3f1ae6e0ee09b95da039b697ab8d8447cdd0796fa31afa9c7d324ee80",
|
||||
"size": 95563022336,
|
||||
"sparse": true,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "19b63b184063c25ff2fc9f1c8d1c919c140c3e1295ebac6cb66e64c5cb609abe"
|
||||
},
|
||||
{
|
||||
"name": "userdata_30",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/userdata_30-498358c1e5347dc3f8c369523bd77b94ef73d6c6729b40f376209d0d32b356fe.img.xz",
|
||||
"hash": "828d0911713af02de7fae4c583a2274783e344939f296c7c016866a8cf2cb63f",
|
||||
"hash_raw": "498358c1e5347dc3f8c369523bd77b94ef73d6c6729b40f376209d0d32b356fe",
|
||||
"size": 32212254720,
|
||||
"sparse": true,
|
||||
"full_check": true,
|
||||
"has_ab": false,
|
||||
"ondevice_hash": "4beb60ffceff88b05daa014db50cb2f4e9acec3ed7ae1b89a8d3c84cfc3c1c92"
|
||||
}
|
||||
]
|
||||
@@ -76,7 +76,7 @@ def sudo_write(val, path):
|
||||
|
||||
def sudo_read(path: str) -> str:
|
||||
try:
|
||||
return subprocess.check_output(f"sudo cat {path}", shell=True, encoding='utf8')
|
||||
return subprocess.check_output(f"sudo cat {path}", shell=True, encoding='utf8').strip()
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
@@ -371,7 +371,7 @@ class Tici(HardwareBase):
|
||||
|
||||
# *** CPU config ***
|
||||
|
||||
# offline big cluster, leave core 4 online for pandad
|
||||
# offline big cluster
|
||||
for i in range(4, 8):
|
||||
val = '0' if powersave_enabled else '1'
|
||||
sudo_write(val, f'/sys/devices/system/cpu/cpu{i}/online')
|
||||
@@ -384,13 +384,13 @@ class Tici(HardwareBase):
|
||||
|
||||
# *** IRQ config ***
|
||||
|
||||
# GPU
|
||||
affine_irq(5, "kgsl-3d0")
|
||||
# GPU, modeld core
|
||||
affine_irq(7, "kgsl-3d0")
|
||||
|
||||
# camerad core
|
||||
camera_irqs = ("cci", "cpas_camnoc", "cpas-cdm", "csid", "ife", "csid-lite", "ife-lite")
|
||||
camera_irqs = ("a5", "cci", "cpas_camnoc", "cpas-cdm", "csid", "ife", "csid-lite", "ife-lite")
|
||||
for n in camera_irqs:
|
||||
affine_irq(5, n)
|
||||
affine_irq(6, n)
|
||||
|
||||
def get_gpu_usage_percent(self):
|
||||
try:
|
||||
|
||||
@@ -31,7 +31,7 @@ class Proc:
|
||||
|
||||
|
||||
PROCS = [
|
||||
Proc(['camerad'], 2.1, msgs=['roadCameraState', 'wideRoadCameraState', 'driverCameraState']),
|
||||
Proc(['camerad'], 1.75, msgs=['roadCameraState', 'wideRoadCameraState', 'driverCameraState']),
|
||||
Proc(['modeld'], 1.12, atol=0.2, msgs=['modelV2']),
|
||||
Proc(['dmonitoringmodeld'], 0.6, msgs=['driverStateV2']),
|
||||
Proc(['encoderd'], 0.23, msgs=[]),
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Import('env', 'arch', 'messaging', 'common', 'visionipc')
|
||||
|
||||
libs = [common, messaging, visionipc,
|
||||
'z', 'avformat', 'avcodec', 'swscale',
|
||||
'avutil', 'yuv', 'OpenCL', 'pthread']
|
||||
'avformat', 'avcodec', 'avutil',
|
||||
'yuv', 'OpenCL', 'pthread', 'zstd']
|
||||
|
||||
src = ['logger.cc', 'video_writer.cc', 'encoder/encoder.cc', 'encoder/v4l_encoder.cc']
|
||||
src = ['logger.cc', 'zstd_writer.cc', 'video_writer.cc', 'encoder/encoder.cc', 'encoder/v4l_encoder.cc', 'encoder/jpeg_encoder.cc']
|
||||
if arch != "larch64":
|
||||
src += ['encoder/ffmpeg_encoder.cc']
|
||||
|
||||
@@ -19,8 +19,8 @@ logger_lib = env.Library('logger', src)
|
||||
libs.insert(0, logger_lib)
|
||||
|
||||
env.Program('loggerd', ['loggerd.cc'], LIBS=libs)
|
||||
env.Program('encoderd', ['encoderd.cc'], LIBS=libs)
|
||||
env.Program('encoderd', ['encoderd.cc'], LIBS=libs + ["jpeg"])
|
||||
env.Program('bootlog.cc', LIBS=libs)
|
||||
|
||||
if GetOption('extras'):
|
||||
env.Program('tests/test_logger', ['tests/test_runner.cc', 'tests/test_logger.cc'], LIBS=libs + ['curl', 'crypto'])
|
||||
env.Program('tests/test_logger', ['tests/test_runner.cc', 'tests/test_logger.cc', 'tests/test_zstd_writer.cc'], LIBS=libs + ['curl', 'crypto'])
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "common/params.h"
|
||||
#include "common/swaglog.h"
|
||||
#include "system/loggerd/logger.h"
|
||||
#include "system/loggerd/zstd_writer.h"
|
||||
|
||||
|
||||
static kj::Array<capnp::word> build_boot_log() {
|
||||
@@ -50,14 +51,14 @@ static kj::Array<capnp::word> build_boot_log() {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
const std::string id = logger_get_identifier("BootCount");
|
||||
const std::string path = Path::log_root() + "/boot/" + id;
|
||||
const std::string path = Path::log_root() + "/boot/" + id + ".zst";
|
||||
LOGW("bootlog to %s", path.c_str());
|
||||
|
||||
// Open bootlog
|
||||
bool r = util::create_directories(Path::log_root() + "/boot/", 0775);
|
||||
assert(r);
|
||||
|
||||
RawFile file(path.c_str());
|
||||
ZstdFileWriter file(path, LOG_COMPRESSION_LEVEL);
|
||||
// Write initdata
|
||||
file.write(logger_build_init_data().asBytes());
|
||||
// Write bootlog
|
||||
|
||||
@@ -6,12 +6,7 @@ VideoEncoder::VideoEncoder(const EncoderInfo &encoder_info, int in_width, int in
|
||||
out_width = encoder_info.frame_width > 0 ? encoder_info.frame_width : in_width;
|
||||
out_height = encoder_info.frame_height > 0 ? encoder_info.frame_height : in_height;
|
||||
|
||||
|
||||
std::vector pubs = {encoder_info.publish_name};
|
||||
if (encoder_info.thumbnail_name != NULL) {
|
||||
pubs.push_back(encoder_info.thumbnail_name);
|
||||
}
|
||||
pm.reset(new PubMaster(pubs));
|
||||
pm.reset(new PubMaster(std::vector{encoder_info.publish_name}));
|
||||
}
|
||||
|
||||
void VideoEncoder::publisher_publish(int segment_num, uint32_t idx, VisionIpcBufExtra &extra,
|
||||
@@ -45,15 +40,4 @@ void VideoEncoder::publisher_publish(int segment_num, uint32_t idx, VisionIpcBuf
|
||||
kj::ArrayOutputStream output_stream(kj::ArrayPtr<capnp::byte>(msg_cache.data(), bytes_size));
|
||||
capnp::writeMessage(output_stream, msg);
|
||||
pm->send(encoder_info.publish_name, msg_cache.data(), bytes_size);
|
||||
|
||||
// Publish keyframe thumbnail
|
||||
if ((flags & V4L2_BUF_FLAG_KEYFRAME) && encoder_info.thumbnail_name != NULL) {
|
||||
MessageBuilder tm;
|
||||
auto thumbnail = tm.initEvent().initThumbnail();
|
||||
thumbnail.setFrameId(extra.frame_id);
|
||||
thumbnail.setTimestampEof(extra.timestamp_eof);
|
||||
thumbnail.setThumbnail(dat);
|
||||
thumbnail.setEncoding(cereal::Thumbnail::Encoding::KEYFRAME);
|
||||
pm->send(encoder_info.thumbnail_name, tm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,6 @@ public:
|
||||
void publisher_publish(int segment_num, uint32_t idx, VisionIpcBufExtra &extra, unsigned int flags, kj::ArrayPtr<capnp::byte> header, kj::ArrayPtr<capnp::byte> dat);
|
||||
|
||||
protected:
|
||||
void publish_thumbnail(uint32_t frame_id, uint64_t timestamp_eof, kj::ArrayPtr<capnp::byte> dat);
|
||||
|
||||
int in_width, in_height;
|
||||
int out_width, out_height;
|
||||
const EncoderInfo encoder_info;
|
||||
|
||||
@@ -48,7 +48,10 @@ FfmpegEncoder::~FfmpegEncoder() {
|
||||
}
|
||||
|
||||
void FfmpegEncoder::encoder_open(const char* path) {
|
||||
const AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_FFVHUFF);
|
||||
auto codec_id = encoder_info.encode_type == cereal::EncodeIndex::Type::QCAMERA_H264
|
||||
? AV_CODEC_ID_H264
|
||||
: AV_CODEC_ID_FFVHUFF;
|
||||
const AVCodec *codec = avcodec_find_encoder(codec_id);
|
||||
|
||||
this->codec_ctx = avcodec_alloc_context3(codec);
|
||||
assert(this->codec_ctx);
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "system/loggerd/encoder/jpeg_encoder.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
JpegEncoder::JpegEncoder(const std::string &pusblish_name, int width, int height)
|
||||
: publish_name(pusblish_name), thumbnail_width(width), thumbnail_height(height) {
|
||||
yuv_buffer.resize((thumbnail_width * ((thumbnail_height + 15) & ~15) * 3) / 2);
|
||||
pm = std::make_unique<PubMaster>(std::vector{pusblish_name.c_str()});
|
||||
}
|
||||
|
||||
JpegEncoder::~JpegEncoder() {
|
||||
if (out_buffer) {
|
||||
free(out_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void JpegEncoder::pushThumbnail(VisionBuf *buf, const VisionIpcBufExtra &extra) {
|
||||
generateThumbnail(buf->y, buf->uv, buf->width, buf->height, buf->stride);
|
||||
|
||||
MessageBuilder msg;
|
||||
auto thumbnaild = msg.initEvent().initThumbnail();
|
||||
thumbnaild.setFrameId(extra.frame_id);
|
||||
thumbnaild.setTimestampEof(extra.timestamp_eof);
|
||||
thumbnaild.setThumbnail({out_buffer, out_size});
|
||||
|
||||
pm->send(publish_name.c_str(), msg);
|
||||
}
|
||||
|
||||
void JpegEncoder::generateThumbnail(const uint8_t *y_addr, const uint8_t *uv_addr, int width, int height, int stride) {
|
||||
int downscale = width / thumbnail_width;
|
||||
assert(downscale * thumbnail_height == height);
|
||||
|
||||
// make the buffer big enough. jpeg_write_raw_data requires 16-pixels aligned height to be used.
|
||||
uint8_t *y_plane = yuv_buffer.data();
|
||||
uint8_t *u_plane = y_plane + thumbnail_width * thumbnail_height;
|
||||
uint8_t *v_plane = u_plane + (thumbnail_width * thumbnail_height) / 4;
|
||||
{
|
||||
// subsampled conversion from nv12 to yuv
|
||||
for (int hy = 0; hy < thumbnail_height / 2; hy++) {
|
||||
for (int hx = 0; hx < thumbnail_width / 2; hx++) {
|
||||
int ix = hx * downscale + (downscale - 1) / 2;
|
||||
int iy = hy * downscale + (downscale - 1) / 2;
|
||||
y_plane[(hy * 2 + 0) * thumbnail_width + (hx * 2 + 0)] = y_addr[(iy * 2 + 0) * stride + ix * 2 + 0];
|
||||
y_plane[(hy * 2 + 0) * thumbnail_width + (hx * 2 + 1)] = y_addr[(iy * 2 + 0) * stride + ix * 2 + 1];
|
||||
y_plane[(hy * 2 + 1) * thumbnail_width + (hx * 2 + 0)] = y_addr[(iy * 2 + 1) * stride + ix * 2 + 0];
|
||||
y_plane[(hy * 2 + 1) * thumbnail_width + (hx * 2 + 1)] = y_addr[(iy * 2 + 1) * stride + ix * 2 + 1];
|
||||
u_plane[hy * thumbnail_width / 2 + hx] = uv_addr[iy * stride + ix * 2 + 0];
|
||||
v_plane[hy * thumbnail_width / 2 + hx] = uv_addr[iy * stride + ix * 2 + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compressToJpeg(y_plane, u_plane, v_plane);
|
||||
}
|
||||
|
||||
void JpegEncoder::compressToJpeg(uint8_t *y_plane, uint8_t *u_plane, uint8_t *v_plane) {
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
if (out_buffer) {
|
||||
free(out_buffer);
|
||||
out_buffer = nullptr;
|
||||
out_size = 0;
|
||||
}
|
||||
jpeg_mem_dest(&cinfo, &out_buffer, &out_size);
|
||||
|
||||
cinfo.image_width = thumbnail_width;
|
||||
cinfo.image_height = thumbnail_height;
|
||||
cinfo.input_components = 3;
|
||||
|
||||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_colorspace(&cinfo, JCS_YCbCr);
|
||||
// configure sampling factors for yuv420.
|
||||
cinfo.comp_info[0].h_samp_factor = 2; // Y
|
||||
cinfo.comp_info[0].v_samp_factor = 2;
|
||||
cinfo.comp_info[1].h_samp_factor = 1; // U
|
||||
cinfo.comp_info[1].v_samp_factor = 1;
|
||||
cinfo.comp_info[2].h_samp_factor = 1; // V
|
||||
cinfo.comp_info[2].v_samp_factor = 1;
|
||||
cinfo.raw_data_in = TRUE;
|
||||
|
||||
jpeg_set_quality(&cinfo, 50, TRUE);
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
JSAMPROW y[16], u[8], v[8];
|
||||
JSAMPARRAY planes[3]{y, u, v};
|
||||
|
||||
for (int line = 0; line < cinfo.image_height; line += 16) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
y[i] = y_plane + (line + i) * cinfo.image_width;
|
||||
if (i % 2 == 0) {
|
||||
int offset = (cinfo.image_width / 2) * ((i + line) / 2);
|
||||
u[i / 2] = u_plane + offset;
|
||||
v[i / 2] = v_plane + offset;
|
||||
}
|
||||
}
|
||||
jpeg_write_raw_data(&cinfo, planes, 16);
|
||||
}
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <jpeglib.h>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "cereal/messaging/messaging.h"
|
||||
#include "msgq/visionipc/visionbuf.h"
|
||||
|
||||
class JpegEncoder {
|
||||
public:
|
||||
JpegEncoder(const std::string &pusblish_name, int width, int height);
|
||||
~JpegEncoder();
|
||||
void pushThumbnail(VisionBuf *buf, const VisionIpcBufExtra &extra);
|
||||
|
||||
private:
|
||||
void generateThumbnail(const uint8_t *y, const uint8_t *uv, int width, int height, int stride);
|
||||
void compressToJpeg(uint8_t *y_plane, uint8_t *u_plane, uint8_t *v_plane);
|
||||
|
||||
int thumbnail_width;
|
||||
int thumbnail_height;
|
||||
std::string publish_name;
|
||||
std::vector<uint8_t> yuv_buffer;
|
||||
std::unique_ptr<PubMaster> pm;
|
||||
|
||||
// JPEG output buffer
|
||||
unsigned char* out_buffer = nullptr;
|
||||
unsigned long out_size = 0;
|
||||
};
|
||||
@@ -155,7 +155,7 @@ void V4LEncoder::dequeue_handler(V4LEncoder *e) {
|
||||
|
||||
V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_height)
|
||||
: VideoEncoder(encoder_info, in_width, in_height) {
|
||||
fd = open("/dev/v4l/by-path/platform-aa00000.qcom_vidc-video-index1", O_RDWR|O_NONBLOCK);
|
||||
fd = HANDLE_EINTR(open("/dev/v4l/by-path/platform-aa00000.qcom_vidc-video-index1", O_RDWR|O_NONBLOCK));
|
||||
assert(fd >= 0);
|
||||
|
||||
struct v4l2_capability cap;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "system/loggerd/loggerd.h"
|
||||
#include "system/loggerd/encoder/jpeg_encoder.h"
|
||||
|
||||
#ifdef QCOM2
|
||||
#include "system/loggerd/encoder/v4l_encoder.h"
|
||||
@@ -50,6 +51,8 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) {
|
||||
std::vector<std::unique_ptr<Encoder>> encoders;
|
||||
VisionIpcClient vipc_client = VisionIpcClient("camerad", cam_info.stream_type, false);
|
||||
|
||||
std::unique_ptr<JpegEncoder> jpeg_encoder;
|
||||
|
||||
int cur_seg = 0;
|
||||
while (!do_exit) {
|
||||
if (!vipc_client.connect(false)) {
|
||||
@@ -67,6 +70,11 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) {
|
||||
auto &e = encoders.emplace_back(new Encoder(encoder_info, buf_info.width, buf_info.height));
|
||||
e->encoder_open(nullptr);
|
||||
}
|
||||
|
||||
// Only one thumbnail can be generated per camera stream
|
||||
if (auto thumbnail_name = cam_info.encoder_infos[0].thumbnail_name) {
|
||||
jpeg_encoder = std::make_unique<JpegEncoder>(thumbnail_name, buf_info.width / 4, buf_info.height / 4);
|
||||
}
|
||||
}
|
||||
|
||||
bool lagging = false;
|
||||
@@ -108,6 +116,10 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) {
|
||||
LOGE("Failed to encode frame. frame_id: %d", extra.frame_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (jpeg_encoder && (extra.frame_id % 1200 == 100)) {
|
||||
jpeg_encoder->pushThumbnail(buf, extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,42 @@ std::string logger_get_identifier(std::string key) {
|
||||
return util::string_format("%08x--%s", cnt, ss.str().c_str());
|
||||
}
|
||||
|
||||
std::string zstd_decompress(const std::string &in) {
|
||||
ZSTD_DCtx *dctx = ZSTD_createDCtx();
|
||||
assert(dctx != nullptr);
|
||||
|
||||
// Initialize input and output buffers
|
||||
ZSTD_inBuffer input = {in.data(), in.size(), 0};
|
||||
|
||||
// Estimate and reserve memory for decompressed data
|
||||
size_t estimatedDecompressedSize = ZSTD_getFrameContentSize(in.data(), in.size());
|
||||
if (estimatedDecompressedSize == ZSTD_CONTENTSIZE_ERROR || estimatedDecompressedSize == ZSTD_CONTENTSIZE_UNKNOWN) {
|
||||
estimatedDecompressedSize = in.size() * 2; // Use a fallback size
|
||||
}
|
||||
|
||||
std::string decompressedData;
|
||||
decompressedData.reserve(estimatedDecompressedSize);
|
||||
|
||||
const size_t bufferSize = ZSTD_DStreamOutSize(); // Recommended output buffer size
|
||||
std::string outputBuffer(bufferSize, '\0');
|
||||
|
||||
while (input.pos < input.size) {
|
||||
ZSTD_outBuffer output = {outputBuffer.data(), bufferSize, 0};
|
||||
|
||||
size_t result = ZSTD_decompressStream(dctx, &output, &input);
|
||||
if (ZSTD_isError(result)) {
|
||||
break;
|
||||
}
|
||||
|
||||
decompressedData.append(outputBuffer.data(), output.pos);
|
||||
}
|
||||
|
||||
ZSTD_freeDCtx(dctx);
|
||||
decompressedData.shrink_to_fit();
|
||||
return decompressedData;
|
||||
}
|
||||
|
||||
|
||||
static void log_sentinel(LoggerState *log, SentinelType type, int exit_signal = 0) {
|
||||
MessageBuilder msg;
|
||||
auto sen = msg.initEvent().initSentinel();
|
||||
@@ -144,12 +180,11 @@ bool LoggerState::next() {
|
||||
bool ret = util::create_directories(segment_path, 0775);
|
||||
assert(ret == true);
|
||||
|
||||
const std::string rlog_path = segment_path + "/rlog";
|
||||
lock_file = rlog_path + ".lock";
|
||||
lock_file = segment_path + "/rlog.lock";
|
||||
std::ofstream{lock_file};
|
||||
|
||||
rlog.reset(new RawFile(rlog_path));
|
||||
qlog.reset(new RawFile(segment_path + "/qlog"));
|
||||
rlog.reset(new ZstdFileWriter(segment_path + "/rlog.zst", LOG_COMPRESSION_LEVEL));
|
||||
qlog.reset(new ZstdFileWriter(segment_path + "/qlog.zst", LOG_COMPRESSION_LEVEL));
|
||||
|
||||
// log init data & sentinel type.
|
||||
write(init_data.asBytes(), true);
|
||||
|
||||
+4
-22
@@ -7,31 +7,12 @@
|
||||
#include "cereal/messaging/messaging.h"
|
||||
#include "common/util.h"
|
||||
#include "system/hardware/hw.h"
|
||||
#include "system/loggerd/zstd_writer.h"
|
||||
|
||||
class RawFile {
|
||||
public:
|
||||
RawFile(const std::string &path) {
|
||||
file = util::safe_fopen(path.c_str(), "wb");
|
||||
assert(file != nullptr);
|
||||
}
|
||||
~RawFile() {
|
||||
util::safe_fflush(file);
|
||||
int err = fclose(file);
|
||||
assert(err == 0);
|
||||
}
|
||||
inline void write(void* data, size_t size) {
|
||||
int written = util::safe_fwrite(data, 1, size, file);
|
||||
assert(written == size);
|
||||
}
|
||||
inline void write(kj::ArrayPtr<capnp::byte> array) { write(array.begin(), array.size()); }
|
||||
|
||||
private:
|
||||
FILE* file = nullptr;
|
||||
};
|
||||
constexpr int LOG_COMPRESSION_LEVEL = 10;
|
||||
|
||||
typedef cereal::Sentinel::SentinelType SentinelType;
|
||||
|
||||
|
||||
class LoggerState {
|
||||
public:
|
||||
LoggerState(const std::string& log_root = Path::log_root());
|
||||
@@ -48,8 +29,9 @@ protected:
|
||||
int part = -1, exit_signal = 0;
|
||||
std::string route_path, route_name, segment_path, lock_file;
|
||||
kj::Array<capnp::word> init_data;
|
||||
std::unique_ptr<RawFile> rlog, qlog;
|
||||
std::unique_ptr<ZstdFileWriter> rlog, qlog;
|
||||
};
|
||||
|
||||
kj::Array<capnp::word> logger_build_init_data();
|
||||
std::string logger_get_identifier(std::string key);
|
||||
std::string zstd_decompress(const std::string &in);
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
|
||||
const EncoderInfo main_road_encoder_info = {
|
||||
.publish_name = "roadEncodeData",
|
||||
.thumbnail_name = "thumbnail",
|
||||
.filename = "fcamera.hevc",
|
||||
INIT_ENCODE_FUNCTIONS(RoadEncode),
|
||||
};
|
||||
|
||||
@@ -106,7 +106,7 @@ class TestEncoder:
|
||||
|
||||
# Check encodeIdx
|
||||
if encode_idx_name is not None:
|
||||
rlog_path = f"{route_prefix_path}--{i}/rlog"
|
||||
rlog_path = f"{route_prefix_path}--{i}/rlog.zst"
|
||||
msgs = [m for m in LogReader(rlog_path) if m.which() == encode_idx_name]
|
||||
encode_msgs = [getattr(m, encode_idx_name) for m in msgs]
|
||||
|
||||
|
||||
@@ -9,12 +9,13 @@ void verify_segment(const std::string &route_path, int segment, int max_segment,
|
||||
SentinelType end_sentinel = segment == max_segment - 1 ? SentinelType::END_OF_ROUTE : SentinelType::END_OF_SEGMENT;
|
||||
|
||||
REQUIRE(!util::file_exists(segment_path + "/rlog.lock"));
|
||||
for (const char *fn : {"/rlog", "/qlog"}) {
|
||||
for (const char *fn : {"/rlog.zst", "/qlog.zst"}) {
|
||||
const std::string log_file = segment_path + fn;
|
||||
std::string log = util::read_file(log_file);
|
||||
REQUIRE(!log.empty());
|
||||
std::string decompressed_log = zstd_decompress(log);
|
||||
int event_cnt = 0, i = 0;
|
||||
kj::ArrayPtr<const capnp::word> words((capnp::word *)log.data(), log.size() / sizeof(capnp::word));
|
||||
kj::ArrayPtr<const capnp::word> words((capnp::word *)decompressed_log.data(), decompressed_log.size() / sizeof(capnp::word));
|
||||
while (words.size() > 0) {
|
||||
try {
|
||||
capnp::FlatArrayMessageReader reader(words);
|
||||
|
||||
@@ -142,7 +142,7 @@ class TestLoggerd:
|
||||
Params().put("RecordFront", "1")
|
||||
|
||||
d = DEVICE_CAMERAS[("tici", "ar0231")]
|
||||
expected_files = {"rlog", "qlog", "qcamera.ts", "fcamera.hevc", "dcamera.hevc", "ecamera.hevc"}
|
||||
expected_files = {"rlog.zst", "qlog.zst", "qcamera.ts", "fcamera.hevc", "dcamera.hevc", "ecamera.hevc"}
|
||||
streams = [(VisionStreamType.VISION_STREAM_ROAD, (d.fcam.width, d.fcam.height, 2048*2346, 2048, 2048*1216), "roadCameraState"),
|
||||
(VisionStreamType.VISION_STREAM_DRIVER, (d.dcam.width, d.dcam.height, 2048*2346, 2048, 2048*1216), "driverCameraState"),
|
||||
(VisionStreamType.VISION_STREAM_WIDE_ROAD, (d.ecam.width, d.ecam.height, 2048*2346, 2048, 2048*1216), "wideRoadCameraState")]
|
||||
@@ -229,7 +229,7 @@ class TestLoggerd:
|
||||
random.sample(no_qlog_services, random.randint(2, min(10, len(no_qlog_services))))
|
||||
sent_msgs = self._publish_random_messages(services)
|
||||
|
||||
qlog_path = os.path.join(self._get_latest_log_dir(), "qlog")
|
||||
qlog_path = os.path.join(self._get_latest_log_dir(), "qlog.zst")
|
||||
lr = list(LogReader(qlog_path))
|
||||
|
||||
# check initData and sentinel
|
||||
@@ -255,7 +255,7 @@ class TestLoggerd:
|
||||
services = random.sample(CEREAL_SERVICES, random.randint(5, 10))
|
||||
sent_msgs = self._publish_random_messages(services)
|
||||
|
||||
lr = list(LogReader(os.path.join(self._get_latest_log_dir(), "rlog")))
|
||||
lr = list(LogReader(os.path.join(self._get_latest_log_dir(), "rlog.zst")))
|
||||
|
||||
# check initData and sentinel
|
||||
self._check_init_data(lr)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user