Compare commits
77 Commits
d6fff3fa1b
...
clearpilot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
980f0aac00 | ||
|
|
0fc13d815d | ||
|
|
ac4d7efff1 | ||
|
|
a47fbb140d | ||
|
|
8225319314 | ||
|
|
3eca593af1 | ||
|
|
445138519d | ||
|
|
679a952f51 | ||
|
|
1b9097bc13 | ||
|
|
4c9c211f97 | ||
|
|
c94dc803dd | ||
|
|
33c59eadb3 | ||
|
|
92db8a5913 | ||
|
|
af3cacae53 | ||
|
|
ec7743c460 | ||
|
|
5e80ad8d05 | ||
|
|
a2cf02ea37 | ||
|
|
75c91213a2 | ||
|
|
7f182b7fae | ||
|
|
0c36ffdfde | ||
|
|
4702c22aa3 | ||
|
|
6ef4519798 | ||
|
|
5e4c1e2427 | ||
|
|
94581c908b | ||
|
|
98d7133844 | ||
|
|
3ae97fe0e5 | ||
|
|
51561d3393 | ||
|
|
be595765e4 | ||
|
|
7bb4980119 | ||
|
|
720c9ccbc8 | ||
|
|
9dc2951e07 | ||
|
|
7962409629 | ||
|
|
314e9b5d32 | ||
|
|
2c9e56a579 | ||
|
|
cee8330928 | ||
|
|
9172cb85ee | ||
|
|
ee0a308db6 | ||
|
|
32cbaa1049 | ||
|
|
5d58961187 | ||
|
|
6ee82f77f6 | ||
|
|
2e8654ba7f | ||
|
|
33afb79600 | ||
|
|
48c2f76109 | ||
|
|
00dd71abb2 | ||
|
|
763198bec1 | ||
|
|
7f63e51658 | ||
|
|
a963ea0296 | ||
|
|
b3467cf739 | ||
|
|
dd96b5aea7 | ||
|
|
9aabc7e605 | ||
|
|
2f9d425859 | ||
|
|
db94b5f923 | ||
|
|
70bf59ccbf | ||
|
|
cc7a35b300 | ||
|
|
8818f9135a | ||
|
|
fc451096c5 | ||
|
|
8e71d08b82 | ||
|
|
babab7f415 | ||
|
|
6939b8820e | ||
|
|
b879b6790f | ||
|
|
2c3a8273f7 | ||
|
|
f7ce58d71f | ||
|
|
42f0e95f0a | ||
|
|
dce9b86fb6 | ||
|
|
8dacb12362 | ||
|
|
cc9e3d6827 | ||
|
|
c22143d2cd | ||
|
|
cb7def739e | ||
|
|
01dfb0205f | ||
|
|
2f2205ebe7 | ||
|
|
64578562fc | ||
|
|
1ef69ac52e | ||
|
|
6e6d4428df | ||
|
|
9cf87b08b5 | ||
|
|
17fbb74695 | ||
|
|
cb7eda64d9 | ||
|
|
037b08dd0d |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -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/
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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
1
openpilot/cereal
Symbolic link
@@ -0,0 +1 @@
|
||||
../cereal/
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
|
Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 257 KiB |
0
selfdrive/clearpilot/resource/debug_ui_scene.png
Normal file → Executable file
0
selfdrive/clearpilot/resource/debug_ui_scene.png
Normal file → Executable file
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
@@ -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():
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
519
selfdrive/manager/manager_wip.txt
Normal file
519
selfdrive/manager/manager_wip.txt
Normal 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)
|
||||
@@ -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 = []
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
251
selfdrive/manager/process_wip.txt
Normal file
251
selfdrive/manager/process_wip.txt
Normal 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
|
||||
350
selfdrive/manager/process_wip2.txt
Normal file
350
selfdrive/manager/process_wip2.txt
Normal 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
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 "add new device" 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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 "add new device" and scan the QR code on the right</source>
|
||||
<translation>Klicke auf "neues Gerät hinzufügen" und scanne den QR code rechts</translation>
|
||||
<translation type="vanished">Klicke auf "neues Gerät hinzufügen" 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>
|
||||
|
||||
@@ -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'un trajet</translation>
|
||||
<translation type="vanished">En attente d'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 "add new device" and scan the QR code on the right</source>
|
||||
<translation>Cliquez sur "ajouter un nouvel appareil" et scannez le code QR à droite</translation>
|
||||
<translation type="vanished">Cliquez sur "ajouter un nouvel appareil" 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'accueil pour l'utiliser comme une application</translation>
|
||||
<translation type="vanished">Ajoutez connect.comma.ai à votre écran d'accueil pour l'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'à 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'à une minute.</translation>
|
||||
<name>SetupWidget</name>
|
||||
<message>
|
||||
<source>Finish Setup</source>
|
||||
<translation>Terminer l'installation</translation>
|
||||
<translation type="vanished">Terminer l'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'offre comma prime.</translation>
|
||||
<translation type="vanished">Associez votre appareil avec comma connect (connect.comma.ai) et profitez de l'offre comma prime.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pair device</source>
|
||||
<translation>Associer l'appareil</translation>
|
||||
<translation type="vanished">Associer l'appareil</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -1502,19 +1474,19 @@ Cela peut prendre jusqu'à une minute.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show ETA in 24h Format</source>
|
||||
<translation>Afficher l'heure d'arrivée en format 24h</translation>
|
||||
<translation type="vanished">Afficher l'heure d'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'interface</translation>
|
||||
<translation type="vanished">Afficher la carte à gauche de l'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'à 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'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'agit d'une fonctionnalité alpha ; il faut s'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'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'agit d'une fonctionnalité alpha ; il faut s'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>
|
||||
|
||||
@@ -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 "add new device" 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>
|
||||
|
||||
@@ -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 "add new device" 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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 "add new device" and scan the QR code on the right</source>
|
||||
<translation>Clique "add new device" e escaneie o QR code a seguir</translation>
|
||||
<translation type="vanished">Clique "add new device" 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 (só nos EUA)</translation>
|
||||
<translation type="vanished">Conectividade LTE (só 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>
|
||||
|
||||
@@ -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 "add new device" and scan the QR code on the right</source>
|
||||
<translation>กดที่ "add new device" และสแกนคิวอาร์โค้ดทางด้านขวา</translation>
|
||||
<translation type="vanished">กดที่ "add new device" และสแกนคิวอาร์โค้ดทางด้านขวา</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>
|
||||
|
||||
@@ -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 "add new device" 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>
|
||||
|
||||
@@ -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 "add new device" 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.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小时制代替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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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 "add new device" and scan the QR code on the right</source>
|
||||
<translation>點選 "add new device" 後掃描右邊的二維碼</translation>
|
||||
<translation type="vanished">點選 "add new device" 後掃描右邊的二維碼</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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
2
system/clearpilot/dev/on_start_brian.sh.cpt
Executable file
2
system/clearpilot/dev/on_start_brian.sh.cpt
Executable 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>
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user