Compare commits

...

77 Commits

Author SHA1 Message Date
Your Name
980f0aac00 wip 2024-07-05 16:30:39 -05:00
Your Name
0fc13d815d wip 2024-07-05 16:24:57 -05:00
Your Name
ac4d7efff1 wip 2024-07-05 16:21:43 -05:00
Your Name
a47fbb140d wip 2024-06-19 00:24:32 -05:00
Your Name
8225319314 wip 2024-06-17 18:34:32 -05:00
Your Name
3eca593af1 wip 2024-06-17 15:45:35 -05:00
Your Name
445138519d wip 2024-06-17 15:43:03 -05:00
Your Name
679a952f51 wip 2024-06-17 12:48:11 -05:00
Your Name
1b9097bc13 wip 2024-06-17 12:47:21 -05:00
Your Name
4c9c211f97 wip 2024-06-17 12:44:38 -05:00
Your Name
c94dc803dd wip 2024-06-17 12:40:02 -05:00
Your Name
33c59eadb3 wip 2024-06-17 12:39:24 -05:00
Your Name
92db8a5913 wip 2024-06-17 12:34:19 -05:00
Your Name
af3cacae53 wip 2024-06-17 12:33:20 -05:00
Your Name
ec7743c460 wip 2024-06-17 12:15:35 -05:00
Your Name
5e80ad8d05 wip 2024-06-17 12:14:25 -05:00
Your Name
a2cf02ea37 wip 2024-06-17 12:12:54 -05:00
Comma Device
75c91213a2 wip 2024-06-17 17:10:43 +00:00
Comma Device
7f182b7fae wip 2024-06-17 16:57:23 +00:00
Your Name
0c36ffdfde wip 2024-06-15 21:05:30 -05:00
Your Name
4702c22aa3 wip 2024-06-15 20:59:47 -05:00
Your Name
6ef4519798 wip 2024-06-15 20:49:08 -05:00
concordia
5e4c1e2427 wip 2024-06-15 20:45:56 -05:00
concordia
94581c908b wip 2024-06-15 20:40:09 -05:00
concordia
98d7133844 wip 2024-06-15 20:38:29 -05:00
concordia
3ae97fe0e5 wip 2024-06-15 20:33:14 -05:00
concordia
51561d3393 wip 2024-06-15 20:30:56 -05:00
concordia
be595765e4 wip 2024-06-15 20:28:00 -05:00
concordia
7bb4980119 wip 2024-06-15 20:25:53 -05:00
concordia
720c9ccbc8 wip 2024-06-15 20:20:54 -05:00
concordia
9dc2951e07 wip 2024-06-10 09:41:39 -05:00
concordia
7962409629 wip 2024-06-10 09:23:55 -05:00
Your Name
314e9b5d32 wip 2024-06-09 18:01:57 -05:00
Your Name
2c9e56a579 wip 2024-06-09 17:43:17 -05:00
Your Name
cee8330928 wip 2024-06-09 17:27:31 -05:00
Your Name
9172cb85ee wip 2024-06-09 17:23:37 -05:00
Your Name
ee0a308db6 wip 2024-06-09 17:19:09 -05:00
Your Name
32cbaa1049 wip 2024-06-09 17:17:02 -05:00
Your Name
5d58961187 wip 2024-06-09 17:09:24 -05:00
Your Name
6ee82f77f6 wip 2024-06-09 16:52:09 -05:00
Your Name
2e8654ba7f wip 2024-06-09 16:50:04 -05:00
Your Name
33afb79600 wip 2024-06-09 16:38:23 -05:00
Your Name
48c2f76109 wip 2024-06-09 16:37:35 -05:00
Your Name
00dd71abb2 wip 2024-06-09 16:17:44 -05:00
Your Name
763198bec1 wip 2024-06-09 16:09:02 -05:00
Comma Device
7f63e51658 wip 2024-06-09 21:08:28 +00:00
Your Name
a963ea0296 wip 2024-06-09 16:08:19 -05:00
Your Name
b3467cf739 wip 2024-05-21 00:29:31 -05:00
Your Name
dd96b5aea7 wip 2024-05-21 00:22:19 -05:00
Your Name
9aabc7e605 wip 2024-05-21 00:20:54 -05:00
Your Name
2f9d425859 wip 2024-05-21 00:19:09 -05:00
Your Name
db94b5f923 wip 2024-05-21 00:10:04 -05:00
Your Name
70bf59ccbf wip 2024-05-21 00:08:37 -05:00
Your Name
cc7a35b300 wip 2024-05-21 00:06:37 -05:00
Your Name
8818f9135a wip 2024-05-21 00:06:17 -05:00
Your Name
fc451096c5 wip 2024-05-21 00:03:13 -05:00
Your Name
8e71d08b82 wip 2024-05-20 23:54:40 -05:00
Your Name
babab7f415 wip 2024-05-20 23:53:14 -05:00
Your Name
6939b8820e wip 2024-05-20 23:52:23 -05:00
Your Name
b879b6790f wip 2024-05-20 23:52:07 -05:00
Your Name
2c3a8273f7 wip 2024-05-20 23:36:58 -05:00
Your Name
f7ce58d71f wip 2024-05-20 23:34:45 -05:00
Your Name
42f0e95f0a wip 2024-05-20 23:32:02 -05:00
Your Name
dce9b86fb6 wip 2024-05-20 23:30:03 -05:00
Your Name
8dacb12362 wip 2024-05-20 23:26:07 -05:00
Your Name
cc9e3d6827 wip 2024-05-20 23:05:08 -05:00
Your Name
c22143d2cd wip 2024-05-20 23:01:14 -05:00
Your Name
cb7def739e wip 2024-05-20 22:59:50 -05:00
Your Name
01dfb0205f wip 2024-05-20 22:52:32 -05:00
Your Name
2f2205ebe7 wip 2024-05-20 22:40:46 -05:00
Your Name
64578562fc wip 2024-05-20 22:34:45 -05:00
Your Name
1ef69ac52e wip 2024-05-20 22:32:27 -05:00
Your Name
6e6d4428df wip 2024-05-20 22:30:27 -05:00
Your Name
9cf87b08b5 wip 2024-05-20 22:29:01 -05:00
Your Name
17fbb74695 wip 2024-05-20 22:26:20 -05:00
Your Name
cb7eda64d9 wip 2024-05-20 22:17:59 -05:00
Your Name
037b08dd0d wip 2024-05-18 08:42:15 -05:00
39 changed files with 2308 additions and 1455 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,5 @@
prebuilt
system/clearpilot/dev/reverse_ssh
system/clearpilot/dev/on_start_brian.sh
system/clearpilot/dev/id_rsa
system/clearpilot/dev/id_rsa.pub
venv/

View File

@@ -232,11 +232,17 @@ std::unordered_map<std::string, uint32_t> keys = {
{"CarMake", PERSISTENT},
{"CarModel", PERSISTENT},
{"CarCruiseDisplayActual", PERSISTENT},
{"CarSpeedLimit", PERSISTENT},
{"CarSpeedLimitWarning", PERSISTENT},
{"CarSpeedLimitLiteral", PERSISTENT},
{"SpeedLimitLatDesired", PERSISTENT},
{"SpeedLimitVTSC", PERSISTENT},
// {"SpeedLimitLatDesired", PERSISTENT},
// {"SpeedLimitVTSC", PERSISTENT},
{"CPTLkasButtonAction", PERSISTENT},
{"ScreenDisaplayMode", PERSISTENT},
{"RadarDist", PERSISTENT},
{"ModelDist", PERSISTENT},

View File

@@ -120,7 +120,8 @@ log.setLevel(logging.DEBUG)
outhandler = logging.StreamHandler()
print_level = os.environ.get('LOGPRINT', 'warning')
# print_level = os.environ.get('LOGPRINT', 'warning')
print_level = os.environ.get('LOGPRINT', 'debug')
if print_level == 'debug':
outhandler.setLevel(logging.DEBUG)
elif print_level == 'info':

1
openpilot/cereal Symbolic link
View File

@@ -0,0 +1 @@
../cereal/

View File

@@ -1,5 +1,214 @@
-----
- screen off on lkas
- speed limit change chirp on cruise
-----
- fix manager / error recording / restart service on fail
- fix gps tracking
- dashcam
- better turning logic
- new settings UI
- experimental mode
------------
- revert a bunch of debugging in canfd
- configure it so i can toggle experimental via lkas
- if experimental enabled, then transmit experimental speed settings
- but only if no lead car or not decelerating. got to think of a condition
where we reengage if the lead is going too slow and we need to let stock long decel
- implement speed limit controller as a simple Warning
- implement a simple resume from standstill hack
- flesh all this out and prepare for trip. we will make auto match speed a future problem.
- continue on other projects and bench this one.
- this whole thing kind of sucks if i cant transmit buttons. keep trying.
- maybe curise_button and not cruise_button_alt will work?
-----
Latest:
- fix hiding path if disabled
- fix suspend on override behavior - override doesnt happen on always on lateral. need alternative check.
- fix & test lane line narrow on lane change view
- the acc cancel does nothing.
- must simulate actual button presses.
- add radar dist, model dist, radar speed, model speed to debug hud
- add wheel touched, wheel override to hud
- fix always on lateral saying its on when actually fully engaged
Notes on speed limit override:
- we need to capture the original speed and feed it to vtsc and model whule we
are under speed adjustment
------
- fix lane lines
- fix always on lateral detection
- position override under 25 mph suspends assist
- output the three speeds
- test - if engaged, adjust the speed twoards experimental one unit every second
- disable onroad on parked, not car off
- test that lkas button crashes controlsd, it should
- test that lkas button creates an alert, it should
- hyundai clsc https://github.com/garrettpall/openpilot/commit/5528198aa73d3d017d16ec4ca38306b11e5da0a8
- get ui to work on its own using no video feed, custom ui state inputs
- dress up ui
- add debug elements to ui with a boolean at top of onroad.cc to enable/disable:
- curviture
- current speed limit
- current cruise speed
- current experimental mode speed
- current distance to lead based on radar
- current distance to lead based on model draw distance
- current speed of lead
- when changing lanes and lateral disabled, draw a narrow single 'line' down center
- of computed path, and don't show side lane boundaries
- make side lanes 10% wider and the disengage mode 10% brighter
- make 25% of side lanes 50% darker than base
- hello world alert triggered by lkas btn
- hello world bootstrap dashboard
- button stuff:
- read paddle left (for full nudgeless lane change + blinker, reset to drive)
- read paddle right ("")
- read current drive mode, reset paddle mode to drive
- write pause, res, accel, mode, drive
wishlist: read / write info switcher, hvac, windows
wishlist: allow lane assist (not lane keep) on disengage
test:
- disable all canbus
- set speed limit during stock long
OP -> Oscar
- oscar - global clearpilot state var
- oscar.cs - clearpilot car state (populated by op variables for cp.planner)
- oscar.ce - clearpilot car event queue (array that can be pushed to from car)
- oscar.ceh - event queue history (for debug)
- oscar.clog - error and console.log style one off messages to transmit to logs or watching consoles
Oscar -> OP
- oscar.ps - clearpilot planner state (data from cp)
- oscar.pe - clearpilot planner event (one time events from planner to be processed by openpilot)
- oscar.peh - planner event history (for debug)
- oscar.plog - retransmits clog as well as additional data for UI based log consoles
- oscar - clearpilot's planner - nodejs process that synchronizes state between all processes and makes decisions
- settings menu
- - branch selector - release, stage, dev. Stage is my personal release branch. Should always be able to easilly switch to stage while im in a development state.
- unfuck the directory structure. new structure:
-
-------
- make functions
--- get_curvature
--- get_wheel_angle
--- get_distance_to_left_lane
--- get_distance_to_right_lane
--- are hands on wheel
--- distance traveled for lane change
--- distance to lead
- put these on a debug.
- Design alternate settings webview
- get speed limit display working
- get calculated experimental speed display working
- get button press emulation working
- get experimental mode working
- get speed limit set working
- dev enable lateral on blinker but no wheel pressure or no wheel presence
- bluetooth dummy device
- Test if activation fix works for op long, submit to frog maintain
- (test) disable all turn signal output commands - they are causing issues
- test "create_acc_cancel" on canfd on cc engaged on boot
- Create clearpilot process. manages behaviors.
- experiment with reduced jerk values
- test toggle stop all canbus output
- check if acc_cancel events are being made on idle in stock long, if so, its a bug.
- Warn if significantly slower traffic
behaviors:
- getting head mode - turn off babysitter with an alert on the screen that it is off, suspend for 10 minutes
- in this mode it should be extra grouchy if a curve is detected, slowdown is detected, or lane lines are weak
- lane change wrong way reenable lateral
- blinker signal wheel angle minor enable lateral
- wheel angle sharp only engage lateral if over lane edge unless hands not on wheel
- no lateral on turn signal - only enforce if model curvature > 10 degrees, hands on wheel, or wheel override (maybe curve not necessary?)
- basic lane keep - nudge wheel slightly if over line and still going straight and hands on wheel
- debug mode activated bu lkas
- See where disk free is going with NCDU and add smarter log rotation
- Maybe this has logs where it could show what happened to frogpilot process?
- Test supress cruise icon on long paused
- increase center lane brightness 50% and make it blueish
- make drive mode color much brighter and 30% more white
- maintain lateral on icon on stop on dash
- prevent engagement if disengaged and brakes are applied, just enable lateral
- edit manager to log all stderr output
- find a way to disable all logging unless debug mode enabled (screen setting)
- set up dash cam recordings
- disable dash cam and record in real logger mode if debug mode is entered
- Integrate here maps api for traffic data
- maybe even speed limit data? and location data?
- write a debug function for python that cats data to a screen terminal and optionally a log file
- if cruise already engaged when boot, just enable lateral
- reengage lateral if changing lanes and changing the wrong way
- speed limit display / over speed display / trigger set
- hack the buttons so we can press them
- auto set speed limit
- conditional experimenal mode
- ui conditional experimental mode, orange lines, show large font of desired speed in lower left
- hold down button to turn off screen, remember setting
- bluetooth dummy device
- dash cam
- change disk used on sidebar to disk free / percent used
-
- warn if lead is going more than 30 under my speed or 20 if auto mode is off
- mark os version different than release, forcing a os reinstall
- no prompt on os reinstall
Test features wizard:
- read paddles
- read speed
- adjust speed
- cancel / resume
- reset drive mode
- read radar distance
- activate blinkers
- disable changing lanes notices (tiny indicator is fine)
- speed limit display / over speed display
- hack the buttons so we can press them
- auto set speed limit

View File

@@ -1,159 +1,45 @@
- lkas button toggle display off / minimal / full / info
- revert a bunch of debugging in canfd
- fix lane lines
- fix always on lateral detection
- position override under 25 mph suspends assist
- fix it so it reads cruise state and uses it to determine program state exclusively
- always on lat in particular
- output the three speeds
- make override a state that can happen on always on lateral
- test - if engaged, adjust the speed twoards experimental one unit every second
- fix turning with override to disengage lower than 20
- disable onroad on parked, not car off
- configure it so i can toggle experimental via lkas
- test that lkas button crashes controlsd, it should
- test that lkas button creates an alert, it should
- if experimental enabled, then transmit experimental speed settings
- but only if no lead car or not decelerating. got to think of a condition
where we reengage if the lead is going too slow and we need to let stock long decel
- hyundai clsc https://github.com/garrettpall/openpilot/commit/5528198aa73d3d017d16ec4ca38306b11e5da0a8
- implement speed limit controller as a simple Warning
- get ui to work on its own using no video feed, custom ui state inputs
- dress up ui
- implement a simple resume from standstill hack
- add debug elements to ui with a boolean at top of onroad.cc to enable/disable:
- curviture
- current speed limit
- current cruise speed
- current experimental mode speed
- current distance to lead based on radar
- current distance to lead based on model draw distance
- current speed of lead
--- TRIP RELEASE ---
- when changing lanes and lateral disabled, draw a narrow single 'line' down center
- of computed path, and don't show side lane boundaries
- configure orangepi wifi selector
- can i have it use phone bt tether?
- fix gps
- implement new onroad settings
- implement new offroad settings
- implement debug console (make it actually useful)
- implement dash cam
- implement dash cam viewer
- implement trip logger
- implement generic CLSC
- implement GM CLSC
- make side lanes 10% wider and the disengage mode 10% brighter
- make 25% of side lanes 50% darker than base
- CRAIG RELEASE -
- hello world alert triggered by lkas btn
- hello world bootstrap dashboard
- implement logo selector
- update models, sync important changes from main
- update installer
- button stuff:
- read paddle left (for full nudgeless lane change + blinker, reset to drive)
- read paddle right ("")
- read current drive mode, reset paddle mode to drive
- write pause, res, accel, mode, drive
- PUBLIC RELEASE -
wishlist: read / write info switcher, hvac, windows
wishlist: allow lane assist (not lane keep) on disengage
test:
- disable all canbus
- set speed limit during stock long
OP -> Oscar
- oscar - global clearpilot state var
- oscar.cs - clearpilot car state (populated by op variables for cp.planner)
- oscar.ce - clearpilot car event queue (array that can be pushed to from car)
- oscar.ceh - event queue history (for debug)
- oscar.clog - error and console.log style one off messages to transmit to logs or watching consoles
Oscar -> OP
- oscar.ps - clearpilot planner state (data from cp)
- oscar.pe - clearpilot planner event (one time events from planner to be processed by openpilot)
- oscar.peh - planner event history (for debug)
- oscar.plog - retransmits clog as well as additional data for UI based log consoles
- oscar - clearpilot's planner - nodejs process that synchronizes state between all processes and makes decisions
- settings menu
- - branch selector - release, stage, dev. Stage is my personal release branch. Should always be able to easilly switch to stage while im in a development state.
- unfuck the directory structure. new structure:
-
-------
- make functions
--- get_curvature
--- get_wheel_angle
--- get_distance_to_left_lane
--- get_distance_to_right_lane
--- are hands on wheel
--- distance traveled for lane change
--- distance to lead
- put these on a debug.
- Design alternate settings webview
- get speed limit display working
- get calculated experimental speed display working
- get button press emulation working
- get experimental mode working
- get speed limit set working
- dev enable lateral on blinker but no wheel pressure or no wheel presence
- bluetooth dummy device
- Test if activation fix works for op long, submit to frog maintain
- (test) disable all turn signal output commands - they are causing issues
- test "create_acc_cancel" on canfd on cc engaged on boot
- Create clearpilot process. manages behaviors.
- experiment with reduced jerk values
- test toggle stop all canbus output
- check if acc_cancel events are being made on idle in stock long, if so, its a bug.
- Warn if significantly slower traffic
behaviors:
- getting head mode - turn off babysitter with an alert on the screen that it is off, suspend for 10 minutes
- in this mode it should be extra grouchy if a curve is detected, slowdown is detected, or lane lines are weak
- lane change wrong way reenable lateral
- blinker signal wheel angle minor enable lateral
- wheel angle sharp only engage lateral if over lane edge unless hands not on wheel
- no lateral on turn signal - only enforce if model curvature > 10 degrees, hands on wheel, or wheel override (maybe curve not necessary?)
- basic lane keep - nudge wheel slightly if over line and still going straight and hands on wheel
- debug mode activated bu lkas
- See where disk free is going with NCDU and add smarter log rotation
- Maybe this has logs where it could show what happened to frogpilot process?
- Test supress cruise icon on long paused
- increase center lane brightness 50% and make it blueish
- make drive mode color much brighter and 30% more white
- maintain lateral on icon on stop on dash
- prevent engagement if disengaged and brakes are applied, just enable lateral
- edit manager to log all stderr output
- find a way to disable all logging unless debug mode enabled (screen setting)
- set up dash cam recordings
- disable dash cam and record in real logger mode if debug mode is entered
- Integrate here maps api for traffic data
- maybe even speed limit data? and location data?
- write a debug function for python that cats data to a screen terminal and optionally a log file
- if cruise already engaged when boot, just enable lateral
- reengage lateral if changing lanes and changing the wrong way
- speed limit display / over speed display / trigger set
- hack the buttons so we can press them
- auto set speed limit
- conditional experimenal mode
- ui conditional experimental mode, orange lines, show large font of desired speed in lower left
- hold down button to turn off screen, remember setting
- bluetooth dummy device
- dash cam
- change disk used on sidebar to disk free / percent used
-
- warn if lead is going more than 30 under my speed or 20 if auto mode is off
- mark os version different than release, forcing a os reinstall
- no prompt on os reinstall
Test features wizard:
- read paddles
- read speed
- adjust speed
- cancel / resume
- reset drive mode
- read radar distance
- activate blinkers
Hyundai CLSC
Hyundai Paddle shifter lane change

View File

@@ -1,3 +1,5 @@
Actual log:
- Pause lateral on lane change
- Updated color scheme
- Updated boot / ready logo
@@ -7,4 +9,121 @@
- Removed nearly everything from onroad ui
- Monitor never fully fatals
- Engage / Disengage sounds silenced
- Removed all 'prime' functionality including map features
- Removed all 'Prime' functionality including "Navigate on Openpilot"
Goal, to be able to say:
ClearPilot
-----------------
ClearPilot is a simplified, enhanced, and opinionated modification of OpenPilot
with a focus on a consistency, privacy, and ease of use. The self driving
behaviors compared to OpenPilot have been reduced and simplified to focus on lane keep assistance,
and to disengage more gracefully on operator override behaviors such as highway lane change or
turning at an intersection. It features a redesigned and customized user interface,
a dashcam module with a frontend for reviewing dashcam footage, and tools for managing
device data via wifi or a self hosted web control panel.
ClearPilot aims to provide a consistent, private, and permanent user experience. Feature updates
will not change or remove existing configured features, or de-select or remove older driving models.
The requirement to be online and periodically check for updates has also been removed - you can install
the software once, and never have to update it or go online again.
-------------------
ClearPilot is based on FrogPilot (link), and has been forked from the "May 1st, 2024 Update for FrogPilot
v0.9.7", which itself is based off of "Feb 27th, 2024 OpenPilot 0.9.6" release. It is designed
for use with Comma 3 / 3X and is not compatable with Comma 2 or older.
ClearPilot is open source software and comes with no guaranteel of mercantability or fitness of any kind.
ClearPilot has some features which may violate local laws or guidelines, or Comma OpenPilot developer
safety guidelines, particularly as it relates to driver monitoring. It is your responsibility to ensure
that the software you run is allowed by local reguilations.
It is your responsibility to test the software in a zero traffic environment to evaluate and understand it's behaviors and limitations,
and to validate it is sutable and for your usage. You are responsible for what your Comma device and veichele
does at all times.
The software was provided as is, without any guarantee or promise that it is able to perform any task at all with
or without issue, and useof the software is at your descression and your own risk. (reword)
We need testers! If you would like to help make your car fully compatable with ClearPilot, please
contact the author at xyz.
-------------------------------
Full Feature Set:
Driving:
- Drastically simplified minimal user interface, with a focus on ease of use for non power users.
- Ability to use a car's stock radar / cruise control functionality, while emulating clicks
on the accel + decel buttons to slow down for detected curves. This is for veicheles which
don't support OpenPilot Longitudial Control, or for users who prefer their veicheles stock
radar cruise control feature over OpenPilot Longitudial Control.
- Special support for some specific HKG and Jeep Veichles
- Speed limit control feature - when over or under speed limit, the system prompts
for you to increase or decrease speed to ideal cruising speed.
- Feature to disable lane keep assistance when making a turn at an intersection or lane change on the
freeway. The standard OpenPilot lane change assistance feature is still available.
- Feature to use paddle shifter button to execute a nudgeless assisted lane change at highway speeds.
- Custom trip recording and dashcam module and playback feature.
- Feature to turn off the screen display via steering wheel button.
- Toggle to show camera feed as monochrome for enhanced ui contrast.
- Feature to relax relax driver monitoring requirements & timeouts 50% never / at night / always.
- Feature to enhance driver engagement by requiring hands on wheel never / at night / always.
- Ability to create a second driver profile with settings menu pin lockout which can have
alternative requirements for driver safety, such as requiring hands on the wheel at all times,
or a maximum amount cruise control speed can be set over the posted speed limit.
- Warning when traffic in the distance is dected to be significantly slower than current speed.
- Ability to set a custom startup logo and customize some aspects of the user experience.
- All telemetry, features, and connectivity related to Comma.AI / Comma Prime removed.
- Requirement to get online to update your software every few weeks removed. Checking for a
new version of the software is only done by user request or by enabling automatic update
checks.
- Ability to set wifi networks as prefered or bandwidth limited. If connected to a bandwidth
limited wifi network and a prefered network becomes available, the system will switch to the
prefered network.
- Various automations for other car features on supported veicheles, such as automatic window
roll up and automatically enable HVAC on startup.
- Wifi accessible control panel for for managing device data including dashcam recordings.
- Available self hosted companion application for backing up and managing device data remotly for
power users. You will be able to host your own ClearPilot installer to ensure you permanently
have a copy of the software for your own use.
- Basic Home Assistant integration.
Full documentation for ClearPilot and each of these features is available (here.)
Hidden features, enable by shell:
- Temporarirly suspend monitoring feature. This mode is canceled whenever a sharp
curve is detected, a lead veichele is detected, or lane line detection is weak.
This feature is disabled by default and must me enabled by modifying a file on
- If ClearPilot disengages due to driver monitoring detection issue, it will allow
re-engagement or driver assistance without a system restart.

View File

@@ -21,21 +21,23 @@ const SteeringLimits HYUNDAI_CANFD_STEERING_LIMITS = {
const CanMsg HYUNDAI_CANFD_HDA2_TX_MSGS[] = {
{0x50, 0, 16}, // LKAS
{0x1CF, 1, 8}, // CRUISE_BUTTON
{426, 1, 16}, // CRUISE_BUTTONS_ALT
{0x1AA, 1, 16}, // CRUISE_BUTTONS_ALT
{0x1A0, 1, 32}, // CRUISE_INFO
{0x2A4, 0, 24}, // CAM_0x2A4
};
const CanMsg HYUNDAI_CANFD_HDA2_ALT_STEERING_TX_MSGS[] = {
{0x110, 0, 32}, // LKAS_ALT
{0x1CF, 1, 8}, // CRUISE_BUTTON
{426, 1, 16}, // CRUISE_BUTTONS_ALT
{0x1AA, 1, 16}, // CRUISE_BUTTONS_ALT
{0x1A0, 1, 32}, // CRUISE_INFO
{0x362, 0, 32}, // CAM_0x362
};
const CanMsg HYUNDAI_CANFD_HDA2_LONG_TX_MSGS[] = {
{0x50, 0, 16}, // LKAS
{0x1CF, 1, 8}, // CRUISE_BUTTON
{426, 1, 16}, // CRUISE_BUTTONS_ALT
{0x1AA, 1, 16}, // CRUISE_BUTTONS_ALT
{0x2A4, 0, 24}, // CAM_0x2A4
{0x51, 0, 32}, // ADRV_0x51
{0x730, 1, 8}, // tester present for ADAS ECU disable
@@ -73,9 +75,6 @@ const CanMsg HYUNDAI_CANFD_HDA1_TX_MSGS[] = {
#define HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(pt_bus) \
{.msg = {{0x1aa, (pt_bus), 16, .check_checksum = false, .max_counter = 0xffU, .frequency = 50U}, { 0 }, { 0 }}}, \
#define HYUNDAI_CANFD_ALT_BUTTONS_ADDR_CHECK(pt_bus) \
{.msg = {{0x1aa, (pt_bus), 16, .check_checksum = false, .max_counter = 0xffU, .frequency = 50U}, { 0 }, { 0 }}}, \
// SCC_CONTROL (from ADAS unit or camera)
#define HYUNDAI_CANFD_SCC_ADDR_CHECK(scc_bus) \
{.msg = {{0x1a0, (scc_bus), 32, .check_checksum = true, .max_counter = 0xffU, .frequency = 50U}, { 0 }, { 0 }}}, \
@@ -404,26 +403,26 @@ BO_ 1151 HVAC_TOUCH_BUTTONS: 8 XXX
}
// ACCEL: safety check
if (addr == 0x1a0) {
int desired_accel_raw = (((GET_BYTE(to_send, 17) & 0x7U) << 8) | GET_BYTE(to_send, 16)) - 1023U;
int desired_accel_val = ((GET_BYTE(to_send, 18) << 4) | (GET_BYTE(to_send, 17) >> 4)) - 1023U;
// if (addr == 0x1a0) {
// int desired_accel_raw = (((GET_BYTE(to_send, 17) & 0x7U) << 8) | GET_BYTE(to_send, 16)) - 1023U;
// int desired_accel_val = ((GET_BYTE(to_send, 18) << 4) | (GET_BYTE(to_send, 17) >> 4)) - 1023U;
bool violation = false;
// bool violation = false;
if (hyundai_longitudinal) {
violation |= longitudinal_accel_checks(desired_accel_raw, HYUNDAI_LONG_LIMITS);
violation |= longitudinal_accel_checks(desired_accel_val, HYUNDAI_LONG_LIMITS);
} else {
// only used to cancel on here
if ((desired_accel_raw != 0) || (desired_accel_val != 0)) {
violation = true;
}
}
// if (hyundai_longitudinal) {
// violation |= longitudinal_accel_checks(desired_accel_raw, HYUNDAI_LONG_LIMITS);
// violation |= longitudinal_accel_checks(desired_accel_val, HYUNDAI_LONG_LIMITS);
// } else {
// // only used to cancel on here
// if ((desired_accel_raw != 0) || (desired_accel_val != 0)) {
// violation = true;
// }
// }
if (violation) {
tx = false;
}
}
// if (violation) {
// tx = false;
// }
// }
return tx;
}
@@ -443,10 +442,14 @@ static int hyundai_canfd_fwd_hook(int bus_num, int addr) {
// HUD icons
bool is_lfahda_msg = ((addr == 0x1e0) && !hyundai_canfd_hda2);
// Cruise Alt Buttons
bool is_cruise_alt_buttons = (addr == 0x1aa); // && hyundai_canfd_hda2);
// CRUISE_INFO for non-HDA2, we send our own longitudinal commands
bool is_scc_msg = ((addr == 0x1a0) && hyundai_longitudinal && !hyundai_canfd_hda2);
bool block_msg = is_lkas_msg || is_lfa_msg || is_lfahda_msg || is_scc_msg;
bool block_msg = is_lkas_msg || is_lfa_msg || is_lfahda_msg || is_scc_msg
|| is_cruise_alt_buttons;
if (!block_msg) {
bus_fwd = 0;
}

View File

@@ -123,9 +123,11 @@ class CarController(CarControllerBase):
if self.frame % 5 == 0 and (not hda2 or hda2_long):
# CLEARPILOT TEST self.CS.lkas_enabled
# can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled, CC.latActive))
params_memory = Params("/dev/shm/params")
lkas_icon = params_memory.get_bool("CPTLkasButtonAction") or CS.lkas_enabled
can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, lkas_icon, lkas_icon))
# params_memory = Params("/dev/shm/params")
# lkas_icon = params_memory.get_bool("CPTLkasButtonAction") or CS.lkas_enabled
# lkas_icon = CS.experimentalMode
can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, False, False))
# can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CS.experimentalMode, False))
# blinkers
if hda2 and self.CP.flags & HyundaiFlags.ENABLE_BLINKERS:
@@ -133,26 +135,29 @@ class CarController(CarControllerBase):
# params_memory = Params("/dev/shm/params")
# if params_memory.get_bool("CPTLkasButtonAction"):
# if self.frame % 10 == 0:
# for _ in range(20):
# can_sends.append(hyundaicanfd.create_buttons_alt(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.SET_DECEL))
# can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame))
# can_sends.append(hyundaicanfd.create_acc_set_speed(self.packer, self.CP, self.CAN, CS.cruise_info, 50))
# can_sends.append(hyundaicanfd.create_acc_cancel(self.packer, self.CP, self.CAN, CS.cruise_info))
# print("Debug cancel executed")
if self.CP.openpilotLongitudinalControl:
if self.CP.openpilotLongitudinalControl: # or CS.experimentalMode:
if hda2:
can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame))
if self.frame % 2 == 0:
can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CC.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override,
set_speed_in_units, hud_control))
self.accel_last = accel
else:
# else:
# Clearpilot
# If cruise control was enabled or idle on start, force cancel
# if CS.fix_main_enabled_cancel_main:
# CS.fix_main_enabled_cancel_main = False
# CC.cruiseControl.cancel = True
# button presses
can_sends.extend(self.create_button_messages(CC, CS, use_clu11=False))
# can_sends.extend(self.create_button_messages(CC, CS, use_clu11=False))
else:
can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.CP, apply_steer, apply_steer_req,
torque_fault, CS.lkas11, sys_warning, sys_state, CC.enabled,
@@ -197,7 +202,6 @@ class CarController(CarControllerBase):
can_sends = []
if use_clu11:
if CC.cruiseControl.cancel:
print("Cancel button go")
can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP))
CS.lkas_trigger_result = 5
elif CC.cruiseControl.resume:
@@ -209,18 +213,21 @@ class CarController(CarControllerBase):
self.last_button_frame = self.frame
else:
if (self.frame - self.last_button_frame) * DT_CTRL > 0.25:
params_memory = Params("/dev/shm/params")
if params_memory.get_bool("CPTLkasButtonAction"):
params_memory.put_bool("CPTLkasButtonAction", False)
CC.cruiseControl.cancel = True
print("Debug cancel executed")
# params_memory = Params("/dev/shm/params")
# if params_memory.get_bool("CPTLkasButtonAction"):
# params_memory.put_bool("CPTLkasButtonAction", False)
# CC.cruiseControl.cancel = True
# print("Debug cancel executed")
# cruise cancel
if CC.cruiseControl.cancel:
if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
# pass
can_sends.append(hyundaicanfd.create_acc_cancel(self.packer, self.CP, self.CAN, CS.cruise_info))
# can_sends.append(hyundaicanfd.create_acc_cancel(self.packer, self.CP, self.CAN, CS.cruise_info))
# for _ in range(20):
# can_sends.append(hyundaicanfd.create_buttons_alt(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.CANCEL))
print("Yes2")
# if CS.cruise_can_msg:
# can_sends.append(hyundaicanfd.create_buttons_alt(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.CANCEL, CS.cruise_can_msg))
# print("Try Cancel Button Alt")
self.last_button_frame = self.frame
CS.lkas_trigger_result = 1
else:

View File

@@ -209,8 +209,10 @@ class CarState(CarStateBase):
self.lkas_previously_enabled = self.lkas_enabled
self.lkas_enabled = cp.vl["BCM_PO_11"]["LFA_Pressed"]
self.params_memory.put_int("CarSpeedLimitLiteral", self.calculate_speed_limit(cp, cp_cam))
# self.params_memory.put_int("CarSpeedLimitLiteral", self.calculate_speed_limit(cp, cp_cam))
self.params_memory.put_float("CarSpeedLimit", self.calculate_speed_limit(cp, cp_cam) * speed_conv)
self.params_memory.put_float("CarCruiseDisplayActual", cp_cruise.vl["SCC11"]["VSetDis"])
return ret
@@ -288,6 +290,7 @@ class CarState(CarStateBase):
ret.cruiseState.nonAdaptive = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]["MSLA_ENABLED"] == 1
self.cruise_can_msg = copy.copy(cp.vl_all[self.cruise_btns_msg_canfd])
# print(self.cruise_can_msg)
self.prev_cruise_buttons = self.cruise_buttons[-1]
self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"])
@@ -414,7 +417,7 @@ class CarState(CarStateBase):
# print("Set limit")
# print(self.calculate_speed_limit(cp, cp_cam))
self.params_memory.put_float("CarSpeedLimitLiteral", self.calculate_speed_limit(cp, cp_cam))
# self.params_memory.put_float("CarSpeedLimitLiteral", self.calculate_speed_limit(cp, cp_cam))
self.params_memory.put_float("CarSpeedLimit", self.calculate_speed_limit(cp, cp_cam) * speed_factor)
return ret

View File

@@ -88,18 +88,90 @@ def create_buttons(packer, CP, CAN, cnt, btn):
bus = CAN.ECAN if CP.flags & HyundaiFlags.CANFD_HDA2 else CAN.CAM
return packer.make_can_msg("CRUISE_BUTTONS", bus, values)
def create_buttons_alt(packer, CP, CAN, cnt, btn):
# null
# {'CHECKSUM': [], 'COUNTER': [], 'NEW_SIGNAL_1': [], 'SET_ME_1': [], 'DISTANCE_UNIT': [],
# 'NEW_SIGNAL_2': [], 'ADAPT
# IVE_CRUISE_MAIN_BTN': [], 'NEW_SIGNAL_3': [], 'LFA_BTN': [], 'CRUISE_BUTTONS': [],
# 'NEW_SIGNAL_4': [], 'NORMAL_CRUI
# SE_MAIN_BTN': [], 'NEW_SIGNAL_5': [], 'SET_ME_2': [], 'NEW_SIGNAL_6': [], 'BYTE6': [],
# 'BYTE7': [], 'BYTE8': [], 'B
# YTE9': [], 'BYTE10': [], 'BYTE11': [], 'BYTE12': [], 'BYTE13': [], 'BYTE14': [],
# 'BYTE15': []}
# holding down up button
# {'CHECKSUM': [5774.0], 'COUNTER': [63.0], 'NEW_SIGNAL_1': [0.0], 'SET_ME_1':
# [0.0], 'DISTANCE_UNIT': [1.0], 'NEW_SIGNAL_2': [4.0], 'ADAPTIVE_CRUISE_MAIN_BTN':
# [0.0], 'NEW_SIGNAL_3': [0.0], 'LFA_BTN': [0.0], 'CRUISE_BUTTONS': [1.0],
# 'NEW_SIGNAL_4': [0.0], 'NORMAL_CRUISE_MAIN_BTN': [0.0], 'NEW_SIGNAL_5': [0.0],
# 'SET_ME_2': [2.0], 'NEW_SIGNAL_6': [1.0], 'BYTE6': [32.0], 'BYTE7': [0.0],
# 'BYTE8': [26.0], 'BYTE9': [0.0], 'BYTE10': [0.0], 'BYTE11': [0.0], 'BYTE12':
# [0.0], 'BYTE13': [0.0], 'BYTE14': [0.0], 'BYTE15': [0.0]}
# {'CHECKSUM': [14783.0], 'COUNTER': [150.0], 'NEW_SIGNAL_1': [0.0],
# 'SET_ME_1': [0.0], 'DISTANCE_UNIT': [1.0], 'NEW_
# SIGNAL_2': [6.0], 'ADAPTIVE_CRUISE_MAIN_BTN': [0.0], 'NEW_SIGNAL_3': [0.0],
# 'LFA_BTN': [0.0], 'CRUISE_BUTTONS': [1.
# 0], 'NEW_SIGNAL_4': [0.0], 'NORMAL_CRUISE_MAIN_BTN': [0.0], 'NEW_SIGNAL_5':
# [0.0], 'SET_ME_2': [2.0], 'NEW_SIGNAL_6
# ': [1.0], 'BYTE6': [37.0], 'BYTE7': [0.0], 'BYTE8': [30.0], 'BYTE9': [0.0],
# 'BYTE10': [0.0], 'BYTE11': [0.0], 'BYTE
# 12': [0.0], 'BYTE13': [0.0], 'BYTE14': [0.0], 'BYTE15': [0.0]}
# {'CHECKSUM': [61602.0], 'COUNTER': [153.0], 'NEW_SIGNAL_1': [0.0], 'SET_ME_1':
# [0.0], 'DISTANCE_UNIT': [1.0], 'NEW_
# SIGNAL_2': [0.0], 'ADAPTIVE_CRUISE_MAIN_BTN': [0.0], 'NEW_SIGNAL_3': [0.0],
# 'LFA_BTN': [1.0], 'CRUISE_BUTTONS': [1.
# 0], 'NEW_SIGNAL_4': [0.0], 'NORMAL_CRUISE_MAIN_BTN': [0.0], 'NEW_SIGNAL_5':
# [0.0], 'SET_ME_2': [2.0], 'NEW_SIGNAL_6
# ': [1.0], 'BYTE6': [38.0], 'BYTE7': [0.0], 'BYTE8': [31.0], 'BYTE9': [0.0],
# 'BYTE10': [0.0], 'BYTE11': [0.0], 'BYTE
# 12': [0.0], 'BYTE13': [0.0], 'BYTE14': [0.0], 'BYTE15': [0.0]}
def create_buttons_alt(packer, CP, CAN, cnt, btn, template):
return
params_memory = Params("/dev/shm/params")
CarCruiseDisplayActual = params_memory.get_float("CarCruiseDisplayActual")
values = {
"COUNTER": cnt,
"SET_ME_1": 1,
"SET_ME_2": 2,
"CRUISE_BUTTONS": btn,
"NEW_SIGNAL_1": 0.0,
"DISTANCE_UNIT": 1.0,
"SET_ME_1": 0.0,
"NEW_SIGNAL_2": 0.0,
"ADAPTIVE_CRUISE_MAIN_BTN": 0.0,
"NEW_SIGNAL_3": 0.0,
"CRUISE_BUTTONS": 1.0, #btn * 1.0,
"NEW_SIGNAL_4": 0.0,
"NORMAL_CRUISE_MAIN_BTN": 0.0,
"NEW_SIGNAL_5": 0.0,
"SET_ME_2": 2.0,
"NEW_SIGNAL_5": 1.0,
# "BYTE_6": CarCruiseDisplayActual+1, # Target
# "BYTE_7": 0.0,
# "BYTE_8": CarCruiseDisplayActual, # Current cruise sets
# "BYTE_9": 0.0,
# "BYTE_10": 0.0,
# "BYTE_11": 0.0,
# "BYTE_12": 0.0,
# "BYTE_13": 0.0,
# "BYTE_14": 0.0,
# "BYTE_15": 0.0,
}
bus = CAN.ECAN # if CP.flags & HyundaiFlags.CANFD_HDA2 else CAN.CAM
return packer.make_can_msg("CRUISE_BUTTONS_ALT", bus, values)
# def create_buttons_alt(packer, CP, CAN, cnt, btn, template):
# template.update({
# "CRUISE_BUTTONS": btn
# })
# bus = CAN.ECAN # if CP.flags & HyundaiFlags.CANFD_HDA2 else CAN.CAM
# return packer.make_can_msg("CRUISE_BUTTONS_ALT", bus, template)
def create_acc_set_speed(packer, CP, CAN, cruise_info_copy, speed):
# why are we executing this at all?
# TODO: why do we copy different values here?
@@ -132,7 +204,7 @@ def create_acc_set_speed(packer, CP, CAN, cruise_info_copy, speed):
def create_acc_cancel(packer, CP, CAN, cruise_info_copy):
# why are we executing this at all?
# This does nothing on the tucson
# TODO: why do we copy different values here?
if CP.flags & HyundaiFlags.CANFD_CAMERA_SCC.value:
values = {s: cruise_info_copy[s] for s in [
@@ -156,7 +228,7 @@ def create_acc_cancel(packer, CP, CAN, cruise_info_copy):
"CRUISE_STANDSTILL",
]}
values.update({
"ACCMode": 0, # testing 1 instead of 4
"ACCMode": 4, # testing 1 instead of 4
"aReqRaw": 0.0,
"aReqValue": 0.0,
})
@@ -164,10 +236,10 @@ def create_acc_cancel(packer, CP, CAN, cruise_info_copy):
# CLEARPILOT changed HDA icons
# This doesn't appear to do anything on my tucson
def create_lfahda_cluster(packer, CAN, enabled, lat_active):
def create_lfahda_cluster(packer, CAN, experimental, lat_active):
values = {
"HDA_ICON": 0, # Literally shows HDA. Maybe we use this to indicate experimental mode
"LFA_ICON": 2 if enabled else 1 if lat_active else 0
"LFA_ICON": 2 if experimental else 0
}
return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values)
@@ -203,6 +275,37 @@ def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_ov
return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values)
def create_acc_control_alt(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control):
jerk = 5
jn = jerk / 50
if not enabled or gas_override:
a_val, a_raw = 0, 0
else:
a_raw = accel
a_val = clip(accel, accel_last - jn, accel_last + jn)
values = {
"ACCMode": 0 if not enabled else (2 if gas_override else 1),
"MainMode_ACC": 1,
"StopReq": 1 if stopping else 0,
"aReqValue": a_val,
"aReqRaw": a_raw,
"VSetDis": set_speed,
"JerkLowerLimit": jerk if enabled else 1,
"JerkUpperLimit": 3.0,
"ACC_ObjDist": 1,
"ObjValid": 0,
"OBJ_STATUS": 2,
"SET_ME_2": 0x4,
"SET_ME_3": 0x3,
"SET_ME_TMP_64": 0x64,
"DISTANCE_SETTING": hud_control.leadDistanceBars,
}
return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values)
# Disabled blinker messages
def create_spas_messages(packer, CAN, frame, left_blink, right_blink):
ret = []

0
selfdrive/clearpilot/resource/debug_ui_scene.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

@@ -76,6 +76,9 @@ class Controls:
self.params_memory = Params("/dev/shm/params")
self.params_storage = Params("/persist/params")
self.params_memory.put_bool("CPTLkasButtonAction", False)
self.params_memory.put_bool("ScreenDisaplayMode", 0)
self.radarless_model = self.params.get("Model", encoding='utf-8') in RADARLESS_MODELS
with car.CarParams.from_bytes(self.params.get("CarParams", block=True)) as msg:
@@ -673,9 +676,9 @@ class Controls:
if model_v2.meta.laneChangeState == LaneChangeState.laneChangeStarting and clearpilot_disable_lat_on_lane_change:
CC.latActive = False
self.params_memory.put_int("no_lat_lane_change", 1)
self.params_memory.put_bool("no_lat_lane_change", True)
else:
self.params_memory.put_int("no_lat_lane_change", 0)
self.params_memory.put_bool("no_lat_lane_change", False)
if CS.leftBlinker or CS.rightBlinker:
self.last_blinker_frame = self.sm.frame
@@ -1131,13 +1134,13 @@ class Controls:
self.drive_added = True
# Clearpilot - todo: override conditional on cruise button tap
# if any(be.pressed and be.type == FrogPilotButtonType.lkas for be in CS.buttonEvents) and self.experimental_mode_via_lkas:
# if self.frogpilot_variables.conditional_experimental_mode:
# conditional_status = self.params_memory.get_int("CEStatus")
# override_value = 0 if conditional_status in {1, 2, 3, 4, 5, 6} else 3 if conditional_status >= 7 else 4
# self.params_memory.put_int("CEStatus", override_value)
# else:
# self.params.put_bool_nonblocking("ExperimentalMode", not self.experimental_mode)
if any(be.pressed and be.type == FrogPilotButtonType.lkas for be in CS.buttonEvents) and self.experimental_mode_via_lkas:
if self.frogpilot_variables.conditional_experimental_mode:
conditional_status = self.params_memory.get_int("CEStatus")
override_value = 0 if conditional_status in {1, 2, 3, 4, 5, 6} else 3 if conditional_status >= 7 else 4
self.params_memory.put_int("CEStatus", override_value)
else:
self.params.put_bool_nonblocking("ExperimentalMode", not self.experimental_mode)
self.previously_enabled |= (self.enabled or self.FPCC.alwaysOnLateral) and CS.vEgo > CRUISING_SPEED
self.previously_enabled &= self.driving_gear
@@ -1237,16 +1240,21 @@ class Controls:
def clearpilot_state_control(self, CC, CS):
if any(be.pressed and be.type == FrogPilotButtonType.lkas for be in CS.buttonEvents):
# self.params_memory.put_bool("CPTLkasButtonAction", True)
if self.params_memory.get_bool("CPTLkasButtonAction"):
self.params_memory.put_bool("CPTLkasButtonAction", False)
else:
self.params_memory.put_bool("CPTLkasButtonAction", True)
# CS.lkas_enabled = self.params_memory.get_bool("CPTLkasButtonAction")
self.params_memory.put_int("SpeedLimitLatDesired", CC.actuators.speed * CV.MS_TO_MPH )
# CC.actuators.speed
# print ("Alive")
# if self.params_memory.get_bool("CPTLkasButtonAction"):
# self.params_memory.put_bool("CPTLkasButtonAction", False)
# else:
# self.params_memory.put_bool("CPTLkasButtonAction", True)
# Rotate display mode. These are mostly used in the frontend ui app.
max_display_mode = 1
current_display_mode = self.params_memory.get_int("ScreenDisaplayMode")
current_display_mode = current_display_mode + 1
if current_display_mode > max_display_mode:
current_display_mode = 0
self.params_memory.put_int("ScreenDisaplayMode", current_display_mode)
# self.params_memory.put_int("SpeedLimitLatDesired", CC.actuators.speed * CV.MS_TO_MPH )
return CC
def main():

View File

@@ -274,7 +274,7 @@ class FrogPilotPlanner:
frogpilotPlan.vtscControllingCurve = bool(self.mtsc_target > self.vtsc_target)
self.params_memory.put_int("SpeedLimitVTSC", frogpilotPlan.adjustedCruise)
# self.params_memory.put_int("SpeedLimitVTSC", frogpilotPlan.adjustedCruise)
pm.send('frogpilotPlan', frogpilot_plan_send)

View File

@@ -149,6 +149,9 @@ def manager_init(frogpilot_functions) -> None:
("ForceFingerprint", "0"),
("ForceMPHDashboard", "0"),
("FPSCounter", "0"),
("FrogPilotDrives", "0"),
("FrogPilotKilometers", "0"),
("FrogPilotMinutes", "0"),
("FrogsGoMooTune", "1"),
("FullMap", "0"),
("GasRegenCmd", "0"),
@@ -169,7 +172,7 @@ def manager_init(frogpilot_functions) -> None:
("IncreaseThermalLimits", "0"),
("LaneChangeTime", "0"),
("LaneDetectionWidth", "60"),
("LaneLinesWidth", "2"),
("LaneLinesWidth", "4"),
("LateralTune", "1"),
("LeadDepartingAlert", "0"),
("LeadDetectionThreshold", "35"),
@@ -179,14 +182,6 @@ def manager_init(frogpilot_functions) -> None:
("LongPitch", "1"),
("LoudBlindspotAlert", "0"),
("LowVoltageShutdown", "11.8"),
("kiV1", "0.60"),
("kiV2", "0.45"),
("kiV3", "0.30"),
("kiV4", "0.15"),
("kpV1", "1.50"),
("kpV2", "1.00"),
("kpV3", "0.75"),
("kpV4", "0.50"),
("MapsSelected", ""),
("MapboxPublicKey", ""),
("MapboxSecretKey", ""),
@@ -277,7 +272,6 @@ def manager_init(frogpilot_functions) -> None:
("TrafficFollow", "0.5"),
("TrafficJerk", "1"),
("TrafficMode", "0"),
("Tuning", "1"),
("TurnAggressiveness", "100"),
("TurnDesires", "0"),
("UnlimitedLength", "1"),
@@ -341,14 +335,14 @@ def manager_init(frogpilot_functions) -> None:
os.environ['CLEAN'] = '1'
# init logging
# sentry.init(sentry.SentryProject.SELFDRIVE)
# cloudlog.bind_global(dongle_id=dongle_id,
# version=get_version(),
# origin=get_normalized_origin(),
# branch=get_short_branch(),
# commit=get_commit(),
# dirty=is_dirty(),
# device=HARDWARE.get_device_type())
sentry.init(sentry.SentryProject.SELFDRIVE)
cloudlog.bind_global(dongle_id=dongle_id,
version=get_version(),
origin=get_normalized_origin(),
branch=get_short_branch(),
commit=get_commit(),
dirty=is_dirty(),
device=HARDWARE.get_device_type())
# preimport all processes
for p in managed_processes.values():
@@ -366,11 +360,8 @@ def manager_cleanup() -> None:
cloudlog.info("everything is dead")
last_running = ""
def manager_thread(frogpilot_functions) -> None:
global last_running
cloudlog.bind(daemon="manager")
cloudlog.info("manager start")
cloudlog.info({"environ": os.environ})
@@ -422,12 +413,8 @@ def manager_thread(frogpilot_functions) -> None:
running = ' '.join("{}{}\u001b[0m".format("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
for p in managed_processes.values() if p.proc)
# clearpilot
if (running != last_running):
print(running)
cloudlog.debug(running)
last_running = running
# send managerState
msg = messaging.new_message('managerState', valid=True)
@@ -436,7 +423,7 @@ def manager_thread(frogpilot_functions) -> None:
# Exit main loop when uninstall/shutdown/reboot is needed
shutdown = False
for param in ("DoUninstall", "DoShutdown", "DoReboot", "DoSoftReboot"):
for param in ("DoUninstall", "DoShutdown", "DoReboot"):
if params.get_bool(param):
shutdown = True
params.put("LastManagerExitReason", f"{param} {datetime.datetime.now()}")
@@ -477,9 +464,6 @@ def main() -> None:
elif params.get_bool("DoReboot"):
cloudlog.warning("reboot")
HARDWARE.reboot()
elif params.get_bool("DoSoftReboot"):
cloudlog.warning("softreboot")
HARDWARE.soft_reboot()
elif params.get_bool("DoShutdown"):
cloudlog.warning("shutdown")
HARDWARE.shutdown()

View File

@@ -0,0 +1,519 @@
#!/usr/bin/env python3
import datetime
import os
import signal
import subprocess
import sys
import threading
import time
import traceback
from cereal import log
import cereal.messaging as messaging
import openpilot.selfdrive.sentry as sentry
from openpilot.common.params import Params, ParamKeyType
from openpilot.common.text_window import TextWindow
from openpilot.common.time import system_time_valid
from openpilot.system.hardware import HARDWARE, PC
from openpilot.selfdrive.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog
from openpilot.selfdrive.manager.process import ensure_running
from openpilot.selfdrive.manager.process_config import managed_processes
from openpilot.selfdrive.athena.registration import register, UNREGISTERED_DONGLE_ID
from openpilot.common.swaglog import cloudlog, add_file_handler
from openpilot.system.version import is_dirty, get_commit, get_version, get_origin, get_short_branch, \
get_normalized_origin, terms_version, training_version, \
is_tested_branch, is_release_branch, get_commit_date
from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import FrogPilotFunctions
from openpilot.selfdrive.frogpilot.controls.lib.model_manager import DEFAULT_MODEL, DEFAULT_MODEL_NAME, delete_deprecated_models
def frogpilot_boot_functions(frogpilot_functions):
try:
delete_deprecated_models()
while not system_time_valid():
print("Waiting for system time to become valid...")
time.sleep(1)
try:
frogpilot_functions.backup_frogpilot()
except subprocess.CalledProcessError as e:
print(f"Failed to backup FrogPilot. Error: {e}")
return
try:
frogpilot_functions.backup_toggles()
except subprocess.CalledProcessError as e:
print(f"Failed to backup toggles. Error: {e}")
return
except Exception as e:
print(f"An unexpected error occurred: {e}")
def manager_init(frogpilot_functions) -> None:
timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
log_dir = f"/data/log2/{timestamp}"
os.makedirs(log_dir, exist_ok=True)
frogpilot_boot = threading.Thread(target=frogpilot_boot_functions, args=(frogpilot_functions,))
frogpilot_boot.start()
save_bootlog()
params = Params()
params_storage = Params("/persist/params")
params.clear_all(ParamKeyType.CLEAR_ON_MANAGER_START)
params.clear_all(ParamKeyType.CLEAR_ON_ONROAD_TRANSITION)
params.clear_all(ParamKeyType.CLEAR_ON_OFFROAD_TRANSITION)
if is_release_branch():
params.clear_all(ParamKeyType.DEVELOPMENT_ONLY)
default_params: list[tuple[str, str | bytes]] = [
("CarParamsPersistent", ""),
("CompletedTrainingVersion", "0"),
("DisengageOnAccelerator", "0"),
("ExperimentalLongitudinalEnabled", "1"),
("GsmMetered", "1"),
("HasAcceptedTerms", "0"),
("IsLdwEnabled", "0"),
("IsMetric", "0"),
("LanguageSetting", "main_en"),
("NavSettingLeftSide", "0"),
("NavSettingTime24h", "0"),
("OpenpilotEnabledToggle", "1"),
("RecordFront", "0"),
("LongitudinalPersonality", str(log.LongitudinalPersonality.standard)),
# Default FrogPilot parameters
("AccelerationPath", "1"),
("AccelerationProfile", "2"),
("AdjacentPath", "0"),
("AdjacentPathMetrics", "0"),
("AggressiveAcceleration", "1"),
("AggressiveFollow", "1.25"),
("AggressiveJerk", "0.5"),
("AlertVolumeControl", "0"),
("AlwaysOnLateral", "1"),
("AlwaysOnLateralMain", "0"),
("AMapKey1", ""),
("AMapKey2", ""),
("AutomaticUpdates", "0"),
("BlindSpotPath", "1"),
("CameraView", "2"),
("CarMake", ""),
("CarModel", ""),
("CECurves", "1"),
("CENavigation", "1"),
("CENavigationIntersections", "1"),
("CENavigationLead", "1"),
("CENavigationTurns", "1"),
("CESignal", "1"),
("CESlowerLead", "1"),
("CESpeed", "0"),
("CESpeedLead", "0"),
("CEStopLights", "1"),
("CEStopLightsLead", "0"),
("Compass", "1"),
("ConditionalExperimental", "1"),
("CrosstrekTorque", "1"),
("CurveSensitivity", "100"),
("CustomAlerts", "1"),
("CustomColors", "1"),
("CustomCruise", "1"),
("CustomCruiseLong", "5"),
("CustomIcons", "1"),
("CustomPaths", "1"),
("CustomPersonalities", "1"),
("CustomSignals", "1"),
("CustomSounds", "1"),
("CustomTheme", "1"),
("CustomUI", "1"),
("CydiaTune", "0"),
("DecelerationProfile", "1"),
("DeveloperUI", "0"),
("DeviceManagement", "1"),
("DeviceShutdown", "9"),
("DisableMTSCSmoothing", "0"),
("DisableOnroadUploads", "0"),
("DisableOpenpilotLongitudinal", "0"),
("DisableVTSCSmoothing", "0"),
("DisengageVolume", "100"),
("DragonPilotTune", "0"),
("DriverCamera", "0"),
("DynamicPathWidth", "0"),
("EngageVolume", "100"),
("EVTable", "1"),
("ExperimentalModeActivation", "1"),
("ExperimentalModeViaDistance", "1"),
("ExperimentalModeViaLKAS", "1"),
("ExperimentalModeViaTap", "0"),
("Fahrenheit", "0"),
("ForceAutoTune", "1"),
("ForceFingerprint", "0"),
("ForceMPHDashboard", "0"),
("FPSCounter", "0"),
("FrogsGoMooTune", "1"),
("FullMap", "0"),
("GasRegenCmd", "0"),
("GMapKey", ""),
("GoatScream", "1"),
("GreenLightAlert", "0"),
("HideAlerts", "0"),
("HideAOLStatusBar", "0"),
("HideCEMStatusBar", "0"),
("HideLeadMarker", "0"),
("HideMapIcon", "0"),
("HideMaxSpeed", "0"),
("HideSpeed", "0"),
("HideSpeedUI", "0"),
("HideUIElements", "0"),
("HigherBitrate", "0"),
("HolidayThemes", "1"),
("IncreaseThermalLimits", "0"),
("LaneChangeTime", "0"),
("LaneDetectionWidth", "60"),
("LaneLinesWidth", "2"),
("LateralTune", "1"),
("LeadDepartingAlert", "0"),
("LeadDetectionThreshold", "35"),
("LeadInfo", "0"),
("LockDoors", "1"),
("LongitudinalTune", "1"),
("LongPitch", "1"),
("LoudBlindspotAlert", "0"),
("LowVoltageShutdown", "11.8"),
("kiV1", "0.60"),
("kiV2", "0.45"),
("kiV3", "0.30"),
("kiV4", "0.15"),
("kpV1", "1.50"),
("kpV2", "1.00"),
("kpV3", "0.75"),
("kpV4", "0.50"),
("MapsSelected", ""),
("MapboxPublicKey", ""),
("MapboxSecretKey", ""),
("MapStyle", "0"),
("MTSCAggressiveness", "100"),
("MTSCCurvatureCheck", "0"),
("Model", DEFAULT_MODEL),
("ModelName", DEFAULT_MODEL_NAME),
("ModelSelector", "1"),
("ModelUI", "1"),
("MTSCEnabled", "1"),
("NNFF", "1"),
("NNFFLite", "1"),
("NoLogging", "0"),
("NoUploads", "0"),
("NudgelessLaneChange", "1"),
("NumericalTemp", "0"),
("OfflineMode", "1"),
("Offset1", "5"),
("Offset2", "5"),
("Offset3", "5"),
("Offset4", "10"),
("OneLaneChange", "1"),
("OnroadDistanceButton", "0"),
("PathEdgeWidth", "20"),
("PathWidth", "61"),
("PauseAOLOnBrake", "0"),
("PauseLateralOnSignal", "0"),
("PedalsOnUI", "1"),
("PreferredSchedule", "0"),
("PromptVolume", "100"),
("PromptDistractedVolume", "100"),
("QOLControls", "1"),
("QOLVisuals", "1"),
("RandomEvents", "0"),
("RefuseVolume", "100"),
("RelaxedFollow", "1.75"),
("RelaxedJerk", "1.0"),
("ReverseCruise", "0"),
("ReverseCruiseUI", "1"),
("RoadEdgesWidth", "2"),
("RoadNameUI", "1"),
("RotatingWheel", "1"),
("ScreenBrightness", "101"),
("ScreenBrightnessOnroad", "101"),
("ScreenManagement", "1"),
("ScreenRecorder", "1"),
("ScreenTimeout", "30"),
("ScreenTimeoutOnroad", "30"),
("SearchInput", "0"),
("SetSpeedLimit", "0"),
("SetSpeedOffset", "0"),
("ShowCPU", "0"),
("ShowGPU", "0"),
("ShowIP", "0"),
("ShowJerk", "1"),
("ShowMemoryUsage", "0"),
("ShowSLCOffset", "1"),
("ShowSLCOffsetUI", "1"),
("ShowStorageLeft", "0"),
("ShowStorageUsed", "0"),
("ShowTuning", "1"),
("Sidebar", "0"),
("SLCConfirmation", "1"),
("SLCConfirmationLower", "1"),
("SLCConfirmationHigher", "1"),
("SLCFallback", "2"),
("SLCLookaheadHigher", "5"),
("SLCLookaheadLower", "5"),
("SLCOverride", "1"),
("SLCPriority1", "Dashboard"),
("SLCPriority2", "Offline Maps"),
("SLCPriority3", "Navigation"),
("SmoothBraking", "1"),
("SmoothBrakingFarLead", "0"),
("SmoothBrakingJerk", "0"),
("SNGHack", "1"),
("SpeedLimitChangedAlert", "1"),
("SpeedLimitController", "1"),
("StandardFollow", "1.45"),
("StandardJerk", "1.0"),
("StandbyMode", "0"),
("SteerRatio", "0"),
("StockTune", "0"),
("StoppingDistance", "0"),
("TacoTune", "1"),
("ToyotaDoors", "0"),
("TrafficFollow", "0.5"),
("TrafficJerk", "1"),
("TrafficMode", "0"),
("Tuning", "1"),
("TurnAggressiveness", "100"),
("TurnDesires", "0"),
("UnlimitedLength", "1"),
("UnlockDoors", "1"),
("UseSI", "1"),
("UseVienna", "0"),
("VisionTurnControl", "1"),
("WarningSoftVolume", "100"),
("WarningImmediateVolume", "100"),
("WheelIcon", "3"),
("WheelSpeed", "0")
]
if not PC:
default_params.append(("LastUpdateTime", datetime.datetime.utcnow().isoformat().encode('utf8')))
if params.get_bool("RecordFrontLock"):
params.put_bool("RecordFront", True)
# set unset params
for k, v in default_params:
if params.get(k) is None:
if params_storage.get(k) is None:
params.put(k, v)
else:
params.put(k, params_storage.get(k))
else:
params_storage.put(k, params.get(k))
# Create folders needed for msgq
try:
os.mkdir("/dev/shm")
except FileExistsError:
pass
except PermissionError:
print("WARNING: failed to make /dev/shm")
# set version params
params.put("Version", get_version())
params.put("TermsVersion", terms_version)
params.put("TrainingVersion", training_version)
params.put("GitCommit", get_commit())
params.put("GitCommitDate", get_commit_date())
params.put("GitBranch", get_short_branch())
params.put("GitRemote", get_origin())
params.put_bool("IsTestedBranch", is_tested_branch())
params.put_bool("IsReleaseBranch", is_release_branch())
# set dongle id
reg_res = register(show_spinner=True)
if reg_res:
dongle_id = reg_res
else:
serial = params.get("HardwareSerial")
raise Exception(f"Registration failed for device {serial}")
os.environ['DONGLE_ID'] = dongle_id # Needed for swaglog
os.environ['GIT_ORIGIN'] = get_normalized_origin() # Needed for swaglog
os.environ['GIT_BRANCH'] = get_short_branch() # Needed for swaglog
os.environ['GIT_COMMIT'] = get_commit() # Needed for swaglog
if not is_dirty():
os.environ['CLEAN'] = '1'
# init logging
# sentry.init(sentry.SentryProject.SELFDRIVE)
# cloudlog.bind_global(dongle_id=dongle_id,
# version=get_version(),
# origin=get_normalized_origin(),
# branch=get_short_branch(),
# commit=get_commit(),
# dirty=is_dirty(),
# device=HARDWARE.get_device_type())
# preimport all processes
for p in managed_processes.values():
p.prepare()
return log_dir
def manager_cleanup() -> None:
# send signals to kill all procs
for p in managed_processes.values():
p.stop(block=False)
# ensure all are killed
for p in managed_processes.values():
p.stop(block=True)
cloudlog.info("everything is dead")
last_running = ""
def manager_thread(frogpilot_functions, log_dir) -> None:
global last_running
cloudlog.bind(daemon="manager")
cloudlog.info("manager start")
cloudlog.info({"environ": os.environ})
params = Params()
params_memory = Params("/dev/shm/params")
ignore: list[str] = []
if params.get("DongleId", encoding='utf8') in (None, UNREGISTERED_DONGLE_ID):
ignore += ["manage_athenad", "uploader"]
if os.getenv("NOBOARD") is not None:
ignore.append("pandad")
ignore += [x for x in os.getenv("BLOCK", "").split(",") if len(x) > 0]
sm = messaging.SubMaster(['deviceState', 'carParams'], poll='deviceState')
pm = messaging.PubMaster(['managerState'])
write_onroad_params(False, params)
ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore, log_dir=log_dir)
started_prev = False
while True:
sm.update(1000)
openpilot_crashed = os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt'))
if openpilot_crashed:
frogpilot_functions.delete_logs()
started = sm['deviceState'].started
if started and not started_prev:
params.clear_all(ParamKeyType.CLEAR_ON_ONROAD_TRANSITION)
if openpilot_crashed:
os.remove(os.path.join(sentry.CRASHES_DIR, 'error.txt'))
elif not started and started_prev:
params.clear_all(ParamKeyType.CLEAR_ON_OFFROAD_TRANSITION)
params_memory.clear_all(ParamKeyType.CLEAR_ON_OFFROAD_TRANSITION)
# update onroad params, which drives boardd's safety setter thread
if started != started_prev:
write_onroad_params(started, params)
started_prev = started
ensure_running(managed_processes.values(), started, params=params, CP=sm['carParams'], not_run=ignore, log_dir=log_dir)
running = ' '.join("{}{}\u001b[0m".format("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
for p in managed_processes.values() if p.proc)
# clearpilot
if (running != last_running):
print(running)
cloudlog.debug(running)
last_running = running
# send managerState
msg = messaging.new_message('managerState', valid=True)
msg.managerState.processes = [p.get_process_state_msg() for p in managed_processes.values()]
pm.send('managerState', msg)
# Exit main loop when uninstall/shutdown/reboot is needed
shutdown = False
for param in ("DoUninstall", "DoShutdown", "DoReboot", "DoSoftReboot"):
if params.get_bool(param):
shutdown = True
params.put("LastManagerExitReason", f"{param} {datetime.datetime.now()}")
cloudlog.warning(f"Shutting down manager - {param} set")
if shutdown:
break
def main() -> None:
frogpilot_functions = FrogPilotFunctions()
try:
frogpilot_functions.setup_frogpilot()
except subprocess.CalledProcessError as e:
print(f"Failed to setup FrogPilot. Error: {e}")
return
log_dir = manager_init(frogpilot_functions)
if os.getenv("PREPAREONLY") is not None:
return
# SystemExit on sigterm
signal.signal(signal.SIGTERM, lambda signum, frame: sys.exit(1))
try:
manager_thread(frogpilot_functions, log_dir)
except Exception:
traceback.print_exc()
sentry.capture_exception()
finally:
manager_cleanup()
params = Params()
if params.get_bool("DoUninstall"):
cloudlog.warning("uninstalling")
frogpilot_functions.uninstall_frogpilot()
elif params.get_bool("DoReboot"):
cloudlog.warning("reboot")
HARDWARE.reboot()
elif params.get_bool("DoSoftReboot"):
cloudlog.warning("softreboot")
HARDWARE.soft_reboot()
elif params.get_bool("DoShutdown"):
cloudlog.warning("shutdown")
HARDWARE.shutdown()
if __name__ == "__main__":
unblock_stdout()
try:
main()
except KeyboardInterrupt:
print("got CTRL-C, exiting")
except Exception:
add_file_handler(cloudlog)
cloudlog.exception("Manager failed to start")
try:
managed_processes['ui'].stop()
except Exception:
pass
# Show last 3 lines of traceback
error = traceback.format_exc(-3)
error = "Manager failed to start\n\n" + error
with TextWindow(error) as t:
t.wait_for_exit()
raise
# manual exit because we are forked
sys.exit(0)

View File

@@ -2,6 +2,7 @@ import importlib
import os
import signal
import struct
import datetime
import time
import subprocess
from collections.abc import Callable, ValuesView
@@ -20,6 +21,11 @@ from openpilot.common.swaglog import cloudlog
WATCHDOG_FN = "/dev/shm/wd_"
ENABLE_WATCHDOG = os.getenv("NO_WATCHDOG") is None
timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
_log_dir = f"/data/log2/{timestamp}"
os.makedirs(_log_dir, exist_ok=True)
def launcher(proc: str, name: str) -> None:
try:
@@ -54,7 +60,6 @@ def nativelauncher(pargs: list[str], cwd: str, name: str) -> None:
os.chdir(cwd)
os.execvp(pargs[0], pargs)
def join_process(process: Process, timeout: float) -> None:
# Process().join(timeout) will hang due to a python 3 bug: https://bugs.python.org/issue28382
# We have to poll the exitcode instead
@@ -190,6 +195,9 @@ class NativeProcess(ManagerProcess):
if self.proc is not None:
return
global _log_dir
log_path = _log_dir+"/"+self.name+".log"
cwd = os.path.join(BASEDIR, self.cwd)
cloudlog.info(f"starting process {self.name}")
self.proc = Process(name=self.name, target=self.launcher, args=(self.cmdline, cwd, self.name))
@@ -221,6 +229,8 @@ class PythonProcess(ManagerProcess):
if self.proc is not None:
return
global _log_dir
log_path = _log_dir+"/"+self.name+".log"
cloudlog.info(f"starting python {self.module}")
self.proc = Process(name=self.name, target=self.launcher, args=(self.module, self.name))
self.proc.start()
@@ -238,6 +248,7 @@ class DaemonProcess(ManagerProcess):
self.enabled = enabled
self.params = None
@staticmethod
def should_run(started, params, CP):
return True
@@ -249,6 +260,9 @@ class DaemonProcess(ManagerProcess):
if self.params is None:
self.params = Params()
global _log_dir
log_path = _log_dir+"/"+self.name+".log"
pid = self.params.get(self.param_name, encoding='utf-8')
if pid is not None:
try:
@@ -264,8 +278,8 @@ class DaemonProcess(ManagerProcess):
cloudlog.info(f"starting daemon {self.name}")
proc = subprocess.Popen(['python', '-m', self.module],
stdin=open('/dev/null'),
stdout=open('/dev/null', 'w'),
stderr=open('/dev/null', 'w'),
stdout=open(log_path, 'a'),
stderr=subprocess.STDOUT,
preexec_fn=os.setpgrp)
self.params.put(self.param_name, str(proc.pid))
@@ -276,6 +290,7 @@ class DaemonProcess(ManagerProcess):
def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None, CP: car.CarParams=None,
not_run: list[str] | None=None) -> list[ManagerProcess]:
if not_run is None:
not_run = []

View File

@@ -28,10 +28,10 @@ def ublox(started, params, CP: car.CarParams) -> bool:
use_ublox = ublox_available()
if use_ublox != params.get_bool("UbloxAvailable"):
params.put_bool("UbloxAvailable", use_ublox)
return started and use_ublox
return use_ublox
def qcomgps(started, params, CP: car.CarParams) -> bool:
return started and not ublox_available()
return not ublox_available()
def always_run(started, params, CP: car.CarParams) -> bool:
return True
@@ -78,13 +78,13 @@ procs = [
PythonProcess("controlsd", "selfdrive.controls.controlsd", only_onroad),
PythonProcess("deleter", "system.loggerd.deleter", always_run),
PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(not PC or WEBCAM)),
#PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI),
#PythonProcess("ugpsd", "system.ugpsd", only_onroad, enabled=TICI),
# PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), # Fixme
# PythonProcess("ugpsd", "system.ugpsd", only_onroad, enabled=TICI),
#PythonProcess("navd", "selfdrive.navd.navd", only_onroad),
PythonProcess("pandad", "selfdrive.boardd.pandad", always_run),
PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad),
#NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], ublox, enabled=TICI),
#PythonProcess("pigeond", "system.ubloxd.pigeond", ublox, enabled=TICI),
NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], ublox, enabled=TICI),
PythonProcess("pigeond", "system.ubloxd.pigeond", ublox, enabled=TICI),
PythonProcess("plannerd", "selfdrive.controls.plannerd", only_onroad),
PythonProcess("radard", "selfdrive.controls.radard", only_onroad),
PythonProcess("thermald", "selfdrive.thermald.thermald", always_run),

View File

@@ -0,0 +1,251 @@
import importlib
import os
import signal
import struct
import time
import subprocess
from collections.abc import Callable, ValuesView
from abc import ABC, abstractmethod
from multiprocessing import Process
from setproctitle import setproctitle
from cereal import car, log
import cereal.messaging as messaging
import openpilot.selfdrive.sentry as sentry
from openpilot.common.basedir import BASEDIR
from openpilot.common.params import Params
from openpilot.common.swaglog import cloudlog
WATCHDOG_FN = "/dev/shm/wd_"
ENABLE_WATCHDOG = os.getenv("NO_WATCHDOG") is None
ENABLE_WATCHDOG = False # Fixme
_log_dir = ""
def nativelauncher(pargs: list[str], cwd: str, name: str, log_path: str) -> None:
os.environ['MANAGER_DAEMON'] = name
with open(log_path, 'a') as log_file:
os.chdir(cwd)
proc = subprocess.Popen(pargs, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True)
log_file.write("Started "+name)
for line in proc.stdout:
print(line, end='')
log_file.write(line)
proc.wait()
def launcher(proc: str, name: str, log_path: str) -> None:
for _ in iter(int, 1):
try:
mod = importlib.import_module(proc)
setproctitle(proc)
messaging.context = messaging.Context()
cloudlog.bind(daemon=name)
sentry.set_tag("daemon", name)
with open(log_path, 'a') as log_file, subprocess.Popen(['python', '-m', proc], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True) as proc:
log_file.write("Started "+name)
for line in proc.stdout:
print(line, end='')
log_file.write(line)
proc.wait()
except Exception as e:
print ("Fatal: "+name)
print (e)
sentry.capture_exception()
def join_process(process: Process, timeout: float) -> None:
t = time.monotonic()
while time.monotonic() - t < timeout and process.exitcode is None:
time.sleep(0.001)
class ManagerProcess(ABC):
daemon = False
sigkill = False
should_run: Callable[[bool, Params, car.CarParams], bool]
proc: Process | None = None
enabled = True
name = ""
last_watchdog_time = 0
watchdog_max_dt: int | None = None
watchdog_seen = False
shutting_down = False
@abstractmethod
def prepare(self) -> None:
pass
@abstractmethod
def start(self) -> None:
pass
def restart(self) -> None:
if self.proc is not None and self.proc.exitcode is not None:
self.stop(sig=signal.SIGKILL, block=False)
self.start()
def check_watchdog(self, started: bool) -> None:
if self.watchdog_max_dt is None or self.proc is None:
return
try:
fn = WATCHDOG_FN + str(self.proc.pid)
with open(fn, "rb") as f:
self.last_watchdog_time = struct.unpack('Q', f.read())[0]
except Exception:
pass
dt = time.monotonic() - self.last_watchdog_time / 1e9
if dt > self.watchdog_max_dt:
if (self.watchdog_seen or self.always_watchdog and self.proc.exitcode is not None) and ENABLE_WATCHDOG:
cloudlog.error(f"Watchdog timeout for {self.name} (exitcode {self.proc.exitcode}) restarting ({started=})")
self.restart()
else:
self.watchdog_seen = True
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals = None) -> int | None:
if self.proc is None:
return None
if self.proc.exitcode is None:
if not self.shutting_down:
cloudlog.info(f"killing {self.name}")
if sig is None:
sig = signal.SIGKILL if self.sigkill else signal.SIGINT
self.signal(sig)
self.shutting_down = True
if not block:
return None
join_process(self.proc, 5)
if self.proc.exitcode is None and retry:
cloudlog.info(f"killing {self.name} with SIGKILL")
self.signal(signal.SIGKILL)
self.proc.join()
ret = self.proc.exitcode
cloudlog.info(f"{self.name} is dead with {ret}")
if self.proc.exitcode is not None:
self.shutting_down = False
self.proc = None
return ret
def signal(self, sig: int) -> None:
if self.proc is None or self.proc.exitcode is not None or self.proc.pid is None:
return
cloudlog.info(f"sending signal {sig} to {self.name}")
os.kill(self.proc.pid, sig)
def get_process_state_msg(self):
state = log.ManagerState.ProcessState.new_message()
state.name = self.name
if self.proc:
state.running = self.proc.is_alive()
state.shouldBeRunning = self.proc is not None and not self.shutting_down
state.pid = self.proc.pid or 0
state.exitCode = self.proc.exitcode or 0
return state
class NativeProcess(ManagerProcess):
def __init__(self, name, cwd, cmdline, should_run, enabled=True, sigkill=False, watchdog_max_dt=None, always_watchdog=False):
self.name = name
self.cwd = cwd
self.cmdline = cmdline
self.should_run = should_run
self.enabled = enabled
self.sigkill = sigkill
self.watchdog_max_dt = watchdog_max_dt
self.launcher = nativelauncher
self.always_watchdog = always_watchdog
def prepare(self) -> None:
pass
def start(self) -> None:
global _log_dir
log_path = _log_dir+"/"+self.name+".log"
if self.shutting_down or self.proc is not None:
return
self.proc = Process(target=nativelauncher, args=(self.cmdline, os.path.join(BASEDIR, self.cwd), self.name, log_path))
self.proc.start()
class PythonProcess(ManagerProcess):
def __init__(self, name, module, should_run, enabled=True, sigkill=False, watchdog_max_dt=None):
self.name = name
self.module = module
self.should_run = should_run
self.enabled = enabled
self.sigkill = sigkill
self.watchdog_max_dt = watchdog_max_dt
self.launcher = launcher
def prepare(self) -> None:
if self.enabled:
cloudlog.info(f"preimporting {self.module}")
importlib.import_module(self.module)
def start(self) -> None:
global _log_dir
log_path = _log_dir+"/"+self.name+".log"
if self.shutting_down or self.proc is not None:
return
self.proc = Process(name=self.name, target=launcher, args=(self.module, self.name, log_path))
self.proc.start()
self.watchdog_seen = False
self.shutting_down = False
class DaemonProcess(ManagerProcess):
"""Python process that has to stay running across manager restart.
This is used for athena so you don't lose SSH access when restarting manager."""
def __init__(self, name, module, param_name, enabled=True):
self.name = name
self.module = module
self.param_name = param_name
self.enabled = enabled
self.params = None
@staticmethod
def should_run(started, params, CP):
return True
def prepare(self) -> None:
pass
def start(self) -> None:
global _log_dir
log_path = _log_dir+"/"+self.name+".log"
if self.params is None:
self.params = Params()
pid = self.params.get(self.param_name, encoding='utf-8')
if pid is not None:
try:
os.kill(int(pid), 0)
return # Process is already running
except OSError:
pass # Process not running, continue to start it
cloudlog.info(f"starting daemon {self.name}")
self.proc = subprocess.Popen(['python', '-m', self.module],
stdin=open('/dev/null'),
stdout=open(log_path, 'a'),
stderr=subprocess.STDOUT,
preexec_fn=os.setpgrp)
self.params.put(self.param_name, str(self.proc.pid))
def stop(self, retry=True, block=True, sig=None) -> None:
pass
def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None, CP: car.CarParams=None, not_run: list[str] | None=None, log_dir: str = None) -> list[ManagerProcess]:
global _log_dir
_log_dir = log_dir
if not_run is None:
not_run = []
running = []
for p in procs:
if p.enabled and p.name not in not_run and p.should_run(started, params, CP):
if p.proc is None or (hasattr(p.proc, 'exitcode') and p.proc.exitcode is not None):
p.start()
running.append(p)
else:
p.stop(block=False)
p.check_watchdog(started)
return running

View File

@@ -0,0 +1,350 @@
import importlib
import os
import signal
import struct
import datetime
import time
import subprocess
from collections.abc import Callable, ValuesView
from abc import ABC, abstractmethod
from multiprocessing import Process
from setproctitle import setproctitle
from cereal import car, log
import cereal.messaging as messaging
import openpilot.selfdrive.sentry as sentry
from openpilot.common.basedir import BASEDIR
from openpilot.common.params import Params
from openpilot.common.swaglog import cloudlog
WATCHDOG_FN = "/dev/shm/wd_"
ENABLE_WATCHDOG = os.getenv("NO_WATCHDOG") is None
timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
_log_dir = f"/data/log2/{timestamp}"
os.makedirs(_log_dir, exist_ok=True)
# def launcher(proc: str, name: str, log_path: str) -> None:
# try:
# # import the process
# mod = importlib.import_module(proc)
# global _log_dir
# log_path = os.path.join(_log_dir, f"{name}.log")
# # rename the process
# setproctitle(proc)
# # create new context since we forked
# messaging.context = messaging.Context()
# # add daemon name tag to logs
# cloudlog.bind(daemon=name)
# sentry.set_tag("daemon", name)
# # exec the process
# mod.main()
# except KeyboardInterrupt:
# cloudlog.warning(f"child {proc} got SIGINT")
# except Exception as e:
# # can't install the crash handler because sys.excepthook doesn't play nice
# # with threads, so catch it here.
# with open(log_path, 'a') as file: file.write(str(e)+"\n")
# sentry.capture_exception()
# raise
def launcher(proc: str, name: str) -> None:
try:
# Import the process module
mod = importlib.import_module(proc)
# Path for logging
global _log_dir
log_path = os.path.join(_log_dir, f"{name}.log")
# Rename the process
setproctitle(name)
# Create new context since we forked
messaging.context = messaging.Context()
# Add daemon name tag to logs
cloudlog.bind(daemon=name)
sentry.set_tag("daemon", name)
# Command construction
command = f"bash -c 'python -m {proc} 2>&1 | tee {log_path}'"
# Execute the command
subprocess.run(command, shell=True, executable='/bin/bash', cwd=os.path.dirname(mod.__file__))
except KeyboardInterrupt:
cloudlog.warning(f"child {proc} got SIGINT")
except Exception as e:
with open(log_path, 'a') as file:
file.write(str(e) + "\n")
sentry.capture_exception()
raise
def nativelauncher(pargs: list[str], cwd: str, name: str) -> None:
os.environ['MANAGER_DAEMON'] = name
global _log_dir
log_path = os.path.join(_log_dir, f"{name}.log")
# Command construction
command = f"bash -c \"{ ' '.join(pargs) } 2>&1 | tee {log_path}\""
# Execute the command in the specified directory
subprocess.run(command, shell=True, cwd=cwd, executable='/bin/bash')
def join_process(process: Process, timeout: float) -> None:
# Process().join(timeout) will hang due to a python 3 bug: https://bugs.python.org/issue28382
# We have to poll the exitcode instead
t = time.monotonic()
while time.monotonic() - t < timeout and process.exitcode is None:
time.sleep(0.001)
class ManagerProcess(ABC):
daemon = False
sigkill = False
should_run: Callable[[bool, Params, car.CarParams], bool]
proc: Process | None = None
enabled = True
name = ""
last_watchdog_time = 0
watchdog_max_dt: int | None = None
watchdog_seen = False
shutting_down = False
@abstractmethod
def prepare(self) -> None:
pass
@abstractmethod
def start(self) -> None:
pass
def restart(self) -> None:
self.stop(sig=signal.SIGKILL)
self.start()
def check_watchdog(self, started: bool) -> None:
if self.watchdog_max_dt is None or self.proc is None:
return
try:
fn = WATCHDOG_FN + str(self.proc.pid)
with open(fn, "rb") as f:
# TODO: why can't pylint find struct.unpack?
self.last_watchdog_time = struct.unpack('Q', f.read())[0]
except Exception:
pass
dt = time.monotonic() - self.last_watchdog_time / 1e9
if dt > self.watchdog_max_dt:
if (self.watchdog_seen or self.always_watchdog and self.proc.exitcode is not None) and ENABLE_WATCHDOG:
cloudlog.error(f"Watchdog timeout for {self.name} (exitcode {self.proc.exitcode}) restarting ({started=})")
self.restart()
else:
self.watchdog_seen = True
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals = None) -> int | None:
if self.proc is None:
return None
if self.proc.exitcode is None:
if not self.shutting_down:
cloudlog.info(f"killing {self.name}")
if sig is None:
sig = signal.SIGKILL if self.sigkill else signal.SIGINT
self.signal(sig)
self.shutting_down = True
if not block:
return None
join_process(self.proc, 5)
# If process failed to die send SIGKILL
if self.proc.exitcode is None and retry:
cloudlog.info(f"killing {self.name} with SIGKILL")
self.signal(signal.SIGKILL)
self.proc.join()
ret = self.proc.exitcode
cloudlog.info(f"{self.name} is dead with {ret}")
if self.proc.exitcode is not None:
self.shutting_down = False
self.proc = None
return ret
def signal(self, sig: int) -> None:
if self.proc is None:
return
# Don't signal if already exited
if self.proc.exitcode is not None and self.proc.pid is not None:
return
# Can't signal if we don't have a pid
if self.proc.pid is None:
return
cloudlog.info(f"sending signal {sig} to {self.name}")
os.kill(self.proc.pid, sig)
def get_process_state_msg(self):
state = log.ManagerState.ProcessState.new_message()
state.name = self.name
if self.proc:
state.running = self.proc.is_alive()
state.shouldBeRunning = self.proc is not None and not self.shutting_down
state.pid = self.proc.pid or 0
state.exitCode = self.proc.exitcode or 0
return state
class NativeProcess(ManagerProcess):
def __init__(self, name, cwd, cmdline, should_run, enabled=True, sigkill=False, watchdog_max_dt=None, always_watchdog=False):
self.name = name
self.cwd = cwd
self.cmdline = cmdline
self.should_run = should_run
self.enabled = enabled
self.sigkill = sigkill
self.watchdog_max_dt = watchdog_max_dt
self.launcher = nativelauncher
self.always_watchdog = always_watchdog
def prepare(self) -> None:
pass
def start(self) -> None:
# In case we only tried a non blocking stop we need to stop it before restarting
if self.shutting_down:
self.stop()
if self.proc is not None:
return
global _log_dir
log_path = _log_dir+"/"+self.name+".log"
cwd = os.path.join(BASEDIR, self.cwd)
cloudlog.info(f"starting process {self.name}")
self.proc = Process(name=self.name, target=self.launcher, args=(self.cmdline, cwd, self.name))
self.proc.start()
self.watchdog_seen = False
self.shutting_down = False
class PythonProcess(ManagerProcess):
def __init__(self, name, module, should_run, enabled=True, sigkill=False, watchdog_max_dt=None):
self.name = name
self.module = module
self.should_run = should_run
self.enabled = enabled
self.sigkill = sigkill
self.watchdog_max_dt = watchdog_max_dt
self.launcher = launcher
def prepare(self) -> None:
if self.enabled:
cloudlog.info(f"preimporting {self.module}")
importlib.import_module(self.module)
def start(self) -> None:
# In case we only tried a non blocking stop we need to stop it before restarting
if self.shutting_down:
self.stop()
if self.proc is not None:
return
global _log_dir
log_path = _log_dir+"/"+self.name+".log"
cloudlog.info(f"starting python {self.module}")
self.proc = Process(name=self.name, target=self.launcher, args=(self.module, self.name))
self.proc.start()
self.watchdog_seen = False
self.shutting_down = False
class DaemonProcess(ManagerProcess):
"""Python process that has to stay running across manager restart.
This is used for athena so you don't lose SSH access when restarting manager."""
def __init__(self, name, module, param_name, enabled=True):
self.name = name
self.module = module
self.param_name = param_name
self.enabled = enabled
self.params = None
@staticmethod
def should_run(started, params, CP):
return True
def prepare(self) -> None:
pass
def start(self) -> None:
if self.params is None:
self.params = Params()
global _log_dir
log_path = _log_dir+"/"+self.name+".log"
pid = self.params.get(self.param_name, encoding='utf-8')
if pid is not None:
try:
os.kill(int(pid), 0)
with open(f'/proc/{pid}/cmdline') as f:
if self.module in f.read():
# daemon is running
return
except (OSError, FileNotFoundError):
# process is dead
pass
cloudlog.info(f"starting daemon {self.name}")
proc = subprocess.Popen(['python', '-m', self.module],
stdin=open('/dev/null'),
stdout=open(log_path, 'a'),
stderr=subprocess.STDOUT,
preexec_fn=os.setpgrp)
self.params.put(self.param_name, str(proc.pid))
def stop(self, retry=True, block=True, sig=None) -> None:
pass
def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None, CP: car.CarParams=None,
not_run: list[str] | None=None) -> list[ManagerProcess]:
if not_run is None:
not_run = []
running = []
for p in procs:
if p.enabled and p.name not in not_run and p.should_run(started, params, CP):
running.append(p)
else:
p.stop(block=False)
p.check_watchdog(started)
for p in running:
p.start()
return running

View File

@@ -29,6 +29,8 @@
// p.restore();
// }
bool alert_is_visible = false;
OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent), scene(uiState()->scene) {
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setMargin(UI_BORDER_SIZE);
@@ -75,7 +77,7 @@ void OnroadWindow::updateState(const UIState &s) {
nvg->updateState(s);
QColor bgColor = bg_colors[s.status];
if (paramsMemory.getInt("no_lat_lane_change") == 1) {
if (paramsMemory.getBool("no_lat_lane_change") == 1) {
bgColor = bg_colors[STATUS_DISENGAGED];
}
@@ -175,52 +177,6 @@ void OnroadWindow::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.fillRect(rect(), QColor(bg.red(), bg.green(), bg.blue(), 255));
if (scene.fps_counter) {
qint64 currentMillis = QDateTime::currentMSecsSinceEpoch();
auto fpsQueue = std::queue<std::pair<qint64, double>>();
static double avgFPS = 0.0;
static double maxFPS = 0.0;
static double minFPS = 99.9;
minFPS = qMin(minFPS, fps);
maxFPS = qMax(maxFPS, fps);
fpsQueue.push({currentMillis, fps});
while (!fpsQueue.empty() && currentMillis - fpsQueue.front().first > 60000) {
fpsQueue.pop();
}
if (!fpsQueue.empty()) {
double totalFPS = 0;
for (auto tempQueue = fpsQueue; !tempQueue.empty(); tempQueue.pop()) {
totalFPS += tempQueue.front().second;
}
avgFPS = totalFPS / fpsQueue.size();
}
QString fpsDisplayString = QString("FPS: %1 (%2) | Min: %3 | Max: %4 | Avg: %5")
.arg(qRound(fps))
.arg(paramsMemory.getInt("CameraFPS"))
.arg(qRound(minFPS))
.arg(qRound(maxFPS))
.arg(qRound(avgFPS));
p.setFont(InterFont(28, QFont::DemiBold));
p.setRenderHint(QPainter::TextAntialiasing);
p.setPen(Qt::white);
QRect currentRect = rect();
int textWidth = p.fontMetrics().horizontalAdvance(fpsDisplayString);
int xPos = (currentRect.width() - textWidth) / 2;
int yPos = currentRect.bottom() - 5;
p.drawText(xPos, yPos, fpsDisplayString);
update();
}
QString logicsDisplayString = QString();
if (scene.show_jerk) {
logicsDisplayString += QString("Acceleration Jerk: %1 (%2%3) | Speed Jerk: %4 (%5%6) | ")
@@ -259,6 +215,14 @@ void OnroadWindow::paintEvent(QPaintEvent *event) {
}
}
// void OnroadWindow::update_screen_on_off() {
// int screenDisaplayMode = paramsMemory.getInt("ScreenDisaplayMode");
// if (screenDisaplayMode == 1) {
// // Conditionally off
// }
// }
// ***** onroad widgets *****
// OnroadAlerts
@@ -270,6 +234,8 @@ void OnroadAlerts::updateAlert(const Alert &a) {
}
void OnroadAlerts::paintEvent(QPaintEvent *event) {
alert_is_visible = false;
if (alert.size == cereal::ControlsState::AlertSize::NONE) {
return;
}
@@ -278,6 +244,8 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) {
return;
}
alert_is_visible = true;
static std::map<cereal::ControlsState::AlertSize, const int> alert_heights = {
{cereal::ControlsState::AlertSize::SMALL, 271},
{cereal::ControlsState::AlertSize::MID, 420},
@@ -355,9 +323,6 @@ AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* par
top_right_layout->setSpacing(0);
top_right_layout->addLayout(buttons_layout);
pedal_icons = new PedalIcons(this);
// top_right_layout->addWidget(pedal_icons, 0, Qt::AlignRight);
main_layout->addLayout(top_right_layout, 0);
main_layout->setAlignment(top_right_layout, Qt::AlignTop | Qt::AlignRight);
@@ -423,8 +388,20 @@ if (edgeColor != bgColor) {
}
void AnnotatedCameraWidget::drawHud(QPainter &p) {
// Blank when screenDisplayMode=1
p.save();
int screenDisaplayMode = paramsMemory.getInt("ScreenDisaplayMode");
if (screenDisaplayMode == 1 && !alert_is_visible) {
// Draw black, filled, full-size rectangle to blank the screen
// p.fillRect(0, 0, width(), height(), Qt::black);
// p.restore();
Hardware::set_display_power(false);
return;
} else {
Hardware::set_display_power(true);
}
// Header gradient
QLinearGradient bg(0, UI_HEADER_HEIGHT - (UI_HEADER_HEIGHT / 2.5), 0, UI_HEADER_HEIGHT);
bg.setColorAt(0, QColor::fromRgbF(0, 0, 0, 0.45));
@@ -441,20 +418,20 @@ void AnnotatedCameraWidget::drawHud(QPainter &p) {
p.restore();
// if (!scene.hide_max_speed) {
drawSpeedWidget(p, 60, 45, QString("MAX"), setSpeedStr, QColor(0xff, 0xff, 0xff));
// drawSpeedWidget(p, 60, 45, QString("MAX"), setSpeedStr, QColor(0xff, 0xff, 0xff));
// }
// Todo: needs to be changed to calculate off of actual speed limit for release
QString speedLimitStr = QString::number(paramsMemory.getInt("CarSpeedLimitLiteral"));
drawSpeedWidget(p, 60, 45 + (225), QString("Limit"), speedLimitStr, QColor(0xff, 0xff, 0xff));
// // Todo: needs to be changed to calculate off of actual speed limit for release
// QString speedLimitStr = QString::number(paramsMemory.getInt("CarSpeedLimitLiteral"));
// drawSpeedWidget(p, 60, 45 + (225), QString("Limit"), speedLimitStr, QColor(0xff, 0xff, 0xff));
// Todo: needs to be changed to calculate off of actual speed limit for release
QString SpeedLimitLatDesired = QString::number(paramsMemory.getInt("SpeedLimitLatDesired"));
drawSpeedWidget(p, 60, 45 + (225 * 2), QString("Exp"), SpeedLimitLatDesired, QColor(0xff, 0xff, 0xff));
// // Todo: needs to be changed to calculate off of actual speed limit for release
// QString SpeedLimitLatDesired = QString::number(paramsMemory.getInt("SpeedLimitLatDesired"));
// drawSpeedWidget(p, 60, 45 + (225 * 2), QString("Exp"), SpeedLimitLatDesired, QColor(0xff, 0xff, 0xff));
// Todo: needs to be changed to calculate off of actual speed limit for release
QString adjustedCruise = QString::number(paramsMemory.getInt("SpeedLimitVTSC"));
drawSpeedWidget(p, 60, 45 + (225 * 3), QString("VTSC"), adjustedCruise, QColor(0xff, 0xff, 0xff));
// // Todo: needs to be changed to calculate off of actual speed limit for release
// QString adjustedCruise = QString::number(paramsMemory.getInt("SpeedLimitVTSC"));
// drawSpeedWidget(p, 60, 45 + (225 * 3), QString("VTSC"), adjustedCruise, QColor(0xff, 0xff, 0xff));
// Todo: lead speed
// Todo: Experimental speed
@@ -530,13 +507,13 @@ void AnnotatedCameraWidget::drawHud(QPainter &p) {
// }
// }
void AnnotatedCameraWidget::drawSpeedWidget(QPainter &p, int x, int y, const QString &title, const QString &speedLimitStr, QColor colorSpeed) {
void AnnotatedCameraWidget::drawSpeedWidget(QPainter &p, int x, int y, const QString &title, const QString &speedLimitStr, QColor colorSpeed, int width) {
// Draw outer box + border to contain set speed and speed limit
const int sign_margin = 12;
const int us_sign_height = 186;
const int eu_sign_size = 176;
const int eu_sign_size = width;
const QSize default_size = {172, 204};
const QSize default_size = {width, 204};
QSize set_speed_size = default_size;
if (is_metric || has_eu_speed_limit) set_speed_size.rwidth() = 200;
if (has_us_speed_limit && speedLimitStr.size() >= 3) set_speed_size.rwidth() = 223;
@@ -560,9 +537,9 @@ void AnnotatedCameraWidget::drawSpeedWidget(QPainter &p, int x, int y, const QSt
p.setFont(InterFont(90, QFont::Bold));
p.setPen(colorSpeed);
p.drawText(set_speed_rect.adjusted(0, 77, 0, 0), Qt::AlignTop | Qt::AlignHCenter, speedLimitStr);
}
void AnnotatedCameraWidget::drawText(QPainter &p, int x, int y, const QString &text, int alpha) {
QRect real_rect = p.fontMetrics().boundingRect(text);
real_rect.moveCenter({x, y - real_rect.height() / 2});
@@ -622,19 +599,19 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) {
// paint center lane path
// QColor bg_colors[CHANGE_LANE_PATH_COLOR];
// int is_no_lat_lane_change = paramsMemory.getInt("no_lat_lane_change");
bool is_no_lat_lane_change = paramsMemory.getBool("no_lat_lane_change");
QColor center_lane_color;
// if (is_no_lat_lane_change) {
// center_lane_color = bg_colors[CHANGE_LANE_PATH_COLOR];
// } else {
if (is_no_lat_lane_change) {
center_lane_color = bg_colors[CHANGE_LANE_PATH_COLOR];
} else {
center_lane_color = bg_colors[CENTER_LANE_COLOR];
// }
}
QLinearGradient path_gradient(0, height(), 0, 0);
// if (edgeColor != bg_colors[STATUS_DISENGAGED] || is_no_lat_lane_change) {
if (edgeColor != bg_colors[STATUS_DISENGAGED] || is_no_lat_lane_change) {
if (scene.acceleration_path) {
// The first half of track_vertices are the points for the right side of the path
// and the indices match the positions of accel from uiPlan
@@ -684,7 +661,7 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) {
painter.setBrush(path_gradient);
painter.drawPolygon(scene.track_vertices);
// }
}
// Paint path edges ,Use current background color
if (edgeColor != bg_colors[STATUS_DISENGAGED]) {
@@ -884,7 +861,8 @@ void AnnotatedCameraWidget::paintEvent(QPaintEvent *event) {
const auto &lead = model.getLeadsV3()[i];
auto lead_drel = lead.getX()[0];
if (lead.getProb() > 0.5 && (prev_drel < 0 || std::abs(lead_drel - prev_drel) > 3.0)) {
drawLead(painter, lead, s->scene.lead_vertices[i], v_ego);
// Disabled for the moment.
// drawLead(painter, lead, s->scene.lead_vertices[i], v_ego);
}
prev_drel = lead_drel;
}
@@ -924,8 +902,6 @@ void AnnotatedCameraWidget::showEvent(QShowEvent *event) {
void AnnotatedCameraWidget::initializeFrogPilotWidgets() {
bottom_layout = new QHBoxLayout();
distance_btn = new DistanceButton(this);
// bottom_layout->addWidget(distance_btn);
// QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
// bottom_layout->addItem(spacer);
@@ -983,8 +959,6 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets() {
obstacleDistance = scene.obstacle_distance;
obstacleDistanceStock = scene.obstacle_distance_stock;
onroadDistanceButton = scene.onroad_distance_button;
roadNameUI = scene.road_name_ui;
speedLimitController = scene.speed_limit_controller;
@@ -1042,91 +1016,10 @@ void AnnotatedCameraWidget::paintFrogPilotWidgets(QPainter &p) {
drawSLCConfirmation(p);
}
// bool enableDistanceButton = onroadDistanceButton && !hideBottomIcons;
// distance_btn->setVisible(enableDistanceButton);
// if (enableDistanceButton) {
// distance_btn->updateState();
// bottom_layout->setAlignment(distance_btn, (rightHandDM ? Qt::AlignRight : Qt::AlignLeft));
// }
// bool enablePedalIcons = scene.pedals_on_ui && !bigMapOpen;
// pedal_icons->setVisible(enablePedalIcons);
// if (enablePedalIcons) {
// pedal_icons->updateState();
// }
// recorder_btn->setVisible(scene.screen_recorder && !mapOpen);
recorder_btn->setVisible(false);
}
DistanceButton::DistanceButton(QWidget *parent) : QPushButton(parent), scene(uiState()->scene) {
// setFixedSize(btn_size * 1.5, btn_size * 1.5);
// profile_data = {
// {QPixmap("../frogpilot/assets/other_images/traffic.png"), "Traffic"},
// {QPixmap("../frogpilot/assets/other_images/aggressive.png"), "Aggressive"},
// {QPixmap("../frogpilot/assets/other_images/standard.png"), "Standard"},
// {QPixmap("../frogpilot/assets/other_images/relaxed.png"), "Relaxed"}
// };
// profile_data_kaofui = {
// {QPixmap("../frogpilot/assets/other_images/traffic_kaofui.png"), "Traffic"},
// {QPixmap("../frogpilot/assets/other_images/aggressive_kaofui.png"), "Aggressive"},
// {QPixmap("../frogpilot/assets/other_images/standard_kaofui.png"), "Standard"},
// {QPixmap("../frogpilot/assets/other_images/relaxed_kaofui.png"), "Relaxed"}
// };
// transitionTimer.start();
// connect(this, &QPushButton::pressed, this, &DistanceButton::buttonPressed);
// connect(this, &QPushButton::released, this, &DistanceButton::buttonReleased);
}
void DistanceButton::buttonPressed() {
// paramsMemory.putBool("OnroadDistanceButtonPressed", true);
}
void DistanceButton::buttonReleased() {
// paramsMemory.putBool("OnroadDistanceButtonPressed", false);
}
void DistanceButton::updateState() {
// if (trafficModeActive != scene.traffic_mode_active || personality != static_cast<int>(scene.personality) && !trafficModeActive) {
// transitionTimer.restart();
// }
// personality = static_cast<int>(scene.personality);
trafficModeActive = scene.traffic_mode_active;
}
void DistanceButton::paintEvent(QPaintEvent *event) {
// QPainter p(this);
// p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
// constexpr qreal fadeDuration = 1000.0;
// constexpr qreal textDuration = 3000.0;
// int elapsed = transitionTimer.elapsed();
// qreal textOpacity = qBound(0.0, 1.0 - ((elapsed - textDuration) / fadeDuration), 1.0);
// qreal imageOpacity = qBound(0.0, (elapsed - textDuration) / fadeDuration, 1.0);
// int profile = trafficModeActive ? 0 : personality + 1;
// auto &[profileImage, profileText] = scene.use_kaofui_icons ? profile_data_kaofui[profile] : profile_data[profile];
// if (textOpacity != 0.0) {
// p.setOpacity(textOpacity);
// p.setFont(InterFont(40, QFont::Bold));
// p.setPen(Qt::white);
// QRect textRect(-25, 0, width(), height() + 95);
// p.drawText(textRect, Qt::AlignCenter, profileText);
// }
// if (imageOpacity != 0.0) {
// drawIcon(p, QPoint((btn_size / 2) * 1.25, btn_size / 2 + 95), profileImage, Qt::transparent, imageOpacity);
// }
}
void AnnotatedCameraWidget::drawLeadInfo(QPainter &p) {
static QElapsedTimer timer;
static bool isFiveSecondsPassed = false;
@@ -1241,43 +1134,6 @@ void AnnotatedCameraWidget::drawLeadInfo(QPainter &p) {
p.restore();
}
PedalIcons::PedalIcons(QWidget *parent) : QWidget(parent), scene(uiState()->scene) {
setFixedSize(btn_size, btn_size);
brake_pedal_img = loadPixmap("../frogpilot/assets/other_images/brake_pedal.png", QSize(img_size, img_size));
gas_pedal_img = loadPixmap("../frogpilot/assets/other_images/gas_pedal.png", QSize(img_size, img_size));
}
void PedalIcons::updateState() {
// acceleration = scene.acceleration;
// accelerating = acceleration > 0.25;
// decelerating = acceleration < -0.25;
// if (accelerating || decelerating) {
// update();
// }
}
void PedalIcons::paintEvent(QPaintEvent *event) {
// QPainter p(this);
// p.setRenderHint(QPainter::Antialiasing);
// int totalWidth = 2 * img_size;
// int startX = (width() - totalWidth) / 2;
// int brakeX = startX + img_size / 2;
// int gasX = startX + img_size;
// float brakeOpacity = scene.standstill ? 1.0f : decelerating ? std::max(0.25f, std::abs(acceleration)) : 0.25f;
// float gasOpacity = accelerating ? std::max(0.25f, acceleration) : 0.25f;
// p.setOpacity(brakeOpacity);
// p.drawPixmap(brakeX, (height() - img_size) / 2, brake_pedal_img);
// p.setOpacity(gasOpacity);
// p.drawPixmap(gasX, (height() - img_size) / 2, gas_pedal_img);
}
void AnnotatedCameraWidget::drawSLCConfirmation(QPainter &p) {
p.save();

View File

@@ -38,53 +38,6 @@ private:
UIScene &scene;
};
class DistanceButton : public QPushButton {
public:
explicit DistanceButton(QWidget *parent = nullptr);
void buttonPressed();
void buttonReleased();
void updateState();
protected:
void paintEvent(QPaintEvent *event) override;
private:
Params paramsMemory{"/dev/shm/params"};
UIScene &scene;
bool trafficModeActive;
// int personality;
QElapsedTimer transitionTimer;
QVector<std::pair<QPixmap, QString>> profile_data;
QVector<std::pair<QPixmap, QString>> profile_data_kaofui;
};
class PedalIcons : public QWidget {
Q_OBJECT
public:
explicit PedalIcons(QWidget *parent = 0);
void updateState();
private:
void paintEvent(QPaintEvent *event) override;
QPixmap brake_pedal_img;
QPixmap gas_pedal_img;
UIScene &scene;
bool accelerating;
bool decelerating;
float acceleration;
};
// container window for the NVG UI
class AnnotatedCameraWidget : public CameraWidget {
@@ -97,7 +50,7 @@ public:
private:
void drawText(QPainter &p, int x, int y, const QString &text, int alpha = 255);
void drawSpeedWidget(QPainter &p, int x, int y, const QString &title, const QString &speedLimitStr, QColor colorSpeed);
void drawSpeedWidget(QPainter &p, int x, int y, const QString &title, const QString &speedLimitStr, QColor colorSpeed, int width = 176);
QVBoxLayout *main_layout;
QPixmap dm_img;
@@ -135,8 +88,6 @@ private:
Params paramsMemory{"/dev/shm/params"};
UIScene &scene;
DistanceButton *distance_btn;
PedalIcons *pedal_icons;
ScreenRecorder *recorder_btn;
QHBoxLayout *bottom_layout;
@@ -146,7 +97,6 @@ private:
bool blindSpotRight;
bool experimentalMode;
bool leadInfo;
bool onroadDistanceButton;
bool roadNameUI;
bool showAlwaysOnLateralStatusBar;
bool showConditionalExperimentalStatusBar;

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation>كم/س</translation>
<translation type="vanished">كم/س</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation>MAX</translation>
<translation type="vanished">MAX</translation>
</message>
<message>
<source>SPEED</source>
<translation>SPEED</translation>
<translation type="vanished">SPEED</translation>
</message>
<message>
<source>LIMIT</source>
<translation>LIMIT</translation>
<translation type="vanished">LIMIT</translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -318,27 +298,27 @@
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation>المنزل</translation>
<translation type="vanished">المنزل</translation>
</message>
<message>
<source>Work</source>
<translation>العمل</translation>
<translation type="vanished">العمل</translation>
</message>
<message>
<source>No destination set</source>
<translation>لم يتم ضبط الوجهة</translation>
<translation type="vanished">لم يتم ضبط الوجهة</translation>
</message>
<message>
<source>home</source>
<translation>المنزل</translation>
<translation type="vanished">المنزل</translation>
</message>
<message>
<source>work</source>
<translation>العمل</translation>
<translation type="vanished">العمل</translation>
</message>
<message>
<source>No %1 location set</source>
<translation>لم يتم ضبط %1 موقع</translation>
<translation type="vanished">لم يتم ضبط %1 موقع</translation>
</message>
</context>
<context>
@@ -710,45 +690,41 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation>الوصول</translation>
<translation type="vanished">الوصول</translation>
</message>
<message>
<source>min</source>
<translation>د</translation>
<translation type="vanished">د</translation>
</message>
<message>
<source>hr</source>
<translation>س</translation>
<translation type="vanished">س</translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation>التنقل</translation>
<translation type="vanished">التنقل</translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation>الإدارة في connect.comma.ai</translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished">الإدارة في connect.comma.ai</translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation>تحميل الخريطة</translation>
<translation type="vanished">تحميل الخريطة</translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation>بانتظار GPS</translation>
<translation type="vanished">بانتظار GPS</translation>
</message>
<message>
<source>Waiting for route</source>
<translation>بانتظار الطريق</translation>
<translation type="vanished">بانتظار الطريق</translation>
</message>
</context>
<context>
@@ -857,19 +833,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation>اقرن جهازك مع حسابك على comma</translation>
<translation type="vanished">اقرن جهازك مع حسابك على comma</translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation>انتقل إلى https://connect.comma.ai على جوالك</translation>
<translation type="vanished">انتقل إلى https://connect.comma.ai على جوالك</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation>انقر &quot;،إضافة جهاز جديد&quot;، وامسح رمز الاستجابة السريعة (QR) على اليمين</translation>
<translation type="vanished">انقر &quot;،إضافة جهاز جديد&quot;، وامسح رمز الاستجابة السريعة (QR) على اليمين</translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation>اجعل لـconnect.comma.ai إشارة مرجعية على شاشتك الرئيسية من أجل استخدامه مثل أي تطبيق</translation>
<translation type="vanished">اجعل لـconnect.comma.ai إشارة مرجعية على شاشتك الرئيسية من أجل استخدامه مثل أي تطبيق</translation>
</message>
</context>
<context>
@@ -887,42 +863,42 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation>الترقية الآن</translation>
<translation type="vanished">الترقية الآن</translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation>كن عضوًا في comma prime على connect.comma.ai</translation>
<translation type="vanished">كن عضوًا في comma prime على connect.comma.ai</translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation>الميزات الأساسية:</translation>
<translation type="vanished">الميزات الأساسية:</translation>
</message>
<message>
<source>Remote access</source>
<translation>التحكم عن بعد</translation>
<translation type="vanished">التحكم عن بعد</translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation>اتصال LTE على مدار الساعة 24/7</translation>
<translation type="vanished">اتصال LTE على مدار الساعة 24/7</translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation>سنة واحدة من تخزين القرص</translation>
<translation type="vanished">سنة واحدة من تخزين القرص</translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation>التنقل خطوة بخطوة</translation>
<translation type="vanished">التنقل خطوة بخطوة</translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> مشترك</translation>
<translation type="vanished"> مشترك</translation>
</message>
<message>
<source>comma prime</source>
<translation>comma prime</translation>
<translation type="vanished">comma prime</translation>
</message>
</context>
<context>
@@ -974,19 +950,19 @@
</message>
<message>
<source>km</source>
<translation>كم</translation>
<translation type="vanished">كم</translation>
</message>
<message>
<source>m</source>
<translation>م</translation>
<translation type="vanished">م</translation>
</message>
<message>
<source>mi</source>
<translation>ميل</translation>
<translation type="vanished">ميل</translation>
</message>
<message>
<source>ft</source>
<translation>قدم</translation>
<translation type="vanished">قدم</translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1064,10 +1040,6 @@ This may take up to a minute.</source>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1176,15 +1148,15 @@ This may take up to a minute.</source>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation>إنهاء الإعداد</translation>
<translation type="vanished">إنهاء الإعداد</translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation>اقرن جهازك بجهاز (connect.comma.ai) واحصل على عرضك من comma prime.</translation>
<translation type="vanished">اقرن جهازك بجهاز (connect.comma.ai) واحصل على عرضك من comma prime.</translation>
</message>
<message>
<source>Pair device</source>
<translation>اقتران الجهاز</translation>
<translation type="vanished">اقتران الجهاز</translation>
</message>
</context>
<context>
@@ -1502,19 +1474,19 @@ This may take up to a minute.</source>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translation>إظهار الوقت المقدر للوصول بصيغة 24 ساعة</translation>
<translation type="vanished">إظهار الوقت المقدر للوصول بصيغة 24 ساعة</translation>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation>استخدام صيغة 24 ساعة بدلاً من صباحاً/مساء</translation>
<translation type="vanished">استخدام صيغة 24 ساعة بدلاً من صباحاً/مساء</translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translation>عرض الخريطة على الجانب الأيسر من واجهة المستخدم</translation>
<translation type="vanished">عرض الخريطة على الجانب الأيسر من واجهة المستخدم</translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation>عرض الخريطة عل الجانب الأيسر عندما تكون وضعية العرض بطريقة الشاشة المنقسمة.</translation>
<translation type="vanished">عرض الخريطة عل الجانب الأيسر عندما تكون وضعية العرض بطريقة الشاشة المنقسمة.</translation>
</message>
<message>
<source>openpilot Longitudinal Control (Alpha)</source>
@@ -1562,11 +1534,11 @@ This may take up to a minute.</source>
</message>
<message>
<source>Navigate on openpilot</source>
<translation>التنقل على openpilot</translation>
<translation type="vanished">التنقل على openpilot</translation>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation>عندما يكون هناك وجهة للتنقل، فإن openpilot سيقوم بإدخال معلومات الخريطة في هذا النموذج. وهذا يقدم سياقاً مفيداً ويسمح لـopenpilot بالبقاء يساراً أو يميناً بالشكل المناسب عند المنعطفات/المخارج. يبقى سلوك تغيير المسار مفعلاً عند السائق،. هذه هي خاصية الجودة ألفا، ولذلك يجب توقع الأخطاء لا سيما عند المخارج والمنعطفات هذه الأخطاء قد تشمل العبور غير المقصود لخطوط المسارات، والتأخر في الخروج، والقيادة نحو الحواجز الفاصلة في المناطق المثلثة بين الطريق الرئيسي والمخارج، وغير ذلك من الأخطاء المشابهة.</translation>
<translation type="vanished">عندما يكون هناك وجهة للتنقل، فإن openpilot سيقوم بإدخال معلومات الخريطة في هذا النموذج. وهذا يقدم سياقاً مفيداً ويسمح لـopenpilot بالبقاء يساراً أو يميناً بالشكل المناسب عند المنعطفات/المخارج. يبقى سلوك تغيير المسار مفعلاً عند السائق،. هذه هي خاصية الجودة ألفا، ولذلك يجب توقع الأخطاء لا سيما عند المخارج والمنعطفات هذه الأخطاء قد تشمل العبور غير المقصود لخطوط المسارات، والتأخر في الخروج، والقيادة نحو الحواجز الفاصلة في المناطق المثلثة بين الطريق الرئيسي والمخارج، وغير ذلك من الأخطاء المشابهة.</translation>
</message>
<message>
<source>New Driving Visualization</source>

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation>km/h</translation>
<translation type="vanished">km/h</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation>MAX</translation>
<translation type="vanished">MAX</translation>
</message>
<message>
<source>SPEED</source>
<translation>Geschwindigkeit</translation>
<translation type="vanished">Geschwindigkeit</translation>
</message>
<message>
<source>LIMIT</source>
<translation>LIMIT</translation>
<translation type="vanished">LIMIT</translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -314,33 +294,6 @@
<translation>Ablehnen, deinstallieren %1</translation>
</message>
</context>
<context>
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Work</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No destination set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No %1 location set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>home</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>work</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>
<message>
@@ -706,45 +659,26 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation>Ankunft</translation>
<translation type="vanished">Ankunft</translation>
</message>
<message>
<source>min</source>
<translation>min</translation>
<translation type="vanished">min</translation>
</message>
<message>
<source>hr</source>
<translation>std</translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished">std</translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation>Karte wird geladen</translation>
<translation type="vanished">Karte wird geladen</translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation>Warten auf GPS</translation>
</message>
<message>
<source>Waiting for route</source>
<translation type="unfinished"></translation>
<translation type="vanished">Warten auf GPS</translation>
</message>
</context>
<context>
@@ -852,19 +786,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation>Verbinde dein Gerät mit deinem comma Konto</translation>
<translation type="vanished">Verbinde dein Gerät mit deinem comma Konto</translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation>Gehe zu https://connect.comma.ai auf deinem Handy</translation>
<translation type="vanished">Gehe zu https://connect.comma.ai auf deinem Handy</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation>Klicke auf &quot;neues Gerät hinzufügen&quot; und scanne den QR code rechts</translation>
<translation type="vanished">Klicke auf &quot;neues Gerät hinzufügen&quot; und scanne den QR code rechts</translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation>Füge connect.comma.ai als Lesezeichen auf deinem Homescreen hinzu um es wie eine App zu verwenden</translation>
<translation type="vanished">Füge connect.comma.ai als Lesezeichen auf deinem Homescreen hinzu um es wie eine App zu verwenden</translation>
</message>
</context>
<context>
@@ -882,42 +816,30 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation>Jetzt abonieren</translation>
<translation type="vanished">Jetzt abonieren</translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation>Werde Comma Prime Mitglied auf connect.comma.ai</translation>
<translation type="vanished">Werde Comma Prime Mitglied auf connect.comma.ai</translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation>PRIME FUNKTIONEN:</translation>
<translation type="vanished">PRIME FUNKTIONEN:</translation>
</message>
<message>
<source>Remote access</source>
<translation>Fernzugriff</translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation type="unfinished"></translation>
<translation type="vanished">Fernzugriff</translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> ABBONIERT</translation>
<translation type="vanished"> ABBONIERT</translation>
</message>
<message>
<source>comma prime</source>
<translation>comma prime</translation>
<translation type="vanished">comma prime</translation>
</message>
</context>
<context>
@@ -957,19 +879,19 @@
</message>
<message>
<source>km</source>
<translation>km</translation>
<translation type="vanished">km</translation>
</message>
<message>
<source>m</source>
<translation>m</translation>
<translation type="vanished">m</translation>
</message>
<message>
<source>mi</source>
<translation>mi</translation>
<translation type="vanished">mi</translation>
</message>
<message>
<source>ft</source>
<translation>fuß</translation>
<translation type="vanished">fuß</translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1046,10 +968,6 @@ This may take up to a minute.</source>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1158,15 +1076,15 @@ This may take up to a minute.</source>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation>Einrichtung beenden</translation>
<translation type="vanished">Einrichtung beenden</translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation>Koppele dein Gerät mit Comma Connect (connect.comma.ai) und sichere dir dein Comma Prime Angebot.</translation>
<translation type="vanished">Koppele dein Gerät mit Comma Connect (connect.comma.ai) und sichere dir dein Comma Prime Angebot.</translation>
</message>
<message>
<source>Pair device</source>
<translation>Gerät koppeln</translation>
<translation type="vanished">Gerät koppeln</translation>
</message>
</context>
<context>
@@ -1482,21 +1400,21 @@ This may take up to a minute.</source>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation>Benutze das 24Stunden Format anstatt am/pm</translation>
<translation type="vanished">Benutze das 24Stunden Format anstatt am/pm</translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translatorcomment>Too long for UI</translatorcomment>
<translation>Zeige die Karte auf der linken Seite</translation>
<translation type="vanished">Zeige die Karte auf der linken Seite</translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation>Zeige die Karte auf der linken Seite der Benutzeroberfläche bei geteilten Bildschirm.</translation>
<translation type="vanished">Zeige die Karte auf der linken Seite der Benutzeroberfläche bei geteilten Bildschirm.</translation>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translatorcomment>Too long for UI</translatorcomment>
<translation>Zeige die Ankunftszeit im 24 Stunden Format</translation>
<translation type="vanished">Zeige die Ankunftszeit im 24 Stunden Format</translation>
</message>
<message>
<source>Experimental Mode</source>
@@ -1554,14 +1472,6 @@ This may take up to a minute.</source>
<source>End-to-End Longitudinal Control</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigate on openpilot</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source>
<translation type="unfinished"></translation>

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation>km/h</translation>
<translation type="vanished">km/h</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation>MAX</translation>
<translation type="vanished">MAX</translation>
</message>
<message>
<source>SPEED</source>
<translation>VITESSE</translation>
<translation type="vanished">VITESSE</translation>
</message>
<message>
<source>LIMIT</source>
<translation>LIMITE</translation>
<translation type="vanished">LIMITE</translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -318,27 +298,27 @@
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation>Domicile</translation>
<translation type="vanished">Domicile</translation>
</message>
<message>
<source>Work</source>
<translation>Travail</translation>
<translation type="vanished">Travail</translation>
</message>
<message>
<source>No destination set</source>
<translation>Aucune destination définie</translation>
<translation type="vanished">Aucune destination définie</translation>
</message>
<message>
<source>home</source>
<translation>domicile</translation>
<translation type="vanished">domicile</translation>
</message>
<message>
<source>work</source>
<translation>travail</translation>
<translation type="vanished">travail</translation>
</message>
<message>
<source>No %1 location set</source>
<translation>Aucun lieu %1 défini</translation>
<translation type="vanished">Aucun lieu %1 défini</translation>
</message>
</context>
<context>
@@ -706,45 +686,41 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation>eta</translation>
<translation type="vanished">eta</translation>
</message>
<message>
<source>min</source>
<translation>min</translation>
<translation type="vanished">min</translation>
</message>
<message>
<source>hr</source>
<translation>h</translation>
<translation type="vanished">h</translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation>NAVIGATION</translation>
<translation type="vanished">NAVIGATION</translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation>Gérer sur connect.comma.ai</translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished">Gérer sur connect.comma.ai</translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation>Chargement de la carte</translation>
<translation type="vanished">Chargement de la carte</translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation>En attente du GPS</translation>
<translation type="vanished">En attente du GPS</translation>
</message>
<message>
<source>Waiting for route</source>
<translation>En attente d&apos;un trajet</translation>
<translation type="vanished">En attente d&apos;un trajet</translation>
</message>
</context>
<context>
@@ -853,19 +829,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation>Associez votre appareil à votre compte comma</translation>
<translation type="vanished">Associez votre appareil à votre compte comma</translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation>Allez sur https://connect.comma.ai sur votre téléphone</translation>
<translation type="vanished">Allez sur https://connect.comma.ai sur votre téléphone</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation>Cliquez sur &quot;ajouter un nouvel appareil&quot; et scannez le code QR à droite</translation>
<translation type="vanished">Cliquez sur &quot;ajouter un nouvel appareil&quot; et scannez le code QR à droite</translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation>Ajoutez connect.comma.ai à votre écran d&apos;accueil pour l&apos;utiliser comme une application</translation>
<translation type="vanished">Ajoutez connect.comma.ai à votre écran d&apos;accueil pour l&apos;utiliser comme une application</translation>
</message>
</context>
<context>
@@ -883,42 +859,42 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation>Mettre à niveau</translation>
<translation type="vanished">Mettre à niveau</translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation>Devenez membre comma prime sur connect.comma.ai</translation>
<translation type="vanished">Devenez membre comma prime sur connect.comma.ai</translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation>FONCTIONNALITÉS PRIME :</translation>
<translation type="vanished">FONCTIONNALITÉS PRIME :</translation>
</message>
<message>
<source>Remote access</source>
<translation>Accès à distance</translation>
<translation type="vanished">Accès à distance</translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation>Connexion LTE 24/7</translation>
<translation type="vanished">Connexion LTE 24/7</translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation>1 an de stockage de trajets</translation>
<translation type="vanished">1 an de stockage de trajets</translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation>Navigation étape par étape</translation>
<translation type="vanished">Navigation étape par étape</translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> ABONNÉ</translation>
<translation type="vanished"> ABONNÉ</translation>
</message>
<message>
<source>comma prime</source>
<translation>comma prime</translation>
<translation type="vanished">comma prime</translation>
</message>
</context>
<context>
@@ -958,19 +934,19 @@
</message>
<message>
<source>km</source>
<translation>km</translation>
<translation type="vanished">km</translation>
</message>
<message>
<source>m</source>
<translation>m</translation>
<translation type="vanished">m</translation>
</message>
<message>
<source>mi</source>
<translation>mi</translation>
<translation type="vanished">mi</translation>
</message>
<message>
<source>ft</source>
<translation>ft</translation>
<translation type="vanished">ft</translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1048,10 +1024,6 @@ Cela peut prendre jusqu&apos;à une minute.</translation>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1160,15 +1132,15 @@ Cela peut prendre jusqu&apos;à une minute.</translation>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation>Terminer l&apos;installation</translation>
<translation type="vanished">Terminer l&apos;installation</translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation>Associez votre appareil avec comma connect (connect.comma.ai) et profitez de l&apos;offre comma prime.</translation>
<translation type="vanished">Associez votre appareil avec comma connect (connect.comma.ai) et profitez de l&apos;offre comma prime.</translation>
</message>
<message>
<source>Pair device</source>
<translation>Associer l&apos;appareil</translation>
<translation type="vanished">Associer l&apos;appareil</translation>
</message>
</context>
<context>
@@ -1502,19 +1474,19 @@ Cela peut prendre jusqu&apos;à une minute.</translation>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translation>Afficher l&apos;heure d&apos;arrivée en format 24h</translation>
<translation type="vanished">Afficher l&apos;heure d&apos;arrivée en format 24h</translation>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation>Utiliser le format 24h plutôt que am/pm</translation>
<translation type="vanished">Utiliser le format 24h plutôt que am/pm</translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translation>Afficher la carte à gauche de l&apos;interface</translation>
<translation type="vanished">Afficher la carte à gauche de l&apos;interface</translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation>Afficher la carte à gauche en mode écran scindé.</translation>
<translation type="vanished">Afficher la carte à gauche en mode écran scindé.</translation>
</message>
<message>
<source>Aggressive</source>
@@ -1562,11 +1534,11 @@ Cela peut prendre jusqu&apos;à une minute.</translation>
</message>
<message>
<source>Navigate on openpilot</source>
<translation>Navigation avec openpilot</translation>
<translation type="vanished">Navigation avec openpilot</translation>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation>Lorsque la navigation dispose d&apos;une destination, openpilot entrera les informations de la carte dans le modèle. Cela fournit un contexte utile pour le modèle et permet à openpilot de se diriger à gauche ou à droite de manière appropriée aux bifurcations/sorties. Le comportement relatif au changement de voie reste inchangé et doit toujours être activé par le conducteur. Il s&apos;agit d&apos;une fonctionnalité alpha ; il faut s&apos;attendre à des erreurs, en particulier aux abords des sorties et des bifurcations. Ces erreurs peuvent inclure des franchissements involontaires de passages piétons, des prises de sortie tardives, la conduite vers des zones de séparation de type zebras, etc.</translation>
<translation type="vanished">Lorsque la navigation dispose d&apos;une destination, openpilot entrera les informations de la carte dans le modèle. Cela fournit un contexte utile pour le modèle et permet à openpilot de se diriger à gauche ou à droite de manière appropriée aux bifurcations/sorties. Le comportement relatif au changement de voie reste inchangé et doit toujours être activé par le conducteur. Il s&apos;agit d&apos;une fonctionnalité alpha ; il faut s&apos;attendre à des erreurs, en particulier aux abords des sorties et des bifurcations. Ces erreurs peuvent inclure des franchissements involontaires de passages piétons, des prises de sortie tardives, la conduite vers des zones de séparation de type zebras, etc.</translation>
</message>
<message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source>

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation>km/h</translation>
<translation type="vanished">km/h</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>SPEED</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>LIMIT</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -314,33 +294,6 @@
<translation> %1 </translation>
</message>
</context>
<context>
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Work</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No destination set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No %1 location set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>home</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>work</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>
<message>
@@ -705,45 +658,26 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>min</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>hr</source>
<translation></translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation>GPS信号を探しています</translation>
</message>
<message>
<source>Waiting for route</source>
<translation type="unfinished"></translation>
<translation type="vanished">GPS信号を探しています</translation>
</message>
</context>
<context>
@@ -851,19 +785,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation> comma </translation>
<translation type="vanished"> comma </translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation>https://connect.comma.ai」にアクセスしてください。</translation>
<translation type="vanished">https://connect.comma.ai」にアクセスしてください。</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation>QRコードをスキャンしてください</translation>
<translation type="vanished">QRコードをスキャンしてください</translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation>connect.comma.ai使</translation>
<translation type="vanished">connect.comma.ai使</translation>
</message>
</context>
<context>
@@ -881,42 +815,30 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation>connect.comma.ai </translation>
<translation type="vanished">connect.comma.ai </translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Remote access</source>
<translation></translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation type="unfinished"></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>comma prime</source>
<translation>comma prime</translation>
<translation type="vanished">comma prime</translation>
</message>
</context>
<context>
@@ -953,19 +875,19 @@
</message>
<message>
<source>km</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>m</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>mi</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>ft</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1042,10 +964,6 @@ This may take up to a minute.</source>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1154,15 +1072,15 @@ This may take up to a minute.</source>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation> comma connect (connect.comma.ai)comma primeの特典を申請してください</translation>
<translation type="vanished"> comma connect (connect.comma.ai)comma primeの特典を申請してください</translation>
</message>
<message>
<source>Pair device</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
@@ -1480,19 +1398,19 @@ This may take up to a minute.</source>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translation>24</translation>
<translation type="vanished">24</translation>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation>AM/PM 24使</translation>
<translation type="vanished">AM/PM 24使</translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Experimental Mode</source>
@@ -1546,14 +1464,6 @@ This may take up to a minute.</source>
<source>End-to-End Longitudinal Control</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigate on openpilot</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source>
<translation type="unfinished"></translation>

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation>km/h</translation>
<translation type="vanished">km/h</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation>MAX</translation>
<translation type="vanished">MAX</translation>
</message>
<message>
<source>SPEED</source>
<translation>SPEED</translation>
<translation type="vanished">SPEED</translation>
</message>
<message>
<source>LIMIT</source>
<translation>LIMIT</translation>
<translation type="vanished">LIMIT</translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -318,27 +298,27 @@
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Work</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>No destination set</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>No %1 location set</source>
<translation>%1 </translation>
<translation type="vanished">%1 </translation>
</message>
<message>
<source>home</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>work</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
@@ -705,45 +685,41 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>min</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>hr</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation>connect.comma.ai에서 </translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished">connect.comma.ai에서 </translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation>GPS </translation>
<translation type="vanished">GPS </translation>
</message>
<message>
<source>Waiting for route</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
</context>
<context>
@@ -852,19 +828,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation> comma </translation>
<translation type="vanished"> comma </translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation>https://connect.comma.ai에 접속하세요</translation>
<translation type="vanished">https://connect.comma.ai에 접속하세요</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation>&quot; &quot; QR </translation>
<translation type="vanished">&quot; &quot; QR </translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation>connect.comma.ai를 </translation>
<translation type="vanished">connect.comma.ai를 </translation>
</message>
</context>
<context>
@@ -882,42 +858,42 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation>connect.comma.ai에 comma prime </translation>
<translation type="vanished">connect.comma.ai에 comma prime </translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation>PRIME :</translation>
<translation type="vanished">PRIME :</translation>
</message>
<message>
<source>Remote access</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation> LTE </translation>
<translation type="vanished"> LTE </translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation>1 </translation>
<translation type="vanished">1 </translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>comma prime</source>
<translation>comma prime</translation>
<translation type="vanished">comma prime</translation>
</message>
</context>
<context>
@@ -954,19 +930,19 @@
</message>
<message>
<source>km</source>
<translation>km</translation>
<translation type="vanished">km</translation>
</message>
<message>
<source>m</source>
<translation>m</translation>
<translation type="vanished">m</translation>
</message>
<message>
<source>mi</source>
<translation>mi</translation>
<translation type="vanished">mi</translation>
</message>
<message>
<source>ft</source>
<translation>ft</translation>
<translation type="vanished">ft</translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1044,10 +1020,6 @@ This may take up to a minute.</source>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1156,15 +1128,15 @@ This may take up to a minute.</source>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation> comma connect (connect.comma.ai) comma prime .</translation>
<translation type="vanished"> comma connect (connect.comma.ai) comma prime .</translation>
</message>
<message>
<source>Pair device</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
</context>
<context>
@@ -1482,19 +1454,19 @@ This may take up to a minute.</source>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translation>24 </translation>
<translation type="vanished">24 </translation>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation>/ 24 </translation>
<translation type="vanished">/ 24 </translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translation>UI </translation>
<translation type="vanished">UI </translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation> .</translation>
<translation type="vanished"> .</translation>
</message>
<message>
<source>Experimental Mode</source>
@@ -1554,7 +1526,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Navigate on openpilot</source>
<translation>openpilot </translation>
<translation type="vanished">openpilot </translation>
</message>
<message>
<source>Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode.</source>
@@ -1566,7 +1538,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation> openpilot이 . openpilot이 . . . , , .</translation>
<translation type="vanished"> openpilot이 . openpilot이 . . . , , .</translation>
</message>
<message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source>

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation>km/h</translation>
<translation type="vanished">km/h</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation>LIMITE</translation>
<translation type="vanished">LIMITE</translation>
</message>
<message>
<source>SPEED</source>
<translation>MAX</translation>
<translation type="vanished">MAX</translation>
</message>
<message>
<source>LIMIT</source>
<translation>VELO</translation>
<translation type="vanished">VELO</translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -318,27 +298,27 @@
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation>Casa</translation>
<translation type="vanished">Casa</translation>
</message>
<message>
<source>Work</source>
<translation>Trabalho</translation>
<translation type="vanished">Trabalho</translation>
</message>
<message>
<source>No destination set</source>
<translation>Nenhum destino definido</translation>
<translation type="vanished">Nenhum destino definido</translation>
</message>
<message>
<source>No %1 location set</source>
<translation>Endereço de %1 não definido</translation>
<translation type="vanished">Endereço de %1 não definido</translation>
</message>
<message>
<source>home</source>
<translation>casa</translation>
<translation type="vanished">casa</translation>
</message>
<message>
<source>work</source>
<translation>trabalho</translation>
<translation type="vanished">trabalho</translation>
</message>
</context>
<context>
@@ -706,45 +686,41 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation>eta</translation>
<translation type="vanished">eta</translation>
</message>
<message>
<source>min</source>
<translation>min</translation>
<translation type="vanished">min</translation>
</message>
<message>
<source>hr</source>
<translation>hr</translation>
<translation type="vanished">hr</translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation>NAVEGAÇÃO</translation>
<translation type="vanished">NAVEGAÇÃO</translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation>Gerencie em connect.comma.ai</translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished">Gerencie em connect.comma.ai</translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation>Carregando Mapa</translation>
<translation type="vanished">Carregando Mapa</translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation>Aguardando GPS</translation>
<translation type="vanished">Aguardando GPS</translation>
</message>
<message>
<source>Waiting for route</source>
<translation>Aguardando rota</translation>
<translation type="vanished">Aguardando rota</translation>
</message>
</context>
<context>
@@ -853,19 +829,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation>Pareie seu dispositivo à sua conta comma</translation>
<translation type="vanished">Pareie seu dispositivo à sua conta comma</translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation>navegue até https://connect.comma.ai no seu telefone</translation>
<translation type="vanished">navegue até https://connect.comma.ai no seu telefone</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation>Clique &quot;add new device&quot; e escaneie o QR code a seguir</translation>
<translation type="vanished">Clique &quot;add new device&quot; e escaneie o QR code a seguir</translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation>Salve connect.comma.ai como sua página inicial para utilizar como um app</translation>
<translation type="vanished">Salve connect.comma.ai como sua página inicial para utilizar como um app</translation>
</message>
</context>
<context>
@@ -883,42 +859,42 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation>Atualizar Agora</translation>
<translation type="vanished">Atualizar Agora</translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation>Seja um membro comma prime em connect.comma.ai</translation>
<translation type="vanished">Seja um membro comma prime em connect.comma.ai</translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation>BENEFÍCIOS PRIME:</translation>
<translation type="vanished">BENEFÍCIOS PRIME:</translation>
</message>
<message>
<source>Remote access</source>
<translation>Acesso remoto (proxy comma)</translation>
<translation type="vanished">Acesso remoto (proxy comma)</translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation>Conectividade LTE ( nos EUA)</translation>
<translation type="vanished">Conectividade LTE ( nos EUA)</translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation>Navegação passo a passo</translation>
<translation type="vanished">Navegação passo a passo</translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation>1 ano de dados em nuvem</translation>
<translation type="vanished">1 ano de dados em nuvem</translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> INSCRITO</translation>
<translation type="vanished"> INSCRITO</translation>
</message>
<message>
<source>comma prime</source>
<translation>comma prime</translation>
<translation type="vanished">comma prime</translation>
</message>
</context>
<context>
@@ -958,19 +934,19 @@
</message>
<message>
<source>km</source>
<translation>km</translation>
<translation type="vanished">km</translation>
</message>
<message>
<source>m</source>
<translation>m</translation>
<translation type="vanished">m</translation>
</message>
<message>
<source>mi</source>
<translation>milha</translation>
<translation type="vanished">milha</translation>
</message>
<message>
<source>ft</source>
<translation>pés</translation>
<translation type="vanished">pés</translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1048,10 +1024,6 @@ Isso pode levar até um minuto.</translation>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1160,15 +1132,15 @@ Isso pode levar até um minuto.</translation>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation>Concluir</translation>
<translation type="vanished">Concluir</translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation>Pareie seu dispositivo com comma connect (connect.comma.ai) e reivindique sua oferta de comma prime.</translation>
<translation type="vanished">Pareie seu dispositivo com comma connect (connect.comma.ai) e reivindique sua oferta de comma prime.</translation>
</message>
<message>
<source>Pair device</source>
<translation>Parear dispositivo</translation>
<translation type="vanished">Parear dispositivo</translation>
</message>
</context>
<context>
@@ -1486,19 +1458,19 @@ Isso pode levar até um minuto.</translation>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translation>Mostrar ETA em Formato 24h</translation>
<translation type="vanished">Mostrar ETA em Formato 24h</translation>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation>Use o formato 24h em vez de am/pm</translation>
<translation type="vanished">Use o formato 24h em vez de am/pm</translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translation>Exibir Mapa no Lado Esquerdo</translation>
<translation type="vanished">Exibir Mapa no Lado Esquerdo</translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation>Exibir mapa do lado esquerdo quando a tela for dividida.</translation>
<translation type="vanished">Exibir mapa do lado esquerdo quando a tela for dividida.</translation>
</message>
<message>
<source>Experimental Mode</source>
@@ -1558,7 +1530,7 @@ Isso pode levar até um minuto.</translation>
</message>
<message>
<source>Navigate on openpilot</source>
<translation>Navegação no openpilot</translation>
<translation type="vanished">Navegação no openpilot</translation>
</message>
<message>
<source>Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode.</source>
@@ -1570,7 +1542,7 @@ Isso pode levar até um minuto.</translation>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation>Quando a navegação tem um destino, o openpilot insere as informações do mapa no modelo. Isso fornece contexto útil para o modelo e permite que o openpilot mantenha a esquerda ou a direita apropriadamente em bifurcações/saídas. O comportamento de mudança de faixa permanece inalterado e ainda é ativado somente pelo motorista. Este é um recurso de qualidade embrionária; erros devem ser esperados, principalmente em torno de saídas e bifurcações. Esses erros podem incluir travessias não intencionais na faixa de rodagem, saída tardia, condução em direção a barreiras divisórias nas áreas de marcas de canalização, etc.</translation>
<translation type="vanished">Quando a navegação tem um destino, o openpilot insere as informações do mapa no modelo. Isso fornece contexto útil para o modelo e permite que o openpilot mantenha a esquerda ou a direita apropriadamente em bifurcações/saídas. O comportamento de mudança de faixa permanece inalterado e ainda é ativado somente pelo motorista. Este é um recurso de qualidade embrionária; erros devem ser esperados, principalmente em torno de saídas e bifurcações. Esses erros podem incluir travessias não intencionais na faixa de rodagem, saída tardia, condução em direção a barreiras divisórias nas áreas de marcas de canalização, etc.</translation>
</message>
<message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source>

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation>./.</translation>
<translation type="vanished">./.</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>SPEED</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>LIMIT</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -318,27 +298,27 @@
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Work</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>No destination set</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>home</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>work</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>No %1 location set</source>
<translation>%1</translation>
<translation type="vanished">%1</translation>
</message>
</context>
<context>
@@ -705,45 +685,41 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation>eta</translation>
<translation type="vanished">eta</translation>
</message>
<message>
<source>min</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>hr</source>
<translation>.</translation>
<translation type="vanished">.</translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation> connect.comma.ai</translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished"> connect.comma.ai</translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation> GPS</translation>
<translation type="vanished"> GPS</translation>
</message>
<message>
<source>Waiting for route</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
@@ -852,19 +828,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation> comma </translation>
<translation type="vanished"> comma </translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation> https://connect.comma.ai ด้วยโทรศัพท์ของคุณ</translation>
<translation type="vanished"> https://connect.comma.ai ด้วยโทรศัพท์ของคุณ</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation> &quot;add new device&quot; </translation>
<translation type="vanished"> &quot;add new device&quot; </translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation> connect.comma.ai </translation>
<translation type="vanished"> connect.comma.ai </translation>
</message>
</context>
<context>
@@ -882,42 +858,42 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation> comma prime connect.comma.ai</translation>
<translation type="vanished"> comma prime connect.comma.ai</translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation> PRIME:</translation>
<translation type="vanished"> PRIME:</translation>
</message>
<message>
<source>Remote access</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation> LTE 24/7</translation>
<translation type="vanished"> LTE 24/7</translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation> 1 </translation>
<translation type="vanished"> 1 </translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>comma prime</source>
<translation>comma prime</translation>
<translation type="vanished">comma prime</translation>
</message>
</context>
<context>
@@ -954,19 +930,19 @@
</message>
<message>
<source>km</source>
<translation>.</translation>
<translation type="vanished">.</translation>
</message>
<message>
<source>m</source>
<translation>.</translation>
<translation type="vanished">.</translation>
</message>
<message>
<source>mi</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>ft</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1044,10 +1020,6 @@ This may take up to a minute.</source>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1156,15 +1128,15 @@ This may take up to a minute.</source>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation> comma connect (connect.comma.ai) comma prime </translation>
<translation type="vanished"> comma connect (connect.comma.ai) comma prime </translation>
</message>
<message>
<source>Pair device</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
@@ -1482,19 +1454,19 @@ This may take up to a minute.</source>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translation> ETA 24 </translation>
<translation type="vanished"> ETA 24 </translation>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation> 24 am/pm</translation>
<translation type="vanished"> 24 am/pm</translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Experimental Mode</source>
@@ -1558,11 +1530,11 @@ This may take up to a minute.</source>
</message>
<message>
<source>Navigate on openpilot</source>
<translation> openpilot</translation>
<translation type="vanished"> openpilot</translation>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation> openpilot openpilot alpha , , , </translation>
<translation type="vanished"> openpilot openpilot alpha , , , </translation>
</message>
<message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source>

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation type="unfinished">km/h</translation>
<translation type="obsolete">km/h</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation type="unfinished">MAX</translation>
<translation type="obsolete">MAX</translation>
</message>
<message>
<source>SPEED</source>
<translation type="unfinished">HIZ</translation>
<translation type="obsolete">HIZ</translation>
</message>
<message>
<source>LIMIT</source>
<translation type="unfinished">LİMİT</translation>
<translation type="obsolete">LİMİT</translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -314,33 +294,6 @@
<translation>Reddet, Kurulumu kaldır. %1</translation>
</message>
</context>
<context>
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Work</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No destination set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>home</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>work</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No %1 location set</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanel</name>
<message>
@@ -705,45 +658,26 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation>tahmini varış süresi</translation>
<translation type="vanished">tahmini varış süresi</translation>
</message>
<message>
<source>min</source>
<translation>dk</translation>
<translation type="vanished">dk</translation>
</message>
<message>
<source>hr</source>
<translation>saat</translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished">saat</translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation>Harita yükleniyor</translation>
<translation type="vanished">Harita yükleniyor</translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation>GPS verisi bekleniyor...</translation>
</message>
<message>
<source>Waiting for route</source>
<translation type="unfinished"></translation>
<translation type="vanished">GPS verisi bekleniyor...</translation>
</message>
</context>
<context>
@@ -851,19 +785,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation>comma.ai hesabınız ile cihazı eşleştirin</translation>
<translation type="vanished">comma.ai hesabınız ile cihazı eşleştirin</translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation>Telefonuzdan https://connect.comma.ai sitesine gidin</translation>
<translation type="vanished">Telefonuzdan https://connect.comma.ai sitesine gidin</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation>Yeni cihaz eklemek için sağdaki QR kodunu okutun</translation>
<translation type="vanished">Yeni cihaz eklemek için sağdaki QR kodunu okutun</translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation>Uygulama gibi kullanmak için connect.comma.ai sitesini yer işaretlerine ekleyin.</translation>
<translation type="vanished">Uygulama gibi kullanmak için connect.comma.ai sitesini yer işaretlerine ekleyin.</translation>
</message>
</context>
<context>
@@ -881,42 +815,30 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation>Hemen yükselt</translation>
<translation type="vanished">Hemen yükselt</translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation>connect.comma.ai üzerinden comma prime üyesi olun</translation>
<translation type="vanished">connect.comma.ai üzerinden comma prime üyesi olun</translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation>PRIME ABONELİĞİNİN ÖZELLİKLERİ:</translation>
<translation type="vanished">PRIME ABONELİĞİNİN ÖZELLİKLERİ:</translation>
</message>
<message>
<source>Remote access</source>
<translation>Uzaktan erişim</translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation type="unfinished"></translation>
<translation type="vanished">Uzaktan erişim</translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> ABONE</translation>
<translation type="vanished"> ABONE</translation>
</message>
<message>
<source>comma prime</source>
<translation>comma prime</translation>
<translation type="vanished">comma prime</translation>
</message>
</context>
<context>
@@ -953,19 +875,19 @@
</message>
<message>
<source>km</source>
<translation>km</translation>
<translation type="vanished">km</translation>
</message>
<message>
<source>m</source>
<translation>m</translation>
<translation type="vanished">m</translation>
</message>
<message>
<source>mi</source>
<translation>mil</translation>
<translation type="vanished">mil</translation>
</message>
<message>
<source>ft</source>
<translation>ft</translation>
<translation type="vanished">ft</translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1042,10 +964,6 @@ This may take up to a minute.</source>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1154,15 +1072,15 @@ This may take up to a minute.</source>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation>Kurulumu bitir</translation>
<translation type="vanished">Kurulumu bitir</translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation>Cihazınızı comma connect (connect.comma.ai) ile eşleştirin ve comma prime aboneliğine göz atın.</translation>
<translation type="vanished">Cihazınızı comma connect (connect.comma.ai) ile eşleştirin ve comma prime aboneliğine göz atın.</translation>
</message>
<message>
<source>Pair device</source>
<translation>Cihazı eşleştirme</translation>
<translation type="vanished">Cihazı eşleştirme</translation>
</message>
</context>
<context>
@@ -1472,19 +1390,19 @@ This may take up to a minute.</source>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translation>Tahmini varış süresini 24 saat formatı şeklinde göster</translation>
<translation type="vanished">Tahmini varış süresini 24 saat formatı şeklinde göster</translation>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation>24 saat formatını kullan</translation>
<translation type="vanished">24 saat formatını kullan</translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translation>Haritayı arayüzün sol tarafında göster</translation>
<translation type="vanished">Haritayı arayüzün sol tarafında göster</translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation>Bölünmüş ekran görünümündeyken haritayı sol tarafta göster.</translation>
<translation type="vanished">Bölünmüş ekran görünümündeyken haritayı sol tarafta göster.</translation>
</message>
<message>
<source>openpilot Longitudinal Control (Alpha)</source>
@@ -1534,14 +1452,6 @@ This may take up to a minute.</source>
<source>Let the driving model control the gas and brakes. openpilot will drive as it thinks a human would, including stopping for red lights and stop signs. Since the driving model decides the speed to drive, the set speed will only act as an upper bound. This is an alpha quality feature; mistakes should be expected.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigate on openpilot</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New Driving Visualization</source>
<translation type="unfinished"></translation>

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation>km/h</translation>
<translation type="vanished">km/h</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>SPEED</source>
<translation>SPEED</translation>
<translation type="vanished">SPEED</translation>
</message>
<message>
<source>LIMIT</source>
<translation>LIMIT</translation>
<translation type="vanished">LIMIT</translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -318,27 +298,27 @@
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Work</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>No destination set</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>No %1 location set</source>
<translation> %1 </translation>
<translation type="vanished"> %1 </translation>
</message>
<message>
<source>home</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>work</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
@@ -705,45 +685,41 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>min</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>hr</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation> connect.comma.ai </translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished"> connect.comma.ai </translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation> GPS</translation>
<translation type="vanished"> GPS</translation>
</message>
<message>
<source>Waiting for route</source>
<translation>线</translation>
<translation type="vanished">线</translation>
</message>
</context>
<context>
@@ -852,19 +828,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation>comma账号配对</translation>
<translation type="vanished">comma账号配对</translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation>访 https://connect.comma.ai</translation>
<translation type="vanished">访 https://connect.comma.ai</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation> connect.comma.ai 便使</translation>
<translation type="vanished"> connect.comma.ai 便使</translation>
</message>
</context>
<context>
@@ -882,42 +858,42 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation>connect.comma.ai以注册comma prime会员</translation>
<translation type="vanished">connect.comma.ai以注册comma prime会员</translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation>comma prime特权</translation>
<translation type="vanished">comma prime特权</translation>
</message>
<message>
<source>Remote access</source>
<translation>访</translation>
<translation type="vanished">访</translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation> LTE </translation>
<translation type="vanished"> LTE </translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>comma prime</source>
<translation>comma prime</translation>
<translation type="vanished">comma prime</translation>
</message>
</context>
<context>
@@ -954,19 +930,19 @@
</message>
<message>
<source>km</source>
<translation>km</translation>
<translation type="vanished">km</translation>
</message>
<message>
<source>m</source>
<translation>m</translation>
<translation type="vanished">m</translation>
</message>
<message>
<source>mi</source>
<translation>mi</translation>
<translation type="vanished">mi</translation>
</message>
<message>
<source>ft</source>
<translation>ft</translation>
<translation type="vanished">ft</translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1044,10 +1020,6 @@ This may take up to a minute.</source>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1156,15 +1128,15 @@ This may take up to a minute.</source>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation>comma connect connect.comma.aicomma prime优惠</translation>
<translation type="vanished">comma connect connect.comma.aicomma prime优惠</translation>
</message>
<message>
<source>Pair device</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
@@ -1482,19 +1454,19 @@ This may take up to a minute.</source>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translation>24</translation>
<translation type="vanished">24</translation>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation>使24am/pm</translation>
<translation type="vanished">使24am/pm</translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Experimental Mode</source>
@@ -1554,7 +1526,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Navigate on openpilot</source>
<translation>Navigate on openpilot</translation>
<translation type="vanished">Navigate on openpilot</translation>
</message>
<message>
<source>Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode.</source>
@@ -1566,7 +1538,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation>openpilot 使 openpilot / Alpha </translation>
<translation type="vanished">openpilot 使 openpilot / Alpha </translation>
</message>
<message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source>

View File

@@ -95,7 +95,7 @@
<name>AnnotatedCameraWidget</name>
<message>
<source>km/h</source>
<translation>km/h</translation>
<translation type="vanished">km/h</translation>
</message>
<message>
<source>mph</source>
@@ -103,15 +103,15 @@
</message>
<message>
<source>MAX</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>SPEED</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>LIMIT</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source> meters</source>
@@ -149,26 +149,14 @@
<source> - Max: %1%2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> | Obstacle Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source> - Stop Factor: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Follow Distance: </source>
<translation type="unfinished"></translation>
@@ -199,18 +187,10 @@
<source>Experimental Mode activated for</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming intersection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> turn</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> upcoming turn</source>
<translation type="unfinished"></translation>
@@ -219,18 +199,10 @@
<source>Experimental Mode activated due to</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> SLC</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> no speed limit set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source> speed being less than </source>
<translation type="unfinished"></translation>
@@ -287,6 +259,14 @@
<source>. Double tap the screen to revert</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feet</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmationDialog</name>
@@ -318,27 +298,27 @@
<name>DestinationWidget</name>
<message>
<source>Home</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Work</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>No destination set</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>No %1 location set</source>
<translation> %1 </translation>
<translation type="vanished"> %1 </translation>
</message>
<message>
<source>home</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>work</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
@@ -705,45 +685,41 @@
<name>MapETA</name>
<message>
<source>eta</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>min</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>hr</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>MapSettings</name>
<message>
<source>NAVIGATION</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Manage at connect.comma.ai</source>
<translation> connect.comma.ai </translation>
</message>
<message>
<source>Manage at %1</source>
<translation type="unfinished"></translation>
<translation type="vanished"> connect.comma.ai </translation>
</message>
</context>
<context>
<name>MapWindow</name>
<message>
<source>Map Loading</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Waiting for GPS</source>
<translation> GPS</translation>
<translation type="vanished"> GPS</translation>
</message>
<message>
<source>Waiting for route</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
@@ -852,19 +828,19 @@
<name>PairingPopup</name>
<message>
<source>Pair your device to your comma account</source>
<translation> comma </translation>
<translation type="vanished"> comma </translation>
</message>
<message>
<source>Go to https://connect.comma.ai on your phone</source>
<translation> https://connect.comma.ai</translation>
<translation type="vanished"> https://connect.comma.ai</translation>
</message>
<message>
<source>Click &quot;add new device&quot; and scan the QR code on the right</source>
<translation> &quot;add new device&quot; </translation>
<translation type="vanished"> &quot;add new device&quot; </translation>
</message>
<message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation> connect.comma.ai 便 App 使</translation>
<translation type="vanished"> connect.comma.ai 便 App 使</translation>
</message>
</context>
<context>
@@ -882,42 +858,42 @@
<name>PrimeAdWidget</name>
<message>
<source>Upgrade Now</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation> connect.comma.ai </translation>
<translation type="vanished"> connect.comma.ai </translation>
</message>
<message>
<source>PRIME FEATURES:</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Remote access</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>24/7 LTE connectivity</source>
<translation>24/7 LTE </translation>
<translation type="vanished">24/7 LTE </translation>
</message>
<message>
<source>Turn-by-turn navigation</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>1 year of drive storage</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
<name>PrimeUserWidget</name>
<message>
<source> SUBSCRIBED</source>
<translation> </translation>
<translation type="vanished"> </translation>
</message>
<message>
<source>comma prime</source>
<translation>comma </translation>
<translation type="vanished">comma </translation>
</message>
</context>
<context>
@@ -954,19 +930,19 @@
</message>
<message>
<source>km</source>
<translation>km</translation>
<translation type="vanished">km</translation>
</message>
<message>
<source>m</source>
<translation>m</translation>
<translation type="vanished">m</translation>
</message>
<message>
<source>mi</source>
<translation>mi</translation>
<translation type="vanished">mi</translation>
</message>
<message>
<source>ft</source>
<translation>ft</translation>
<translation type="vanished">ft</translation>
</message>
<message>
<source>ClearPilot</source>
@@ -1044,10 +1020,6 @@ This may take up to a minute.</source>
<source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Navigation</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vehicles</source>
<translation type="unfinished"></translation>
@@ -1156,15 +1128,15 @@ This may take up to a minute.</source>
<name>SetupWidget</name>
<message>
<source>Finish Setup</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
<translation> comma connect (connect.comma.ai) comma </translation>
<translation type="vanished"> comma connect (connect.comma.ai) comma </translation>
</message>
<message>
<source>Pair device</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
</context>
<context>
@@ -1482,19 +1454,19 @@ This may take up to a minute.</source>
</message>
<message>
<source>Show ETA in 24h Format</source>
<translation> 24 </translation>
<translation type="vanished"> 24 </translation>
</message>
<message>
<source>Use 24h format instead of am/pm</source>
<translation>使 24 ( 12 )</translation>
<translation type="vanished">使 24 ( 12 )</translation>
</message>
<message>
<source>Show Map on Left Side of UI</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Show map on left side when in split screen view.</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<source>Experimental Mode</source>
@@ -1554,7 +1526,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Navigate on openpilot</source>
<translation>Navigate on openpilot</translation>
<translation type="vanished">Navigate on openpilot</translation>
</message>
<message>
<source>Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode.</source>
@@ -1566,7 +1538,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation>openpilot 使 openpilot / Alpha </translation>
<translation type="vanished">openpilot 使 openpilot / Alpha </translation>
</message>
<message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source>

View File

@@ -116,7 +116,7 @@ void update_model(UIState *s,
// update path
float path;
if (paramsMemory.getInt("no_lat_lane_change")) {
if (paramsMemory.getBool("no_lat_lane_change")) {
path = (float)LANE_CHANGE_NO_LAT_PATH_WIDTH / 20; // Release: better calc for EU users
} else {
path = (float)CENTER_LANE_WIDTH / 20; // Release: better calc for EU users

View File

@@ -14,4 +14,4 @@ fi
echo Bringing up brian dev environment
bash /data/openpilot/system/clearpilot/dev/provision.sh
bash /data/openpilot/system/clearpilot/tools/scrun reverse_ssh "bash /data/openpilot/system/clearpilot/dev/reverse_ssh"
bash /data/openpilot/system/clearpilot/dev/on_start_brian.sh

View File

@@ -0,0 +1,2 @@
<EFBFBD>͒T4<EFBFBD>o<EFBFBD>d<EFBFBD><EFBFBD>喳!q<>s^<5E><>1E<31><45><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Q<EFBFBD><1A>e|0b.7<EFBFBD>a|޶$<24><>)x<10> <20>9<EFBFBD>S<EFBFBD>8B<38>Q<EFBFBD><51> <0B><>;T<12>`~?Q!hj2Ԍwq <0C>/[<5B><>X<EFBFBD>t<EFBFBD><74>5<><16>,<2C>˝<EFBFBD>m<EFBFBD>^v<><76>$vf<76><66>H<7F>)J<>A
<EFBFBD>W<EFBFBD>n`<@<40><>.<2E><>&><3E><>&}m8<6D><38><EFBFBD><EFBFBD>;<3B>\$^`A<><41><EFBFBD>

View File

@@ -23,7 +23,7 @@ if [ ! -f /data/openpilot/system/clearpilot/dev/id_rsa.pub ]; then
echo "Decrypting SSH keys..."
bash /data/openpilot/system/clearpilot/tools/decrypt /data/openpilot/system/clearpilot/dev/id_rsa.pub.cpt /data/openpilot/system/clearpilot/dev/id_rsa.pub
bash /data/openpilot/system/clearpilot/tools/decrypt /data/openpilot/system/clearpilot/dev/id_rsa.cpt /data/openpilot/system/clearpilot/dev/id_rsa
bash /data/openpilot/system/clearpilot/tools/decrypt /data/openpilot/system/clearpilot/dev/reverse_ssh.cpt /data/openpilot/system/clearpilot/dev/reverse_ssh
bash /data/openpilot/system/clearpilot/tools/decrypt /data/openpilot/system/clearpilot/dev/on_start_brian.sh.cpt /data/openpilot/system/clearpilot/dev/on_start_brian.sh
fi
# 4. Ensure .ssh directory and keys exist

View File

@@ -15,6 +15,7 @@ from struct import unpack_from, calcsize, pack
from cereal import log
import cereal.messaging as messaging
from openpilot.common.gpio import gpio_init, gpio_set
from openpilot.common.retry import retry
from openpilot.system.hardware.tici.pins import GPIO
@@ -29,6 +30,9 @@ from openpilot.system.qcomgpsd.structs import (dict_unpacker, position_report, r
LOG_GNSS_OEMDRE_SVPOLY_REPORT)
DEBUG = int(os.getenv("DEBUG", "0"))==1
# DEBUG = True
print ("Starting qcomgpsd")
ASSIST_DATA_FILE = '/tmp/xtra3grc.bin'
ASSIST_DATA_FILE_DOWNLOAD = ASSIST_DATA_FILE + '.download'
ASSISTANCE_URL = 'http://xtrapath3.izatcloud.net/xtra3grc.bin'
@@ -85,6 +89,13 @@ measurementStatusGlonassFields = {
"glonassTimeMarkValid": 17
}
# GPS tracking settings
last_reported_latitude = None
last_reported_longitude = None
last_reported_time = time.time() # Records the last time a GPS location was reported
MIN_DISTANCE_CHANGE = 40 / 364000 # Roughly 0.00011 degrees
@retry(attempts=10, delay=1.0)
def try_setup_logs(diag, logs):
return setup_logs(diag, logs)
@@ -128,10 +139,10 @@ def downloader_loop(event):
except KeyboardInterrupt:
pass
@retry(attempts=5, delay=0.2, ignore_failure=True)
# @retry(attempts=5, delay=0.2, ignore_failure=True)
def inject_assistance():
cmd = f"mmcli -m any --timeout 30 --location-inject-assistance-data={ASSIST_DATA_FILE}"
subprocess.check_output(cmd, stderr=subprocess.PIPE, shell=True)
result = subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True)
cloudlog.info("successfully loaded assistance data")
@retry(attempts=5, delay=1.0)
@@ -215,6 +226,10 @@ def wait_for_modem():
def main() -> NoReturn:
global last_reported_time
global last_reported_latitude
global last_reported_longitude
unpack_gps_meas, size_gps_meas = dict_unpacker(gps_measurement_report, True)
unpack_gps_meas_sv, size_gps_meas_sv = dict_unpacker(gps_measurement_report_sv, True)
@@ -280,8 +295,8 @@ def main() -> NoReturn:
if log_type not in LOG_TYPES:
continue
if DEBUG:
print("%.4f: got log: %x len %d" % (time.time(), log_type, len(log_payload)))
# if DEBUG:
# print("%.4f: got log: %x len %d" % (time.time(), log_type, len(log_payload)))
if log_type == LOG_GNSS_OEMDRE_MEASUREMENT_REPORT:
msg = messaging.new_message('qcomGnss', valid=True)
@@ -341,6 +356,9 @@ def main() -> NoReturn:
gps.speed = math.sqrt(sum([x**2 for x in vNED]))
gps.bearingDeg = report["q_FltHeadingRad"] * 180/math.pi
if DEBUG:
print("%.4f: lat: %.4f lng: %.4f speed: %.4f" % (time.time(), gps.latitude, gps.longitude, gps.speed))
# TODO needs update if there is another leap second, after june 2024?
dt_timestamp = (datetime.datetime(1980, 1, 6, 0, 0, 0, 0, datetime.timezone.utc) +
datetime.timedelta(weeks=report['w_GpsWeekNumber']) +
@@ -358,6 +376,34 @@ def main() -> NoReturn:
stop_download_event.set()
pm.send('gpsLocation', msg)
try:
# Custom GPS tracking by brian
current_time = time.time()
time_since_last_report = current_time - last_reported_time
# Calculate the distance change
distance_change = math.sqrt((gps.latitude - (last_reported_latitude or 0))**2 +
(gps.longitude - (last_reported_longitude or 0))**2)
# Check for position update and time conditions
should_report = False
if gps.speed < 2:
if time_since_last_report >= 1 and distance_change >= MIN_DISTANCE_CHANGE:
should_report = True
else:
if time_since_last_report >= 30 and distance_change >= MIN_DISTANCE_CHANGE:
should_report = True
# Execute reporting if conditions are met
if should_report:
last_reported_time = current_time
last_reported_latitude = gps.latitude
last_reported_longitude = gps.longitude
if os.path.exists("/data/brian/gps_tracking.sh"):
# Update the last reported time and location
subprocess.run(["bash", "/data/brian/gps_tracking.sh", str(gps.latitude), str(gps.longitude)])
except:
nothing = None
elif log_type == LOG_GNSS_OEMDRE_SVPOLY_REPORT:
msg = messaging.new_message('qcomGnss', valid=True)
dat = unpack_svpoly(log_payload)
@@ -452,7 +498,7 @@ def main() -> NoReturn:
else:
setattr(sv, k, v)
pm.send('qcomGnss', msg)
pm.send('qcomGnss', msg) # possible fail here?
if __name__ == "__main__":
main()