mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-08-24 04:23:47 +08:00
Compare commits
366 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c046bc3ce | |||
| 35b78c3d0b | |||
| 5188f31531 | |||
| ae5fe50c0d | |||
| 883e282d0a | |||
| 0837757107 | |||
| 9e6a13a4e3 | |||
| beca4a184c | |||
| 2725a8bf1c | |||
| 35dc7d661e | |||
| 82d875e026 | |||
| 9693fb458d | |||
| b82d8bf175 | |||
| d7202e68a4 | |||
| 9c88e294ae | |||
| 7828ee9974 | |||
| e83da5f38b | |||
| 4f886b8998 | |||
| d418a1417c | |||
| 4b00b7ee59 | |||
| fae2950581 | |||
| fad2c3c1a8 | |||
| 64c6944ee9 | |||
| 9e752a67d7 | |||
| 2005875548 | |||
| c57146922f | |||
| c39b2dad94 | |||
| 3e4374b907 | |||
| 6fffb2c3f2 | |||
| d71127b2ed | |||
| 1dae8b2d16 | |||
| f54b10e3f2 | |||
| 38312b519d | |||
| d1f23ad7ea | |||
| ebc3e5b04c | |||
| 0c56c7d76d | |||
| fdf97f224f | |||
| 2806c9c38b | |||
| e6b769245c | |||
| 5c126396b9 | |||
| de912b917e | |||
| cd182c95db | |||
| 3d752d1f24 | |||
| a6001f2bc9 | |||
| 14a22c0736 | |||
| 450f0770b7 | |||
| 8109909e57 | |||
| 483b14c4e7 | |||
| e5bedd1c89 | |||
| 1dbd066824 | |||
| 6b5b686fa5 | |||
| 76bc538ac7 | |||
| 3f6a4606c5 | |||
| 53eb821dc4 | |||
| d8faa768e8 | |||
| ebe5378dd0 | |||
| f4530681a3 | |||
| f64a180973 | |||
| 82e1ebe97e | |||
| da3ff45bb6 | |||
| 41da513fca | |||
| b2950149fb | |||
| a829a1b972 | |||
| 4fb8e4beed | |||
| 298b36cec7 | |||
| 4824642838 | |||
| 872790782d | |||
| af4f0f8372 | |||
| 1fcb1bb00f | |||
| e8ff41b0e8 | |||
| 0521af3f5c | |||
| 1d5f0ab282 | |||
| 8e378ecaf8 | |||
| b0423fdb2a | |||
| e1ce48b79a | |||
| 1bce355885 | |||
| e9ce266638 | |||
| c72be372a1 | |||
| 5f6ec0ebcf | |||
| 848290d07e | |||
| 6694928a46 | |||
| b3c90ef7b2 | |||
| bf85781f16 | |||
| 924e5a3211 | |||
| e88efc82f4 | |||
| aa74e67330 | |||
| a4ee4ba76d | |||
| 45c853c87a | |||
| e8ab9d812d | |||
| 0db8722221 | |||
| 9bd86cb2ea | |||
| 94f3771fcc | |||
| e911de5968 | |||
| a33497ed19 | |||
| 91f2bf3459 | |||
| e74252bdf5 | |||
| c4f79b7043 | |||
| cea6e00819 | |||
| df8b02b4bf | |||
| 08e34dc293 | |||
| ffa78eabaa | |||
| 723023fcfb | |||
| 46222c3bb0 | |||
| 335821663f | |||
| 0d3bc959c8 | |||
| 4f3c19ffb5 | |||
| 4da32cc009 | |||
| ae5c44355d | |||
| 066438ad10 | |||
| 9532675814 | |||
| e74460f3a8 | |||
| c347db376a | |||
| c9bd67b261 | |||
| 5e8cf86284 | |||
| 4820265268 | |||
| 01aa6c4204 | |||
| 545f323000 | |||
| f0b255aad0 | |||
| a31cb3f543 | |||
| 929b417f19 | |||
| 905304cbcc | |||
| 21beea51ec | |||
| d7b8ce86ed | |||
| 2d3d104658 | |||
| ded02895f4 | |||
| 9778a925b0 | |||
| 423a7d2ed0 | |||
| e4e10d4b87 | |||
| 362e9ce04b | |||
| 3946e643f6 | |||
| 0c37a38596 | |||
| 9c5acf61c0 | |||
| 121b304fe0 | |||
| 47d848293b | |||
| 8b94f8b2f8 | |||
| dec014cd17 | |||
| 7b40272866 | |||
| 506456e7f0 | |||
| 4ea4b9d177 | |||
| 0e2313dc31 | |||
| 79ea7db103 | |||
| f9ae9192fa | |||
| 7ec23006c6 | |||
| 2be9447a6c | |||
| cfd926778e | |||
| a97a67e3d0 | |||
| 518b6de08d | |||
| 6933e3bcdb | |||
| 05e0ca8bee | |||
| 410614fcf3 | |||
| e2bc0996ef | |||
| 1be0c20cf5 | |||
| 839143b9ed | |||
| bce86637ae | |||
| b833d3ee89 | |||
| e0441dfb4b | |||
| 62ec40bba6 | |||
| 15c6d38028 | |||
| 56eb9f555c | |||
| 2f9951df02 | |||
| 6030bf4da3 | |||
| 074694d660 | |||
| df35f48f3b | |||
| 4fb9704540 | |||
| 48cbe266fc | |||
| 21aa7ff367 | |||
| 7caf05dd51 | |||
| 2d779f5db9 | |||
| 18208f1da0 | |||
| 5a3c6ddf57 | |||
| eaa8732ab0 | |||
| 6f0284c84f | |||
| 999ea03f23 | |||
| 0975db3ff1 | |||
| 8d70a8b80a | |||
| da93f92887 | |||
| 9117f6c071 | |||
| 3567ff9691 | |||
| f44ae2ced9 | |||
| 376e0ca615 | |||
| 32b7686468 | |||
| b9e0f52ea9 | |||
| a3163b680f | |||
| 8a927d808f | |||
| bc7d5e474d | |||
| 36f192b5fe | |||
| ffd5cd4ac2 | |||
| e4a00fcd6c | |||
| 0bdcb41103 | |||
| 78051085ca | |||
| 4910d5809a | |||
| 8dd862ff28 | |||
| 1b57497da9 | |||
| 8d8d1ffc7a | |||
| c5919d5495 | |||
| da71951c95 | |||
| 25a152cd8b | |||
| 9077a1082a | |||
| 7ae7000254 | |||
| 7029455706 | |||
| 3a71a62215 | |||
| 00622e8c33 | |||
| 549da3ee92 | |||
| e038a65ef8 | |||
| 8d0513c657 | |||
| 2cea48f4cd | |||
| 8855a9ab65 | |||
| 32321c01cc | |||
| 52cd65fefb | |||
| 1fcdeccd40 | |||
| 3517c36978 | |||
| fb30c3c1e8 | |||
| 1c25e568d5 | |||
| f172122b7c | |||
| 67d6cdc7cd | |||
| 6724085cfd | |||
| 6774f34eee | |||
| 6d0402896d | |||
| 344021a3d9 | |||
| a9b85ab27d | |||
| 17204a46e4 | |||
| 7c4d415462 | |||
| b8985b6d72 | |||
| c669473f88 | |||
| 8751435bf5 | |||
| 30ae210761 | |||
| 3eb693f58b | |||
| 7b4a31c5ac | |||
| 1527c8cf88 | |||
| ab0a7ae666 | |||
| 11ec2f1f21 | |||
| 2c6808d37e | |||
| 2e96382c49 | |||
| 0239e440ca | |||
| 76b972daff | |||
| bc3ef3e7dd | |||
| 9839291dd0 | |||
| 17cba328d6 | |||
| 86093765d8 | |||
| 05fa1c8ae8 | |||
| e8a40d6b85 | |||
| c265e0bb85 | |||
| c6b118788b | |||
| b004f6dbdc | |||
| cd4930b680 | |||
| f861aca628 | |||
| 1ff0d8e2ee | |||
| d76d70764e | |||
| dc73ce0b71 | |||
| 3f666748af | |||
| 8de8a8838c | |||
| f563b7eb71 | |||
| 3c18b83708 | |||
| bd35f5904b | |||
| 474f2737f6 | |||
| ea1ac4a212 | |||
| 165d7c7b36 | |||
| b53cbb2e18 | |||
| b95f8c5929 | |||
| e564bb0b85 | |||
| e2ec8a7b13 | |||
| 75c6f0f10e | |||
| af38044b42 | |||
| 684fa846d8 | |||
| 416e722855 | |||
| 9fd4613bbb | |||
| a0362e3c5f | |||
| e32ef1cdc0 | |||
| 20673ec8a6 | |||
| 53fbdf7329 | |||
| 6f72b74fac | |||
| e83705a32e | |||
| 95d36b9ba2 | |||
| b9e74254bd | |||
| b4405b200d | |||
| a8a3fdac54 | |||
| 4eddc622a7 | |||
| 4e42ada240 | |||
| 6266217655 | |||
| ea09d32e98 | |||
| 15958c88d3 | |||
| b80d7fb5ea | |||
| 1c3d25c6ff | |||
| c9f22b32c7 | |||
| c0524985bb | |||
| 83839c7ea7 | |||
| c1a1d4b4c3 | |||
| b5af7a905a | |||
| 96b1b2f55f | |||
| 9361ba5d70 | |||
| 4e9014311e | |||
| 232873fc70 | |||
| 0a61fca9c9 | |||
| 480bdc34dc | |||
| 716b475a13 | |||
| b1ec5ec034 | |||
| 470613c2b7 | |||
| 336c5b4154 | |||
| abdb9dc750 | |||
| ab98683973 | |||
| 186c24dbe6 | |||
| 9cdf6340a1 | |||
| 2855b1341c | |||
| cf28f99976 | |||
| a39d67dc47 | |||
| 7e75257f12 | |||
| df38449553 | |||
| 1385ef3bc5 | |||
| 7c23c11c51 | |||
| aeff2e12ec | |||
| 7274899671 | |||
| 6c00fd608f | |||
| df6a034c11 | |||
| acb109c290 | |||
| b227b00249 | |||
| 3ec9d6c18a | |||
| 86db8b95f0 | |||
| 4cfff8a35f | |||
| 962fedf48c | |||
| 04494414d1 | |||
| 0b83576e9b | |||
| ce4ef0f817 | |||
| f0b15c1c56 | |||
| f898e9fdfe | |||
| 8ee7804b0e | |||
| 923228194e | |||
| 8837b2e3f6 | |||
| f48c9dc1c2 | |||
| 74aa07a8cd | |||
| 5236e4860f | |||
| 3d174da1c3 | |||
| 8faa40f3a3 | |||
| 3e03275f28 | |||
| 7595cf8a25 | |||
| 2675d43adb | |||
| d9f4ce82e6 | |||
| 648a1845d8 | |||
| a87eff6d1c | |||
| dd6ad37e23 | |||
| c5e778b939 | |||
| a9ab81a77a | |||
| 2d40e1d8e5 | |||
| 7c8f367a5d | |||
| ff4cf558aa | |||
| 0e151e51bc | |||
| 60cc0031b0 | |||
| d24cac0998 | |||
| 45d110830c | |||
| ea3a9ae911 | |||
| 6bff8c0e7c | |||
| bc6b8802b8 | |||
| 252ef572d3 | |||
| 414d397e3f | |||
| 11b7b3789d | |||
| 871ac53717 | |||
| 64ea66b6e6 | |||
| 6d7c6759b3 | |||
| 4cea013570 | |||
| eb375c0587 | |||
| 7fd8a5a4bd | |||
| b3c90216bb | |||
| 10f345f956 | |||
| 956d2c36d0 | |||
| 55e688b6f2 | |||
| f017954027 | |||
| 7e992d11b1 |
@@ -2,5 +2,6 @@ Wen
|
|||||||
REGIST
|
REGIST
|
||||||
PullRequest
|
PullRequest
|
||||||
cancelled
|
cancelled
|
||||||
|
indeces
|
||||||
FOF
|
FOF
|
||||||
NoO
|
NoO
|
||||||
|
|||||||
Generated
+7
@@ -21,5 +21,12 @@
|
|||||||
</clean>
|
</clean>
|
||||||
</configuration>
|
</configuration>
|
||||||
</target>
|
</target>
|
||||||
|
<target id="f2590b2b-9b93-49f9-8510-da3f3724a2ae" name="replay" defaultType="TOOL">
|
||||||
|
<configuration id="d475264f-6f4c-4092-9b4e-6773309f38b7" name="replay" toolchainName="Default">
|
||||||
|
<build type="TOOL">
|
||||||
|
<tool actionId="Tool_External Tools_uv build tools replay" />
|
||||||
|
</build>
|
||||||
|
</configuration>
|
||||||
|
</target>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
Generated
+7
@@ -20,4 +20,11 @@
|
|||||||
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$" />
|
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$" />
|
||||||
</exec>
|
</exec>
|
||||||
</tool>
|
</tool>
|
||||||
|
<tool name="uv build tools replay" showInMainMenu="false" showInEditor="false" showInProject="false" showInSearchPopup="false" disabled="false" useConsole="true" showConsoleOnStdOut="false" showConsoleOnStdErr="false" synchronizeAfterRun="true">
|
||||||
|
<exec>
|
||||||
|
<option name="COMMAND" value="bash" />
|
||||||
|
<option name="PARAMETERS" value="-c "source .venv/bin/activate && scons -u -j$(nproc) tools/replay/"" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$ProjectFileDir$" />
|
||||||
|
</exec>
|
||||||
|
</tool>
|
||||||
</toolSet>
|
</toolSet>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Build Debug" type="CLionExternalRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" WORKING_DIR="file://$ProjectFileDir$/selfdrive/ui" PASS_PARENT_ENVS_2="true" PROJECT_NAME="sunnypilot" TARGET_NAME="uv Scons Build Debug" CONFIG_NAME="uv Scons Build Debug" RUN_PATH="ui">
|
<configuration default="false" name="Build Debug" type="CLionExternalRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" WORKING_DIR="file://$ProjectFileDir$/selfdrive/ui" PASS_PARENT_ENVS_2="true" PROJECT_NAME="openpilot-special" TARGET_NAME="uv Scons Build Debug" CONFIG_NAME="uv Scons Build Debug" RUN_PATH="ui">
|
||||||
<envs>
|
<envs>
|
||||||
<env name="QT_DBL_CLICK_DIST" value="150" />
|
<env name="QT_DBL_CLICK_DIST" value="150" />
|
||||||
</envs>
|
</envs>
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Debug Route Controls" type="PythonConfigurationType" factoryName="Python">
|
||||||
|
<module name="openpilot-special" />
|
||||||
|
<option name="ENV_FILES" value="" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
<env name="FINGERPRINT" value="KIA_EV9" />
|
||||||
|
<env name="SKIP_FW_QUERY" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/selfdrive/car" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/selfdrive/car/card.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="true" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Replay for controls + ui" type="Multirun" separateTabs="false" reuseTabsWithFailures="false" startOneByOne="true" markFailedProcess="true" hideSuccessProcess="false" delayTime="0.0">
|
||||||
|
<runConfiguration name="replay for controls" type="Native Application" />
|
||||||
|
<runConfiguration name="Build Debug" type="Custom Build Application" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="replay for controls" type="CLionNativeAppRunConfigurationType" focusToolWindowBeforeRun="true" PROGRAM_PARAMS=""$Prompt$" --block "sendcan,carState,carParams,carOutput,liveTracks,carParamsSP,carStateSP,bookmarkButton"" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="true" WORKING_DIR="file://$ProjectFileDir$/tools/replay" PASS_PARENT_ENVS_2="true" PROJECT_NAME="openpilot-special" TARGET_NAME="replay" CONFIG_NAME="replay" version="1" RUN_PATH="replay">
|
||||||
|
<method v="2">
|
||||||
|
<option name="CLION.COMPOUND.BUILD" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -262,4 +262,11 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
|||||||
{"TorqueParamsOverrideEnabled", {PERSISTENT | BACKUP, BOOL, "0"}},
|
{"TorqueParamsOverrideEnabled", {PERSISTENT | BACKUP, BOOL, "0"}},
|
||||||
{"TorqueParamsOverrideFriction", {PERSISTENT | BACKUP, FLOAT, "0.1"}},
|
{"TorqueParamsOverrideFriction", {PERSISTENT | BACKUP, FLOAT, "0.1"}},
|
||||||
{"TorqueParamsOverrideLatAccelFactor", {PERSISTENT | BACKUP, FLOAT, "2.5"}},
|
{"TorqueParamsOverrideLatAccelFactor", {PERSISTENT | BACKUP, FLOAT, "2.5"}},
|
||||||
|
|
||||||
|
// Tuning keys
|
||||||
|
{"EnableHkgTuningAngleSmoothingFactor", {PERSISTENT | BACKUP, BOOL, "1"}},
|
||||||
|
{"HkgTuningAngleMinTorqueReductionGain", {PERSISTENT | BACKUP, INT, "10"}},
|
||||||
|
{"HkgTuningAngleMaxTorqueReductionGain", {PERSISTENT | BACKUP, INT, "100"}},
|
||||||
|
{"HkgTuningAngleActiveTorqueReductionGain", {PERSISTENT | BACKUP, INT, "100"}},
|
||||||
|
{"HkgTuningOverridingCycles", {PERSISTENT | BACKUP, INT, "17"}},
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
Submodule opendbc_repo updated: 61bf5a90c5...11a657be24
@@ -13,7 +13,7 @@ cd $ROOT
|
|||||||
|
|
||||||
FAILED=0
|
FAILED=0
|
||||||
|
|
||||||
IGNORED_FILES="uv\.lock|docs\/CARS.md|LICENSE\.md"
|
IGNORED_FILES="uv\.lock|docs\/CARS.md|LICENSE\.md|layouts\/.*\.xml|.*\.ipynb"
|
||||||
IGNORED_DIRS="^third_party.*|^msgq.*|^msgq_repo.*|^opendbc.*|^opendbc_repo.*|^cereal.*|^panda.*|^rednose.*|^rednose_repo.*|^tinygrad.*|^tinygrad_repo.*|^teleoprtc.*|^teleoprtc_repo.*"
|
IGNORED_DIRS="^third_party.*|^msgq.*|^msgq_repo.*|^opendbc.*|^opendbc_repo.*|^cereal.*|^panda.*|^rednose.*|^rednose_repo.*|^tinygrad.*|^tinygrad_repo.*|^teleoprtc.*|^teleoprtc_repo.*"
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from openpilot.selfdrive.ui.layouts.settings import settings as OP
|
|||||||
from openpilot.selfdrive.ui.layouts.settings.developer import DeveloperLayout
|
from openpilot.selfdrive.ui.layouts.settings.developer import DeveloperLayout
|
||||||
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.device import DeviceLayoutSP
|
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.device import DeviceLayoutSP
|
||||||
from openpilot.selfdrive.ui.layouts.settings.firehose import FirehoseLayout
|
from openpilot.selfdrive.ui.layouts.settings.firehose import FirehoseLayout
|
||||||
from openpilot.selfdrive.ui.layouts.settings.software import SoftwareLayout
|
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.software import SoftwareLayoutSP
|
||||||
from openpilot.selfdrive.ui.layouts.settings.toggles import TogglesLayout
|
from openpilot.selfdrive.ui.layouts.settings.toggles import TogglesLayout
|
||||||
from openpilot.system.ui.lib.application import gui_app, MousePos
|
from openpilot.system.ui.lib.application import gui_app, MousePos
|
||||||
from openpilot.system.ui.lib.multilang import tr_noop
|
from openpilot.system.ui.lib.multilang import tr_noop
|
||||||
@@ -114,7 +114,7 @@ class SettingsLayoutSP(OP.SettingsLayout):
|
|||||||
OP.PanelType.NETWORK: PanelInfo(tr_noop("Network"), NetworkUISP(wifi_manager), icon="icons/network.png"),
|
OP.PanelType.NETWORK: PanelInfo(tr_noop("Network"), NetworkUISP(wifi_manager), icon="icons/network.png"),
|
||||||
OP.PanelType.SUNNYLINK: PanelInfo(tr_noop("sunnylink"), SunnylinkLayout(), icon="icons/wifi_strength_full.png"),
|
OP.PanelType.SUNNYLINK: PanelInfo(tr_noop("sunnylink"), SunnylinkLayout(), icon="icons/wifi_strength_full.png"),
|
||||||
OP.PanelType.TOGGLES: PanelInfo(tr_noop("Toggles"), TogglesLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_toggle.png"),
|
OP.PanelType.TOGGLES: PanelInfo(tr_noop("Toggles"), TogglesLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_toggle.png"),
|
||||||
OP.PanelType.SOFTWARE: PanelInfo(tr_noop("Software"), SoftwareLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_software.png"),
|
OP.PanelType.SOFTWARE: PanelInfo(tr_noop("Software"), SoftwareLayoutSP(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_software.png"),
|
||||||
OP.PanelType.MODELS: PanelInfo(tr_noop("Models"), ModelsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_models.png"),
|
OP.PanelType.MODELS: PanelInfo(tr_noop("Models"), ModelsLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_models.png"),
|
||||||
OP.PanelType.STEERING: PanelInfo(tr_noop("Steering"), SteeringLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_lateral.png"),
|
OP.PanelType.STEERING: PanelInfo(tr_noop("Steering"), SteeringLayout(), icon="../../sunnypilot/selfdrive/assets/offroad/icon_lateral.png"),
|
||||||
OP.PanelType.CRUISE: PanelInfo(tr_noop("Cruise"), CruiseLayout(), icon="icons/speed_limit.png"),
|
OP.PanelType.CRUISE: PanelInfo(tr_noop("Cruise"), CruiseLayout(), icon="icons/speed_limit.png"),
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
"""
|
||||||
|
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||||
|
|
||||||
|
This file is part of sunnypilot and is licensed under the MIT License.
|
||||||
|
See the LICENSE.md file in the root directory for more details.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
|
||||||
|
from openpilot.selfdrive.ui.layouts.settings.software import SoftwareLayout
|
||||||
|
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||||
|
from openpilot.system.hardware import HARDWARE
|
||||||
|
from openpilot.system.ui.lib.application import gui_app
|
||||||
|
from openpilot.system.ui.lib.multilang import tr, tr_noop
|
||||||
|
from openpilot.system.ui.widgets import DialogResult
|
||||||
|
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
|
||||||
|
|
||||||
|
from openpilot.system.ui.sunnypilot.widgets.list_view import toggle_item_sp
|
||||||
|
from openpilot.system.ui.sunnypilot.widgets.tree_dialog import TreeOptionDialog, TreeNode, TreeFolder
|
||||||
|
|
||||||
|
|
||||||
|
DESCRIPTIONS = {
|
||||||
|
'disable_updates_offroad': tr_noop(
|
||||||
|
"When enabled, automatic software updates will be off.<br><b>This requires a reboot to take effect.</b>"
|
||||||
|
),
|
||||||
|
'disable_updates_onroad': tr_noop(
|
||||||
|
"Please enable \"Always Offroad\" mode or turn off the vehicle to adjust these toggles."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SoftwareLayoutSP(SoftwareLayout):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.disable_updates_toggle = toggle_item_sp(
|
||||||
|
lambda: tr("Disable Updates"),
|
||||||
|
description="",
|
||||||
|
initial_state=ui_state.params.get_bool("DisableUpdates"),
|
||||||
|
callback=self._on_disable_updates_toggled,
|
||||||
|
)
|
||||||
|
self._scroller.add_widget(self.disable_updates_toggle)
|
||||||
|
|
||||||
|
def _handle_reboot(self, result):
|
||||||
|
if result == DialogResult.CONFIRM:
|
||||||
|
ui_state.params.put_bool("DisableUpdates", self.disable_updates_toggle.action_item.get_state())
|
||||||
|
ui_state.params.put_bool("DoReboot", True)
|
||||||
|
else:
|
||||||
|
self.disable_updates_toggle.action_item.set_state(ui_state.params.get_bool("DisableUpdates"))
|
||||||
|
|
||||||
|
def _on_disable_updates_toggled(self, enabled):
|
||||||
|
dialog = ConfirmDialog(tr("System reboot required for changes to take effect. Reboot now?"), tr("Reboot"))
|
||||||
|
gui_app.set_modal_overlay(dialog, callback=self._handle_reboot)
|
||||||
|
|
||||||
|
def _on_select_branch(self):
|
||||||
|
current_git_branch = ui_state.params.get("GitBranch") or ""
|
||||||
|
branches_str = ui_state.params.get("UpdaterAvailableBranches") or ""
|
||||||
|
branches = [b for b in branches_str.split(",") if b]
|
||||||
|
current_target = ui_state.params.get("UpdaterTargetBranch") or ""
|
||||||
|
top_level_branches = [current_git_branch, "release-mici", "release-tizi", "staging", "dev", "master"]
|
||||||
|
|
||||||
|
if HARDWARE.get_device_type() == "tici":
|
||||||
|
top_level_branches = ["release-tici", "staging-tici"]
|
||||||
|
branches = [b for b in branches if b.endswith("-tici")]
|
||||||
|
|
||||||
|
top_level_nodes = [TreeNode(b, {'display_name': b}) for b in top_level_branches if b in branches]
|
||||||
|
remaining_branches = [b for b in branches if b not in top_level_branches]
|
||||||
|
prebuilt_nodes = [TreeNode(b, {'display_name': b}) for b in remaining_branches if b.endswith("-prebuilt")]
|
||||||
|
non_prebuilt_nodes = [TreeNode(b, {'display_name': b}) for b in remaining_branches if not b.endswith("-prebuilt")]
|
||||||
|
|
||||||
|
folders = [
|
||||||
|
TreeFolder("", top_level_nodes),
|
||||||
|
TreeFolder("Prebuilt Branches", prebuilt_nodes),
|
||||||
|
TreeFolder("Non-Prebuilt Branches", non_prebuilt_nodes),
|
||||||
|
]
|
||||||
|
|
||||||
|
def _on_branch_selected(result):
|
||||||
|
if result == DialogResult.CONFIRM and self._branch_dialog is not None:
|
||||||
|
selection = self._branch_dialog.selection_ref
|
||||||
|
if selection:
|
||||||
|
ui_state.params.put("UpdaterTargetBranch", selection)
|
||||||
|
self._branch_btn.action_item.set_value(selection)
|
||||||
|
os.system("pkill -SIGUSR1 -f system.updated.updated")
|
||||||
|
self._branch_dialog = None
|
||||||
|
|
||||||
|
self._branch_dialog = TreeOptionDialog(tr("Select a branch"), folders, current_target, "",
|
||||||
|
on_exit=_on_branch_selected)
|
||||||
|
|
||||||
|
gui_app.set_modal_overlay(self._branch_dialog, callback=_on_branch_selected)
|
||||||
|
|
||||||
|
def _update_state(self):
|
||||||
|
super()._update_state()
|
||||||
|
show_advanced = ui_state.params.get_bool("ShowAdvancedControls")
|
||||||
|
self.disable_updates_toggle.action_item.set_enabled(ui_state.is_offroad())
|
||||||
|
self.disable_updates_toggle.set_visible(show_advanced)
|
||||||
|
|
||||||
|
disable_updates_desc = tr(DESCRIPTIONS["disable_updates_offroad"] if ui_state.is_offroad() else DESCRIPTIONS["disable_updates_onroad"])
|
||||||
|
self.disable_updates_toggle.set_description(disable_updates_desc)
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||||
|
*
|
||||||
|
* This file is part of sunnypilot and is licensed under the MIT License.
|
||||||
|
* See the LICENSE.md file in the root directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/lateral/angle_tuning_settings.h"
|
||||||
|
|
||||||
|
#include "selfdrive/ui/sunnypilot/qt/widgets/scrollview.h"
|
||||||
|
|
||||||
|
AngleTunningSettings::AngleTunningSettings(QWidget *parent) : QWidget(parent) {
|
||||||
|
QVBoxLayout *main_layout = new QVBoxLayout(this);
|
||||||
|
main_layout->setContentsMargins(50, 20, 50, 20);
|
||||||
|
main_layout->setSpacing(20);
|
||||||
|
|
||||||
|
// Back button
|
||||||
|
PanelBackButton *back = new PanelBackButton();
|
||||||
|
connect(back, &QPushButton::clicked, [=]() { emit backPress(); });
|
||||||
|
main_layout->addWidget(back, 0, Qt::AlignLeft);
|
||||||
|
|
||||||
|
auto *list = new ListWidgetSP(this, false);
|
||||||
|
|
||||||
|
main_layout->addWidget(new QWidget());
|
||||||
|
|
||||||
|
enableHkgAngleSmoothingFactor = new ExpandableToggleRow("EnableHkgTuningAngleSmoothingFactor", tr("HKG Angle Smoothing Factor"), tr("Applies EMA (Exponential Moving Average) to the desired angle steering and avoid overcorrections."), "../assets/offroad/icon_blank.png");
|
||||||
|
list->addItem(enableHkgAngleSmoothingFactor);
|
||||||
|
|
||||||
|
auto first_row = new QHBoxLayout();
|
||||||
|
hkgTuningOverridingCycles = new OptionControlSP("HkgTuningOverridingCycles", tr("Override Ramp-Down Cycles"), tr("Number of cycles to ramp down the current amount of torque on the steering wheel.<br/>A smaller value means a faster override by the user (less effort)"), "../assets/offroad/icon_blank.png", {10, 30}, 1);
|
||||||
|
connect(hkgTuningOverridingCycles, &OptionControlSP::updateLabels, hkgTuningOverridingCycles, [=]() {
|
||||||
|
this->updateToggles(offroad);
|
||||||
|
});
|
||||||
|
first_row->addWidget(hkgTuningOverridingCycles);
|
||||||
|
|
||||||
|
hkgAngleMinTorque = new OptionControlSP("HkgTuningAngleMinTorqueReductionGain", tr("Override Steering Effort"), tr("Sets the steering effort percentage used when the driver is overriding lateral control.<br/>Higher values increase resistance and make the wheel feel stiffer."), "../assets/offroad/icon_blank.png", {5, 60}, 1);
|
||||||
|
connect(hkgAngleMinTorque, &OptionControlSP::updateLabels, hkgAngleMinTorque, [=]() {
|
||||||
|
this->updateToggles(offroad);
|
||||||
|
});
|
||||||
|
first_row->addWidget(hkgAngleMinTorque);
|
||||||
|
list->addItem(first_row);
|
||||||
|
|
||||||
|
auto second_row = new QHBoxLayout();
|
||||||
|
hkgAngleActiveTorque = new OptionControlSP("HkgTuningAngleActiveTorqueReductionGain", tr("Min Active Torque"), tr("Torque applied when lateral control is active but the vehicle is not turning.<br/>Used to maintain lane centering on straight paths when no user input is detected."), "../assets/offroad/icon_blank.png", {10, 100}, 1);
|
||||||
|
connect(hkgAngleActiveTorque, &OptionControlSP::updateLabels, hkgAngleActiveTorque, [=]() {
|
||||||
|
this->updateToggles(offroad);
|
||||||
|
});
|
||||||
|
second_row->addWidget(hkgAngleActiveTorque);
|
||||||
|
|
||||||
|
hkgAngleMaxTorque = new OptionControlSP("HkgTuningAngleMaxTorqueReductionGain", tr("Max Torque Allowance"), tr("Sets the maximum torque reduction percentage the controller can apply during normal lateral control.<br/>"), "../assets/offroad/icon_blank.png", {10, 100}, 1);
|
||||||
|
connect(hkgAngleMaxTorque, &OptionControlSP::updateLabels, hkgAngleMaxTorque, [=]() {
|
||||||
|
this->updateToggles(offroad);
|
||||||
|
});
|
||||||
|
second_row->addWidget(hkgAngleMaxTorque);
|
||||||
|
list->addItem(second_row);
|
||||||
|
|
||||||
|
QObject::connect(uiState(), &UIState::offroadTransition, this, &AngleTunningSettings::updateToggles);
|
||||||
|
|
||||||
|
main_layout->addWidget(new ScrollViewSP(list, this));
|
||||||
|
|
||||||
|
auto *warning = new QLabel(tr("Reboot required for settings to apply; Tap on each setting to see more details."));
|
||||||
|
warning->setStyleSheet("font-size: 30px; font-weight: 500; font-family: 'Noto Color Emoji'; color: orange;");
|
||||||
|
main_layout->addWidget(warning, 0, Qt::AlignCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AngleTunningSettings::showEvent(QShowEvent *event) {
|
||||||
|
updateToggles(offroad);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AngleTunningSettings::updateToggles(bool _offroad) {
|
||||||
|
auto HkgAngleSmoothingFactorValue = params.getBool("EnableHkgTuningAngleSmoothingFactor");
|
||||||
|
enableHkgAngleSmoothingFactor->toggleFlipped(HkgAngleSmoothingFactorValue);
|
||||||
|
|
||||||
|
auto HkgAngleMinTorqueValue = QString::fromStdString(params.get("HkgTuningAngleMinTorqueReductionGain")).toInt();
|
||||||
|
hkgAngleMinTorque->setLabel(QString::number(HkgAngleMinTorqueValue)+"%");
|
||||||
|
|
||||||
|
auto HkgAngleActiveTorqueValue = QString::fromStdString(params.get("HkgTuningAngleActiveTorqueReductionGain")).toInt();
|
||||||
|
hkgAngleActiveTorque->setLabel(QString::number(HkgAngleActiveTorqueValue)+"%");
|
||||||
|
|
||||||
|
auto HkgAngleMaxTorqueValue = QString::fromStdString(params.get("HkgTuningAngleMaxTorqueReductionGain")).toInt();
|
||||||
|
hkgAngleMaxTorque->setLabel(QString::number(HkgAngleMaxTorqueValue)+"%");
|
||||||
|
|
||||||
|
auto HkgTuningOverridingCyclesValue = QString::fromStdString(params.get("HkgTuningOverridingCycles")).toInt();
|
||||||
|
hkgTuningOverridingCycles->setLabel(QString::number(HkgTuningOverridingCyclesValue));
|
||||||
|
|
||||||
|
offroad = _offroad;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||||
|
*
|
||||||
|
* This file is part of sunnypilot and is licensed under the MIT License.
|
||||||
|
* See the LICENSE.md file in the root directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "selfdrive/ui/qt/util.h"
|
||||||
|
#include "selfdrive/ui/sunnypilot/ui.h"
|
||||||
|
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h"
|
||||||
|
#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h"
|
||||||
|
#include "selfdrive/ui/sunnypilot/qt/widgets/expandable_row.h"
|
||||||
|
|
||||||
|
class AngleTunningSettings : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AngleTunningSettings(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void showEvent(QShowEvent *event) override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void backPress();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateToggles(bool _offroad);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Params params;
|
||||||
|
bool offroad;
|
||||||
|
|
||||||
|
ExpandableToggleRow* enableHkgAngleSmoothingFactor;
|
||||||
|
OptionControlSP* hkgAngleMinTorque;
|
||||||
|
OptionControlSP* hkgAngleActiveTorque;
|
||||||
|
OptionControlSP* hkgAngleMaxTorque;
|
||||||
|
OptionControlSP* hkgTuningOverridingCycles;
|
||||||
|
};
|
||||||
@@ -101,18 +101,22 @@ class TreeOptionDialog(MultiOptionDialog):
|
|||||||
self.search_dialog = None
|
self.search_dialog = None
|
||||||
self._search_pressed = False
|
self._search_pressed = False
|
||||||
|
|
||||||
if current_ref:
|
self.selection_node = None
|
||||||
found = False
|
# Try to match by ref, by display text, or fall back to "Default" when no ref is set
|
||||||
for folder in folders:
|
for folder in self.folders:
|
||||||
for node in folder.nodes:
|
for node in folder.nodes:
|
||||||
if node.ref == current_ref:
|
display = self.display_func(node)
|
||||||
display = self.display_func(node)
|
if (
|
||||||
self.selection = display
|
node.ref == current_ref or
|
||||||
self.current = display
|
display == current_ref or
|
||||||
found = True
|
(not current_ref and node.ref == "Default")
|
||||||
break
|
):
|
||||||
if found:
|
self.selection = display
|
||||||
|
self.current = display
|
||||||
|
self.selection_node = node
|
||||||
break
|
break
|
||||||
|
if self.selection_node is not None:
|
||||||
|
break
|
||||||
|
|
||||||
self._build_visible_items()
|
self._build_visible_items()
|
||||||
|
|
||||||
@@ -155,6 +159,17 @@ class TreeOptionDialog(MultiOptionDialog):
|
|||||||
|
|
||||||
def _build_visible_items(self, reset_scroll=True):
|
def _build_visible_items(self, reset_scroll=True):
|
||||||
self.visible_items = []
|
self.visible_items = []
|
||||||
|
|
||||||
|
# Pinned selected item at the very top (if any)
|
||||||
|
if getattr(self, "selection_node", None) is not None:
|
||||||
|
node = self.selection_node
|
||||||
|
display = self.display_func(node)
|
||||||
|
self.selection = self.current = display
|
||||||
|
favorite_cb = (lambda node_ref=node: self._toggle_favorite(node_ref)) if self.fav_param and node.ref != "Default" else None
|
||||||
|
self.visible_items.append(TreeItemWidget(self.display_func(node), node.ref, False, 0,
|
||||||
|
lambda node_ref=node: self._select_node(node_ref),
|
||||||
|
favorite_cb, node.ref in self.favorites, is_expanded=True))
|
||||||
|
|
||||||
for folder in self.folders:
|
for folder in self.folders:
|
||||||
nodes = [node for node in folder.nodes if not self.query or search_from_list(self.query, [search_func(node) for search_func in self.search_funcs])]
|
nodes = [node for node in folder.nodes if not self.query or search_from_list(self.query, [search_func(node) for search_func in self.search_funcs])]
|
||||||
if not nodes and self.query:
|
if not nodes and self.query:
|
||||||
@@ -165,6 +180,10 @@ class TreeOptionDialog(MultiOptionDialog):
|
|||||||
lambda folder_ref=folder: self._toggle_folder(folder_ref)))
|
lambda folder_ref=folder: self._toggle_folder(folder_ref)))
|
||||||
if expanded:
|
if expanded:
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
|
# Skip duplicate root-level item for the selected node
|
||||||
|
if self.selection_node is not None and node.ref == self.selection_node.ref and not folder.folder:
|
||||||
|
continue
|
||||||
|
|
||||||
favorite_cb = (lambda node_ref=node: self._toggle_favorite(node_ref)) if self.fav_param and node.ref != "Default" else None
|
favorite_cb = (lambda node_ref=node: self._toggle_favorite(node_ref)) if self.fav_param and node.ref != "Default" else None
|
||||||
self.visible_items.append(TreeItemWidget(self.display_func(node), node.ref, False, 1 if folder.folder else 0,
|
self.visible_items.append(TreeItemWidget(self.display_func(node), node.ref, False, 1 if folder.folder else 0,
|
||||||
lambda node_ref=node: self._select_node(node_ref),
|
lambda node_ref=node: self._select_node(node_ref),
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ SP_BRANCH_MIGRATIONS = {
|
|||||||
("tizi", "staging-c3-new"): "staging",
|
("tizi", "staging-c3-new"): "staging",
|
||||||
("tizi", "dev-c3-new"): "dev",
|
("tizi", "dev-c3-new"): "dev",
|
||||||
("tizi", "master-dev-c3-new"): "master-dev",
|
("tizi", "master-dev-c3-new"): "master-dev",
|
||||||
|
("tici", "hkg-angle-steering-2025"): "hkg-angle-steering-2025-tici",
|
||||||
|
("tici", "hkg-angle-steering-2025-prebuilt"): "hkg-angle-steering-2025-tici-prebuilt"
|
||||||
}
|
}
|
||||||
|
|
||||||
BUILD_METADATA_FILENAME = "build.json"
|
BUILD_METADATA_FILENAME = "build.json"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,183 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<root>
|
||||||
|
<tabbed_widget parent="main_window" name="Main Window">
|
||||||
|
<Tab containers="1" tab_name="actuator data">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter orientation="-" sizes="0.25;0.25;0.25;0.25" count="4">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-0.100000" left="301.990881" top="0.100000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carControl/actuators/torque" color="#17becf"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-130.920132" left="301.990881" top="103.993176" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carControl/actuators/steeringAngleDeg" color="#1f77b4"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-0.604818" left="301.990881" top="24.797527" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carState/vEgoRaw" color="#ff7f0e"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-0.037812" left="301.990881" top="0.047261" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carControl/actuators/curvature" color="#f14cc1"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<Tab containers="1" tab_name="steering messages (CAN)">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter orientation="-" sizes="0.142857;0.142857;0.142857;0.142857;0.142857;0.142857;0.142857" count="7">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-0.025000" left="301.990881" top="1.025000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/can/128/LKAS_ALT/ADAS_ACIAnglTqRedcGainVal" color="#1f77b4"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-128.740000" left="301.990881" top="103.940000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/can/128/LKAS_ALT/ADAS_StrAnglReqVal" color="#29d627"/>
|
||||||
|
<curve name="/can/192/LKAS_ALT/ADAS_StrAnglReqVal" color="#b41f32"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-0.025000" left="301.990881" top="1.025000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carState/steeringPressed" color="#d62728"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="0.975000" left="301.990881" top="2.025000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/sendcan/0/LKAS_ALT/LKAS_ANGLE_ACTIVE" color="#1f77b4"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-0.025000" left="301.990881" top="1.025000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carState/steerFaultTemporary" color="#d62728"/>
|
||||||
|
<curve name="/carControl/latActive" color="#1ac938"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-0.025000" left="301.990881" top="1.025000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/can/1/CCNC_0x161/DAW_ICON" color="#f14cc1"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-14.375000" left="301.990881" top="589.375000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/pandaStates/0/safetyTxBlocked" color="#1f77b4"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<Tab containers="1" tab_name="Understanding Torque">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter orientation="-" sizes="0.5;0.5" count="2">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-6.175000" left="429.901019" top="253.175000" right="590.696728"/>
|
||||||
|
<limitY/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-24.190000" left="301.990881" top="21.590000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carState/steeringTorqueEps" color="#1ac938"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<Tab containers="1" tab_name="tab2">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter orientation="-" sizes="0.25;0.25;0.25;0.25" count="4">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Dots">
|
||||||
|
<range bottom="-0.025000" left="301.990881" top="1.025000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/sendcan/0/LKAS_ALT/ADAS_ACIAnglTqRedcGainVal" color="#9467bd"/>
|
||||||
|
<curve name="/can/1/LFA_ALT/ADAS_ACIAnglTqRedcGainVal" color="#17becf"/>
|
||||||
|
<curve name="/can/128/LKAS_ALT/ADAS_ACIAnglTqRedcGainVal" color="#1f77b4"/>
|
||||||
|
<curve name="/can/192/LKAS_ALT/ADAS_ACIAnglTqRedcGainVal" color="#d62728"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Dots">
|
||||||
|
<range bottom="0.975000" left="301.990881" top="2.025000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/can/128/LKAS_ALT/LKAS_ANGLE_ACTIVE" color="#b8c91a"/>
|
||||||
|
<curve name="/can/192/LKAS_ALT/LKAS_ANGLE_ACTIVE" color="#ff7f0e"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Lines">
|
||||||
|
<range bottom="-0.025000" left="301.990881" top="1.025000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/can/1/CCNC_0x161/DAW_ICON" color="#f14cc1"/>
|
||||||
|
<curve name="/carState/steerFaultTemporary" color="#1f77b4"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot mode="TimeSeries" flip_x="false" flip_y="false" style="Dots">
|
||||||
|
<range bottom="-14.375000" left="301.990881" top="589.375000" right="462.962504"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/pandaStates/0/safetyTxBlocked" color="#bcbd22"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<currentTabIndex index="3"/>
|
||||||
|
</tabbed_widget>
|
||||||
|
<use_relative_time_offset enabled="1"/>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<Plugins>
|
||||||
|
<plugin ID="DataLoad CSV">
|
||||||
|
<default time_axis="" delimiter="0"/>
|
||||||
|
</plugin>
|
||||||
|
<plugin ID="DataLoad MCAP"/>
|
||||||
|
<plugin ID="DataLoad Rlog"/>
|
||||||
|
<plugin ID="DataLoad ULog"/>
|
||||||
|
<plugin ID="Cereal Subscriber"/>
|
||||||
|
<plugin ID="UDP Server"/>
|
||||||
|
<plugin ID="WebSocket Server"/>
|
||||||
|
<plugin ID="ZMQ Subscriber"/>
|
||||||
|
<plugin ID="Fast Fourier Transform"/>
|
||||||
|
<plugin ID="Quaternion to RPY"/>
|
||||||
|
<plugin ID="Reactive Script Editor">
|
||||||
|
<library code="--[[ Helper function to create a series from arrays

 new_series: a series previously created with ScatterXY.new(name)
 prefix: prefix of the timeseries, before the index of the array
 suffix_X: suffix to complete the name of the series containing the X value. If [nil], use the index of the array.
 suffix_Y: suffix to complete the name of the series containing the Y value
 timestamp: usually the tracker_time variable
 
 Example:
 
 Assuming we have multiple series in the form:
 
 /trajectory/node.{X}/position/x
 /trajectory/node.{X}/position/y
 
 where {N} is the index of the array (integer). We can create a reactive series from the array with:
 
 new_series = ScatterXY.new("my_trajectory") 
 CreateSeriesFromArray( new_series, "/trajectory/node", "position/x", "position/y", tracker_time );
--]]

function CreateSeriesFromArray( new_series, prefix, suffix_X, suffix_Y, timestamp )
 
 --- clear previous values
 new_series:clear()
 
 --- Append points to new_series
 index = 0
 while(true) do

 x = index;
 -- if not nil, get the X coordinate from a series
 if suffix_X ~= nil then 
 series_x = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_X) )
 if series_x == nil then break end
 x = series_x:atTime(timestamp)	 
 end
 
 series_y = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_Y) )
 if series_y == nil then break end 
 y = series_y:atTime(timestamp)
 
 new_series:push_back(x,y)
 index = index+1
 end
end

--[[ Similar to the built-in function GetSeriesNames(), but select only the names with a give prefix. --]]

function GetSeriesNamesByPrefix(prefix)
 -- GetSeriesNames(9 is a built-in function
 all_names = GetSeriesNames()
 filtered_names = {}
 for i, name in ipairs(all_names) do
 -- check the prefix
 if name:find(prefix, 1, #prefix) then
 table.insert(filtered_names, name);
 end
 end
 return filtered_names
end

--[[ Modify an existing series, applying offsets to all their X and Y values

 series: an existing timeseries, obtained with TimeseriesView.find(name)
 delta_x: offset to apply to each x value
 delta_y: offset to apply to each y value 
 
--]]

function ApplyOffsetInPlace(series, delta_x, delta_y)
 -- use C++ indeces, not Lua indeces
 for index=0, series:size()-1 do
 x,y = series:at(index)
 series:set(index, x + delta_x, y + delta_y)
 end
end
"/>
|
||||||
|
<scripts/>
|
||||||
|
</plugin>
|
||||||
|
<plugin ID="CSV Exporter"/>
|
||||||
|
</Plugins>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<customMathEquations/>
|
||||||
|
<snippets/>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
</root>
|
||||||
|
|
||||||
@@ -0,0 +1,636 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<root>
|
||||||
|
<tabbed_widget name="Main Window" parent="main_window">
|
||||||
|
<Tab tab_name="actuator data" containers="1">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter orientation="-" sizes="0.25;0.25;0.25;0.25" count="4">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-0.100000" left="6.467547" top="0.100000"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carControl/actuators/torque" color="#17becf"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-356.587494" left="6.467547" top="491.287506"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carControl/actuators/steeringAngleDeg" color="#1f77b4"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-0.856228" left="6.467547" top="35.834527"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carState/vEgoRaw" color="#ff7f0e"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-0.186684" left="6.467547" top="0.134230"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carControl/actuators/curvature" color="#f14cc1"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<Tab tab_name="steering messages (CAN)" containers="1">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter orientation="-" sizes="0.25;0.25;0.25;0.25" count="4">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-0.022000" left="6.467547" top="0.902000"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/sendcan/0/LKAS_ALT/ADAS_ACIAnglTqRedcGainVal" color="#1f77b4"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-5.168301" left="6.467547" top="4.590794"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="IMU_LatAccelVal_ms^2_roll_compensated" color="#ff7f0e"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-0.025000" left="6.467547" top="1.025000"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carState/steeringPressed" color="#d62728"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-0.100000" left="6.467547" top="0.100000"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/can/1/CCNC_0x161/DAW_ICON" color="#f14cc1"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<Tab tab_name="Understanding Torque" containers="1">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter orientation="-" sizes="0.5;0.5" count="2">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="722.420439" bottom="-6.250000" left="0.000000" top="256.250000"/>
|
||||||
|
<limitY/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-34.457500" left="6.467547" top="26.757499"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carState/steeringTorqueEps" color="#1ac938"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<Tab tab_name="Angle Error and Saturation TQ" containers="1">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter orientation="-" sizes="0.200218;0.200218;0.199129;0.200218;0.200218" count="5">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-356.587494" left="6.467547" top="491.287506"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carControl/actuators/steeringAngleDeg" color="#d62728"/>
|
||||||
|
<curve name="/carState/steeringAngleDeg" color="#1ac938"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-134.196237" left="6.467547" top="34.112077"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="Angle Error" color="#ff7f0e"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-0.022000" left="6.467547" top="0.902000"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/sendcan/0/LKAS_ALT/ADAS_ACIAnglTqRedcGainVal" color="#1f77b4"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-0.025000" left="6.467547" top="1.025000"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="Angle Staturation" color="#f14cc1"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot style="Lines" mode="TimeSeries" flip_x="false" flip_y="false">
|
||||||
|
<range right="396.045059" bottom="-0.025000" left="6.467547" top="1.025000"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carControl/latActive" color="#9467bd"/>
|
||||||
|
<curve name="/carState/steeringPressed" color="#17becf"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<currentTabIndex index="3"/>
|
||||||
|
</tabbed_widget>
|
||||||
|
<use_relative_time_offset enabled="1"/>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<Plugins>
|
||||||
|
<plugin ID="DataLoad CSV">
|
||||||
|
<default time_axis="" delimiter="0"/>
|
||||||
|
</plugin>
|
||||||
|
<plugin ID="DataLoad MCAP"/>
|
||||||
|
<plugin ID="DataLoad Rlog"/>
|
||||||
|
<plugin ID="DataLoad ULog"/>
|
||||||
|
<plugin ID="Cereal Subscriber"/>
|
||||||
|
<plugin ID="UDP Server"/>
|
||||||
|
<plugin ID="WebSocket Server"/>
|
||||||
|
<plugin ID="ZMQ Subscriber"/>
|
||||||
|
<plugin ID="Fast Fourier Transform"/>
|
||||||
|
<plugin ID="Quaternion to RPY"/>
|
||||||
|
<plugin ID="Reactive Script Editor">
|
||||||
|
<library code="--[[ Helper function to create a series from arrays

 new_series: a series previously created with ScatterXY.new(name)
 prefix: prefix of the timeseries, before the index of the array
 suffix_X: suffix to complete the name of the series containing the X value. If [nil], use the index of the array.
 suffix_Y: suffix to complete the name of the series containing the Y value
 timestamp: usually the tracker_time variable
 
 Example:
 
 Assuming we have multiple series in the form:
 
 /trajectory/node.{X}/position/x
 /trajectory/node.{X}/position/y
 
 where {N} is the index of the array (integer). We can create a reactive series from the array with:
 
 new_series = ScatterXY.new("my_trajectory") 
 CreateSeriesFromArray( new_series, "/trajectory/node", "position/x", "position/y", tracker_time );
--]]

function CreateSeriesFromArray( new_series, prefix, suffix_X, suffix_Y, timestamp )
 
 --- clear previous values
 new_series:clear()
 
 --- Append points to new_series
 index = 0
 while(true) do

 x = index;
 -- if not nil, get the X coordinate from a series
 if suffix_X ~= nil then 
 series_x = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_X) )
 if series_x == nil then break end
 x = series_x:atTime(timestamp)	 
 end
 
 series_y = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_Y) )
 if series_y == nil then break end 
 y = series_y:atTime(timestamp)
 
 new_series:push_back(x,y)
 index = index+1
 end
end

--[[ Similar to the built-in function GetSeriesNames(), but select only the names with a give prefix. --]]

function GetSeriesNamesByPrefix(prefix)
 -- GetSeriesNames(9 is a built-in function
 all_names = GetSeriesNames()
 filtered_names = {}
 for i, name in ipairs(all_names) do
 -- check the prefix
 if name:find(prefix, 1, #prefix) then
 table.insert(filtered_names, name);
 end
 end
 return filtered_names
end

--[[ Modify an existing series, applying offsets to all their X and Y values

 series: an existing timeseries, obtained with TimeseriesView.find(name)
 delta_x: offset to apply to each x value
 delta_y: offset to apply to each y value 
 
--]]

function ApplyOffsetInPlace(series, delta_x, delta_y)
 -- use C++ indeces, not Lua indeces
 for index=0, series:size()-1 do
 x,y = series:at(index)
 series:set(index, x + delta_x, y + delta_y)
 end
end
"/>
|
||||||
|
<scripts/>
|
||||||
|
</plugin>
|
||||||
|
<plugin ID="CSV Exporter"/>
|
||||||
|
</Plugins>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<previouslyLoaded_Datafiles>
|
||||||
|
<fileInfo filename="../tmpgh9xhmjb.rlog" prefix="">
|
||||||
|
<selected_datasources value=""/>
|
||||||
|
</fileInfo>
|
||||||
|
</previouslyLoaded_Datafiles>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<customMathEquations>
|
||||||
|
<snippet name="Angle Staturation">
|
||||||
|
<global></global>
|
||||||
|
<function>if value > .3 then
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return 0</function>
|
||||||
|
<linked_source>Angle Error</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="ang_cmd rate">
|
||||||
|
<global>firstX = 0
|
||||||
|
firstY = 0
|
||||||
|
is_first = true
|
||||||
|
secondX = 0
|
||||||
|
secondY = 0
|
||||||
|
is_second = false</global>
|
||||||
|
<function>-- Wait for initial values
|
||||||
|
if (is_first) then
|
||||||
|
is_first = false
|
||||||
|
is_second = true
|
||||||
|
firstX = time
|
||||||
|
firstY = value
|
||||||
|
end
|
||||||
|
|
||||||
|
if (is_second) then
|
||||||
|
is_second = false
|
||||||
|
secondX = time
|
||||||
|
secondY = value
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Central derivative: dy/dx ~= f(x+delta_x)-f(x-delta_x)/(2*delta_x)
|
||||||
|
dx = time - firstX
|
||||||
|
dy = value - firstY
|
||||||
|
-- Increment
|
||||||
|
firstX = secondX
|
||||||
|
firstY = secondY
|
||||||
|
secondX = time
|
||||||
|
secondY = value
|
||||||
|
|
||||||
|
return dy/dx</function>
|
||||||
|
<linked_source>/can/1/LFA_ALT/LKAS_ANGLE_CMD</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="max torque lj adj">
|
||||||
|
<global>min=0
|
||||||
|
max=250
|
||||||
|
max_from_speed=96
|
||||||
|
|
||||||
|
k1=200
|
||||||
|
k2=30
|
||||||
|
k3=1
|
||||||
|
k4=1
|
||||||
|
k5=10
|
||||||
|
|
||||||
|
function sign(number)
|
||||||
|
return number > 0 and 1 or (number == 0 and 0 or -1)
|
||||||
|
end</global>
|
||||||
|
<function>return 250 - value * 20</function>
|
||||||
|
<linked_source>desired lateral jark</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="max torque(calc)">
|
||||||
|
<global>min=0
|
||||||
|
max=250
|
||||||
|
max_from_speed=96
|
||||||
|
|
||||||
|
rate_lim = 500
|
||||||
|
|
||||||
|
la_deadzone = 0.38
|
||||||
|
|
||||||
|
k1=200
|
||||||
|
k2=20
|
||||||
|
k3=1.0
|
||||||
|
k4=1
|
||||||
|
k5=10
|
||||||
|
|
||||||
|
old = 0
|
||||||
|
|
||||||
|
function sign(number)
|
||||||
|
return number > 0 and 1 or (number == 0 and 0 or -1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function apply_rate_limit(old, new, limit)
|
||||||
|
return math.min(math.max(new, old - limit), old + limit)
|
||||||
|
end
|
||||||
|
|
||||||
|
function apply_deadzone(val, deadzone)
|
||||||
|
if math.abs(val) <= deadzone then
|
||||||
|
return 0.0
|
||||||
|
elseif val < 0.0 then
|
||||||
|
return val + deadzone
|
||||||
|
else
|
||||||
|
return val - deadzone
|
||||||
|
end
|
||||||
|
end</global>
|
||||||
|
<function>la = apply_deadzone(v2, la_deadzone)
|
||||||
|
lj = v3
|
||||||
|
|
||||||
|
if la == 0.0 then
|
||||||
|
lj = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
fla = math.min(math.abs(k1 * la)^k3, max)
|
||||||
|
flj = math.min(math.abs(k2 * lj)^k4, max)
|
||||||
|
|
||||||
|
out = fla
|
||||||
|
|
||||||
|
flv = math.min(max_from_speed, k5 * v4)
|
||||||
|
|
||||||
|
out = out + flv
|
||||||
|
|
||||||
|
out = math.max(math.min(out, max), min)
|
||||||
|
|
||||||
|
if sign(la) == sign(lj) then
|
||||||
|
out = out - flj
|
||||||
|
else
|
||||||
|
out = out + flj
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if v5 == 1.0 then
|
||||||
|
out = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
out = math.max(math.min(out, max), min)
|
||||||
|
out = apply_rate_limit(old, out, rate_lim)
|
||||||
|
old = out
|
||||||
|
|
||||||
|
return out</function>
|
||||||
|
<linked_source>/can/1/LFA_ALT/LKAS_ANGLE_CMD</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>ang_cmd rate</v1>
|
||||||
|
<v2>desired lat accel</v2>
|
||||||
|
<v3>desired lateral jark</v3>
|
||||||
|
<v4>/carState/vEgo</v4>
|
||||||
|
<v5>/can/1/LFA_ALT/LKAS_ANGLE_ACTIVE</v5>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="carState.vEgo mph">
|
||||||
|
<global></global>
|
||||||
|
<function>return value * 2.23694</function>
|
||||||
|
<linked_source>/carState/vEgo</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="abs(des la accel)">
|
||||||
|
<global></global>
|
||||||
|
<function>return math.abs(value)</function>
|
||||||
|
<linked_source>desired lat accel</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="roll compensated lateral acceleration">
|
||||||
|
<global></global>
|
||||||
|
<function>if (v3 == 0 and v4 == 1) then
|
||||||
|
return (value * v1 ^ 2) - (v2 * 9.81)
|
||||||
|
end
|
||||||
|
return 0</function>
|
||||||
|
<linked_source>/controlsState/curvature</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/vEgo</v1>
|
||||||
|
<v2>/liveParameters/roll</v2>
|
||||||
|
<v3>/carState/steeringPressed</v3>
|
||||||
|
<v4>/carControl/latActive</v4>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="Zero">
|
||||||
|
<global></global>
|
||||||
|
<function>return (0)</function>
|
||||||
|
<linked_source>/carState/canValid</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="IMU_LatAccelVal_ms^2">
|
||||||
|
<global></global>
|
||||||
|
<function>return value * -9.8</function>
|
||||||
|
<linked_source>/can/1/IMU_01_10ms/IMU_LatAccelVal</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/latActive</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="desired lat accel">
|
||||||
|
<global></global>
|
||||||
|
<function>return value * v1^2</function>
|
||||||
|
<linked_source>/controlsState/desiredCurvature</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/vEgo</v1>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="engaged_accel_actuator">
|
||||||
|
<global>engage_delay = 5
|
||||||
|
last_bad_time = -engage_delay</global>
|
||||||
|
<function>accel = value
|
||||||
|
brake = v1
|
||||||
|
gas = v2
|
||||||
|
enabled = v3
|
||||||
|
|
||||||
|
if (brake ~= 0 or gas ~= 0 or enabled == 0) then
|
||||||
|
last_bad_time = time
|
||||||
|
end
|
||||||
|
|
||||||
|
if (time > last_bad_time + engage_delay) then
|
||||||
|
return value
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end</function>
|
||||||
|
<linked_source>/carControl/actuators/accel</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/brakePressed</v1>
|
||||||
|
<v2>/carState/gasPressed</v2>
|
||||||
|
<v3>/carControl/enabled</v3>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="Angle Error">
|
||||||
|
<global>last_angle_requested = 0</global>
|
||||||
|
<function>angle_error = last_angle_requested - v1
|
||||||
|
|
||||||
|
|
||||||
|
last_angle_requested = value
|
||||||
|
return angle_error</function>
|
||||||
|
<linked_source>/carControl/actuators/steeringAngleDeg</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringAngleDeg</v1>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="carState.vEgo kmh">
|
||||||
|
<global></global>
|
||||||
|
<function>return value * 3.6</function>
|
||||||
|
<linked_source>/carState/vEgo</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="engaged_accel_plan">
|
||||||
|
<global>engage_delay = 5
|
||||||
|
last_bad_time = -engage_delay</global>
|
||||||
|
<function>accel = value
|
||||||
|
brake = v1
|
||||||
|
gas = v2
|
||||||
|
enabled = v3
|
||||||
|
|
||||||
|
if (brake ~= 0 or gas ~= 0 or enabled == 0) then
|
||||||
|
last_bad_time = time
|
||||||
|
end
|
||||||
|
|
||||||
|
if (time > last_bad_time + engage_delay) then
|
||||||
|
return value
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end</function>
|
||||||
|
<linked_source>/longitudinalPlan/accels/0</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/brakePressed</v1>
|
||||||
|
<v2>/carState/gasPressed</v2>
|
||||||
|
<v3>/carControl/enabled</v3>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="engaged_accel_actual">
|
||||||
|
<global>engage_delay = 5
|
||||||
|
last_bad_time = -engage_delay</global>
|
||||||
|
<function>accel = value
|
||||||
|
brake = v1
|
||||||
|
gas = v2
|
||||||
|
enabled = v3
|
||||||
|
|
||||||
|
if (brake ~= 0 or gas ~= 0 or enabled == 0) then
|
||||||
|
last_bad_time = time
|
||||||
|
end
|
||||||
|
|
||||||
|
if (time > last_bad_time + engage_delay) then
|
||||||
|
return value
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end</function>
|
||||||
|
<linked_source>/carState/aEgo</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/brakePressed</v1>
|
||||||
|
<v2>/carState/gasPressed</v2>
|
||||||
|
<v3>/carControl/enabled</v3>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="desired lateral jark">
|
||||||
|
<global>firstX = 0
|
||||||
|
firstY = 0
|
||||||
|
is_first = true
|
||||||
|
secondX = 0
|
||||||
|
secondY = 0
|
||||||
|
is_second = false</global>
|
||||||
|
<function>-- Wait for initial values
|
||||||
|
if (is_first) then
|
||||||
|
is_first = false
|
||||||
|
is_second = true
|
||||||
|
firstX = time
|
||||||
|
firstY = value
|
||||||
|
end
|
||||||
|
|
||||||
|
if (is_second) then
|
||||||
|
is_second = false
|
||||||
|
secondX = time
|
||||||
|
secondY = value
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Central derivative: dy/dx ~= f(x+delta_x)-f(x-delta_x)/(2*delta_x)
|
||||||
|
dx = time - firstX
|
||||||
|
dy = value - firstY
|
||||||
|
-- Increment
|
||||||
|
firstX = secondX
|
||||||
|
firstY = secondY
|
||||||
|
secondX = time
|
||||||
|
secondY = value
|
||||||
|
|
||||||
|
return dy/dx</function>
|
||||||
|
<linked_source>desired lat accel</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="engaged curvature plan">
|
||||||
|
<global>engage_delay = 5
|
||||||
|
last_bad_time = -engage_delay</global>
|
||||||
|
<function>curvature = value
|
||||||
|
pressed = v1
|
||||||
|
enabled = v2
|
||||||
|
|
||||||
|
if (pressed == 1 or enabled == 0) then
|
||||||
|
last_bad_time = time
|
||||||
|
end
|
||||||
|
|
||||||
|
if (time > last_bad_time + engage_delay) then
|
||||||
|
return value
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end</function>
|
||||||
|
<linked_source>/lateralPlan/curvatures/0</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/enabled</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="abs(ang_cmd)">
|
||||||
|
<global></global>
|
||||||
|
<function>return math.abs(value)</function>
|
||||||
|
<linked_source>/can/1/LFA_ALT/LKAS_ANGLE_CMD</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="zero">
|
||||||
|
<global>min=0
|
||||||
|
max=250
|
||||||
|
max_from_speed=96
|
||||||
|
|
||||||
|
rate_lim = 500
|
||||||
|
|
||||||
|
la_deadzone = 0.38
|
||||||
|
|
||||||
|
k1=200
|
||||||
|
k2=20
|
||||||
|
k3=1.0
|
||||||
|
k4=1
|
||||||
|
k5=10
|
||||||
|
|
||||||
|
old = 0
|
||||||
|
|
||||||
|
function sign(number)
|
||||||
|
return number > 0 and 1 or (number == 0 and 0 or -1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function apply_rate_limit(old, new, limit)
|
||||||
|
return math.min(math.max(new, old - limit), old + limit)
|
||||||
|
end
|
||||||
|
|
||||||
|
function apply_deadzone(val, deadzone)
|
||||||
|
if math.abs(val) <= deadzone then
|
||||||
|
return 0.0
|
||||||
|
elseif val < 0.0 then
|
||||||
|
return val + deadzone
|
||||||
|
else
|
||||||
|
return val - deadzone
|
||||||
|
end
|
||||||
|
end</global>
|
||||||
|
<function>return 0</function>
|
||||||
|
<linked_source>/carState/aEgo</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="engaged curvature vehicle model">
|
||||||
|
<global>engage_delay = 5
|
||||||
|
last_bad_time = -engage_delay</global>
|
||||||
|
<function>curvature = value
|
||||||
|
pressed = v1
|
||||||
|
enabled = v2
|
||||||
|
|
||||||
|
if (pressed == 1 or enabled == 0) then
|
||||||
|
last_bad_time = time
|
||||||
|
end
|
||||||
|
|
||||||
|
if (time > last_bad_time + engage_delay) then
|
||||||
|
return value
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end</function>
|
||||||
|
<linked_source>/controlsState/curvature</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/enabled</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="Actual lateral accel (roll compensated)">
|
||||||
|
<global></global>
|
||||||
|
<function>return (value * v1 ^ 2) - (v2 * 9.81)</function>
|
||||||
|
<linked_source>/controlsState/curvature</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/vEgo</v1>
|
||||||
|
<v2>/liveParameters/roll</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="IMU_LatAccelVal_ms^2_roll_compensated">
|
||||||
|
<global></global>
|
||||||
|
<function>if (v1 == 0 and v2 == 1) then
|
||||||
|
return (value * -9.8) - (v3 * 9.81)
|
||||||
|
end
|
||||||
|
--return 0
|
||||||
|
return (value * -9.8) - (v3 * 9.81)</function>
|
||||||
|
<linked_source>/can/1/IMU_01_10ms/IMU_LatAccelVal</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/latActive</v2>
|
||||||
|
<v3>/liveParameters/roll</v3>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="IMU_LatAccelVal_Ms^2">
|
||||||
|
<global></global>
|
||||||
|
<function>if (v1 == 0 and v2 == 1) then
|
||||||
|
return value * -9.8
|
||||||
|
end
|
||||||
|
return 0</function>
|
||||||
|
<linked_source>/can/1/IMU_01_10ms/IMU_LatAccelVal</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/latActive</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="engaged curvature yaw">
|
||||||
|
<global>engage_delay = 5
|
||||||
|
last_bad_time = -engage_delay</global>
|
||||||
|
<function>curvature = value / v3
|
||||||
|
pressed = v1
|
||||||
|
enabled = v2
|
||||||
|
|
||||||
|
if (pressed == 1 or enabled == 0) then
|
||||||
|
last_bad_time = time
|
||||||
|
end
|
||||||
|
|
||||||
|
if (time > last_bad_time + engage_delay) then
|
||||||
|
return curvature
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end</function>
|
||||||
|
<linked_source>/liveLocationKalman/angularVelocityCalibrated/value/2</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/enabled</v2>
|
||||||
|
<v3>/liveLocationKalman/velocityCalibrated/value/0</v3>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="IMU_LatAccelVal_Ms^3">
|
||||||
|
<global></global>
|
||||||
|
<function>return value * -9.8</function>
|
||||||
|
<linked_source>/can/1/IMU_01_10ms/IMU_LatAccelVal</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/latActive</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="Desired lateral accel (roll compensated)">
|
||||||
|
<global></global>
|
||||||
|
<function>return (value * v1 ^ 2) - (v2 * 9.81)</function>
|
||||||
|
<linked_source>/controlsState/desiredCurvature</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/vEgo</v1>
|
||||||
|
<v2>/liveParameters/roll</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
</customMathEquations>
|
||||||
|
<snippets/>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
</root>
|
||||||
|
|
||||||
@@ -0,0 +1,281 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<root>
|
||||||
|
<tabbed_widget name="Main Window" parent="main_window">
|
||||||
|
<Tab containers="1" tab_name="tab1">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter sizes="0.500397;0.499603" count="2" orientation="-">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot flip_x="false" flip_y="false" mode="TimeSeries" style="Lines">
|
||||||
|
<range top="256.250000" left="0.000000" right="421.102293" bottom="-6.250000"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve color="#1ac938" name="/can/1/LFA_ALT/LKAS_ANGLE_MAX_TORQUE"/>
|
||||||
|
<curve color="#17becf" name="max torque(calc)">
|
||||||
|
<transform name="Moving Average" alias="max torque(calc)[Moving Average]">
|
||||||
|
<options compensate_offset="true" value="10"/>
|
||||||
|
</transform>
|
||||||
|
</curve>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot flip_x="false" flip_y="false" mode="TimeSeries" style="Lines">
|
||||||
|
<range top="2.776497" left="0.000000" right="421.102293" bottom="-2.918548"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve color="#f14cc1" name="desired lat accel"/>
|
||||||
|
<curve color="#888888" name="zero"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<currentTabIndex index="0"/>
|
||||||
|
</tabbed_widget>
|
||||||
|
<use_relative_time_offset enabled="1"/>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<Plugins>
|
||||||
|
<plugin ID="DataLoad CSV">
|
||||||
|
<default time_axis="" delimiter="0"/>
|
||||||
|
</plugin>
|
||||||
|
<plugin ID="DataLoad MCAP"/>
|
||||||
|
<plugin ID="DataLoad Rlog"/>
|
||||||
|
<plugin ID="DataLoad ULog"/>
|
||||||
|
<plugin ID="Cereal Subscriber"/>
|
||||||
|
<plugin ID="UDP Server"/>
|
||||||
|
<plugin ID="WebSocket Server"/>
|
||||||
|
<plugin ID="ZMQ Subscriber"/>
|
||||||
|
<plugin ID="Fast Fourier Transform"/>
|
||||||
|
<plugin ID="Quaternion to RPY"/>
|
||||||
|
<plugin ID="Reactive Script Editor">
|
||||||
|
<library code="--[[ Helper function to create a series from arrays

 new_series: a series previously created with ScatterXY.new(name)
 prefix: prefix of the timeseries, before the index of the array
 suffix_X: suffix to complete the name of the series containing the X value. If [nil], use the index of the array.
 suffix_Y: suffix to complete the name of the series containing the Y value
 timestamp: usually the tracker_time variable
 
 Example:
 
 Assuming we have multiple series in the form:
 
 /trajectory/node.{X}/position/x
 /trajectory/node.{X}/position/y
 
 where {N} is the index of the array (integer). We can create a reactive series from the array with:
 
 new_series = ScatterXY.new("my_trajectory") 
 CreateSeriesFromArray( new_series, "/trajectory/node", "position/x", "position/y", tracker_time );
--]]

function CreateSeriesFromArray( new_series, prefix, suffix_X, suffix_Y, timestamp )
 
 --- clear previous values
 new_series:clear()
 
 --- Append points to new_series
 index = 0
 while(true) do

 x = index;
 -- if not nil, get the X coordinate from a series
 if suffix_X ~= nil then 
 series_x = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_X) )
 if series_x == nil then break end
 x = series_x:atTime(timestamp)	 
 end
 
 series_y = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_Y) )
 if series_y == nil then break end 
 y = series_y:atTime(timestamp)
 
 new_series:push_back(x,y)
 index = index+1
 end
end

--[[ Similar to the built-in function GetSeriesNames(), but select only the names with a give prefix. --]]

function GetSeriesNamesByPrefix(prefix)
 -- GetSeriesNames(9 is a built-in function
 all_names = GetSeriesNames()
 filtered_names = {}
 for i, name in ipairs(all_names) do
 -- check the prefix
 if name:find(prefix, 1, #prefix) then
 table.insert(filtered_names, name);
 end
 end
 return filtered_names
end

--[[ Modify an existing series, applying offsets to all their X and Y values

 series: an existing timeseries, obtained with TimeseriesView.find(name)
 delta_x: offset to apply to each x value
 delta_y: offset to apply to each y value 
 
--]]

function ApplyOffsetInPlace(series, delta_x, delta_y)
 -- use C++ indeces, not Lua indeces
 for index=0, series:size()-1 do
 x,y = series:at(index)
 series:set(index, x + delta_x, y + delta_y)
 end
end
"/>
|
||||||
|
<scripts/>
|
||||||
|
</plugin>
|
||||||
|
<plugin ID="CSV Exporter"/>
|
||||||
|
</Plugins>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<previouslyLoaded_Datafiles>
|
||||||
|
<fileInfo prefix="" filename="../tmpa_e8kwpj.rlog">
|
||||||
|
<selected_datasources value=""/>
|
||||||
|
</fileInfo>
|
||||||
|
</previouslyLoaded_Datafiles>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<customMathEquations>
|
||||||
|
<snippet name="zero">
|
||||||
|
<global>min=0
|
||||||
|
max=250
|
||||||
|
max_from_speed=96
|
||||||
|
|
||||||
|
rate_lim = 500
|
||||||
|
|
||||||
|
la_deadzone = 0.38
|
||||||
|
|
||||||
|
k1=200
|
||||||
|
k2=20
|
||||||
|
k3=1.0
|
||||||
|
k4=1
|
||||||
|
k5=10
|
||||||
|
|
||||||
|
old = 0
|
||||||
|
|
||||||
|
function sign(number)
|
||||||
|
return number > 0 and 1 or (number == 0 and 0 or -1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function apply_rate_limit(old, new, limit)
|
||||||
|
return math.min(math.max(new, old - limit), old + limit)
|
||||||
|
end
|
||||||
|
|
||||||
|
function apply_deadzone(val, deadzone)
|
||||||
|
if math.abs(val) <= deadzone then
|
||||||
|
return 0.0
|
||||||
|
elseif val < 0.0 then
|
||||||
|
return val + deadzone
|
||||||
|
else
|
||||||
|
return val - deadzone
|
||||||
|
end
|
||||||
|
end</global>
|
||||||
|
<function>return 0</function>
|
||||||
|
<linked_source>/carState/aEgo</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="max torque lj adj">
|
||||||
|
<global>min=0
|
||||||
|
max=250
|
||||||
|
max_from_speed=96
|
||||||
|
|
||||||
|
k1=200
|
||||||
|
k2=30
|
||||||
|
k3=1
|
||||||
|
k4=1
|
||||||
|
k5=10
|
||||||
|
|
||||||
|
function sign(number)
|
||||||
|
return number > 0 and 1 or (number == 0 and 0 or -1)
|
||||||
|
end</global>
|
||||||
|
<function>return 250 - value * 20</function>
|
||||||
|
<linked_source>desired lateral jark</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="ang_cmd rate">
|
||||||
|
<global>firstX = 0
|
||||||
|
firstY = 0
|
||||||
|
is_first = true
|
||||||
|
secondX = 0
|
||||||
|
secondY = 0
|
||||||
|
is_second = false</global>
|
||||||
|
<function>-- Wait for initial values
|
||||||
|
if (is_first) then
|
||||||
|
is_first = false
|
||||||
|
is_second = true
|
||||||
|
firstX = time
|
||||||
|
firstY = value
|
||||||
|
end
|
||||||
|
|
||||||
|
if (is_second) then
|
||||||
|
is_second = false
|
||||||
|
secondX = time
|
||||||
|
secondY = value
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Central derivative: dy/dx ~= f(x+delta_x)-f(x-delta_x)/(2*delta_x)
|
||||||
|
dx = time - firstX
|
||||||
|
dy = value - firstY
|
||||||
|
-- Increment
|
||||||
|
firstX = secondX
|
||||||
|
firstY = secondY
|
||||||
|
secondX = time
|
||||||
|
secondY = value
|
||||||
|
|
||||||
|
return dy/dx</function>
|
||||||
|
<linked_source>/can/1/LFA_ALT/LKAS_ANGLE_CMD</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="max torque(calc)">
|
||||||
|
<global>min=0
|
||||||
|
max=250
|
||||||
|
max_from_speed=96
|
||||||
|
|
||||||
|
rate_lim = 500
|
||||||
|
|
||||||
|
la_deadzone = 0.38
|
||||||
|
|
||||||
|
k1=200
|
||||||
|
k2=20
|
||||||
|
k3=1.0
|
||||||
|
k4=1
|
||||||
|
k5=10
|
||||||
|
|
||||||
|
old = 0
|
||||||
|
|
||||||
|
function sign(number)
|
||||||
|
return number > 0 and 1 or (number == 0 and 0 or -1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function apply_rate_limit(old, new, limit)
|
||||||
|
return math.min(math.max(new, old - limit), old + limit)
|
||||||
|
end
|
||||||
|
|
||||||
|
function apply_deadzone(val, deadzone)
|
||||||
|
if math.abs(val) <= deadzone then
|
||||||
|
return 0.0
|
||||||
|
elseif val < 0.0 then
|
||||||
|
return val + deadzone
|
||||||
|
else
|
||||||
|
return val - deadzone
|
||||||
|
end
|
||||||
|
end</global>
|
||||||
|
<function>la = apply_deadzone(v2, la_deadzone)
|
||||||
|
lj = v3
|
||||||
|
|
||||||
|
if la == 0.0 then
|
||||||
|
lj = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
fla = math.min(math.abs(k1 * la)^k3, max)
|
||||||
|
flj = math.min(math.abs(k2 * lj)^k4, max)
|
||||||
|
|
||||||
|
out = fla
|
||||||
|
|
||||||
|
flv = math.min(max_from_speed, k5 * v4)
|
||||||
|
|
||||||
|
out = out + flv
|
||||||
|
|
||||||
|
out = math.max(math.min(out, max), min)
|
||||||
|
|
||||||
|
if sign(la) == sign(lj) then
|
||||||
|
out = out - flj
|
||||||
|
else
|
||||||
|
out = out + flj
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if v5 == 1.0 then
|
||||||
|
out = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
out = math.max(math.min(out, max), min)
|
||||||
|
out = apply_rate_limit(old, out, rate_lim)
|
||||||
|
old = out
|
||||||
|
|
||||||
|
return out</function>
|
||||||
|
<linked_source>/can/1/LFA_ALT/LKAS_ANGLE_CMD</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>ang_cmd rate</v1>
|
||||||
|
<v2>desired lat accel</v2>
|
||||||
|
<v3>desired lateral jark</v3>
|
||||||
|
<v4>/carState/vEgo</v4>
|
||||||
|
<v5>/can/1/LFA_ALT/LKAS_ANGLE_ACTIVE</v5>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="desired lateral jark">
|
||||||
|
<global>firstX = 0
|
||||||
|
firstY = 0
|
||||||
|
is_first = true
|
||||||
|
secondX = 0
|
||||||
|
secondY = 0
|
||||||
|
is_second = false</global>
|
||||||
|
<function>-- Wait for initial values
|
||||||
|
if (is_first) then
|
||||||
|
is_first = false
|
||||||
|
is_second = true
|
||||||
|
firstX = time
|
||||||
|
firstY = value
|
||||||
|
end
|
||||||
|
|
||||||
|
if (is_second) then
|
||||||
|
is_second = false
|
||||||
|
secondX = time
|
||||||
|
secondY = value
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Central derivative: dy/dx ~= f(x+delta_x)-f(x-delta_x)/(2*delta_x)
|
||||||
|
dx = time - firstX
|
||||||
|
dy = value - firstY
|
||||||
|
-- Increment
|
||||||
|
firstX = secondX
|
||||||
|
firstY = secondY
|
||||||
|
secondX = time
|
||||||
|
secondY = value
|
||||||
|
|
||||||
|
return dy/dx</function>
|
||||||
|
<linked_source>desired lat accel</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="abs(des la accel)">
|
||||||
|
<global></global>
|
||||||
|
<function>return math.abs(value)</function>
|
||||||
|
<linked_source>desired lat accel</linked_source>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="desired lat accel">
|
||||||
|
<global></global>
|
||||||
|
<function>return value * v1^2</function>
|
||||||
|
<linked_source>/controlsState/desiredCurvature</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/vEgo</v1>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="abs(ang_cmd)">
|
||||||
|
<global></global>
|
||||||
|
<function>return math.abs(value)</function>
|
||||||
|
<linked_source>/can/1/LFA_ALT/LKAS_ANGLE_CMD</linked_source>
|
||||||
|
</snippet>
|
||||||
|
</customMathEquations>
|
||||||
|
<snippets/>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
</root>
|
||||||
|
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<root>
|
||||||
|
<tabbed_widget parent="main_window" name="Main Window">
|
||||||
|
<Tab tab_name="tab1" containers="1">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter sizes="0.25;0.25;0.25;0.25" count="4" orientation="-">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
|
||||||
|
<range bottom="-3.582051" right="1431.113121" top="5.314632" left="5.322399"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="Actual lateral accel (roll compensated)" color="#1ac938"/>
|
||||||
|
<curve name="Desired lateral accel (roll compensated)" color="#ff7f0e"/>
|
||||||
|
<curve name="IMU_LatAccelVal_ms^2" color="#f14cc1"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
|
||||||
|
<range bottom="-3.741271" right="1431.113121" top="3.756006" left="5.322399"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="roll compensated lateral acceleration" color="#ff7f0e"/>
|
||||||
|
<curve name="IMU_LatAccelVal_Ms^2" color="#1ac938"/>
|
||||||
|
<curve name="IMU_LatAccelVal_ms^2_roll_compensated" color="#9467bd"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
|
||||||
|
<range bottom="-0.025000" right="1431.113121" top="1.025000" left="5.322399"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carState/steeringPressed" color="#0097ff"/>
|
||||||
|
<curve name="/carOutput/actuatorsOutput/torque" color="#d62728"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
|
||||||
|
<range bottom="-1.660728" right="1431.113121" top="67.942958" left="5.322399"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/carState/vEgo" color="#f14cc1">
|
||||||
|
<transform name="Scale/Offset" alias="/carState/vEgo[Scale/Offset]">
|
||||||
|
<options value_scale="2.23694" time_offset="0" value_offset="0"/>
|
||||||
|
</transform>
|
||||||
|
</curve>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<Tab tab_name="tab2" containers="1">
|
||||||
|
<Container>
|
||||||
|
<DockSplitter sizes="0.5;0.5" count="2" orientation="-">
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
|
||||||
|
<range bottom="30595.900000" right="1431.113121" top="34884.100000" left="5.322399"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/can/1/IMU_01_10ms/IMU_RollRtVal" color="#17becf"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
<DockArea name="...">
|
||||||
|
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
|
||||||
|
<range bottom="-0.058795" right="1431.113121" top="0.072448" left="5.322399"/>
|
||||||
|
<limitY/>
|
||||||
|
<curve name="/liveParameters/roll" color="#bcbd22"/>
|
||||||
|
</plot>
|
||||||
|
</DockArea>
|
||||||
|
</DockSplitter>
|
||||||
|
</Container>
|
||||||
|
</Tab>
|
||||||
|
<currentTabIndex index="1"/>
|
||||||
|
</tabbed_widget>
|
||||||
|
<use_relative_time_offset enabled="1"/>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<Plugins>
|
||||||
|
<plugin ID="DataLoad CSV">
|
||||||
|
<default time_axis="" delimiter="0"/>
|
||||||
|
</plugin>
|
||||||
|
<plugin ID="DataLoad MCAP"/>
|
||||||
|
<plugin ID="DataLoad Rlog"/>
|
||||||
|
<plugin ID="DataLoad ULog"/>
|
||||||
|
<plugin ID="Cereal Subscriber"/>
|
||||||
|
<plugin ID="UDP Server"/>
|
||||||
|
<plugin ID="WebSocket Server"/>
|
||||||
|
<plugin ID="ZMQ Subscriber"/>
|
||||||
|
<plugin ID="Fast Fourier Transform"/>
|
||||||
|
<plugin ID="Quaternion to RPY"/>
|
||||||
|
<plugin ID="Reactive Script Editor">
|
||||||
|
<library code="--[[ Helper function to create a series from arrays

 new_series: a series previously created with ScatterXY.new(name)
 prefix: prefix of the timeseries, before the index of the array
 suffix_X: suffix to complete the name of the series containing the X value. If [nil], use the index of the array.
 suffix_Y: suffix to complete the name of the series containing the Y value
 timestamp: usually the tracker_time variable
 
 Example:
 
 Assuming we have multiple series in the form:
 
 /trajectory/node.{X}/position/x
 /trajectory/node.{X}/position/y
 
 where {N} is the index of the array (integer). We can create a reactive series from the array with:
 
 new_series = ScatterXY.new("my_trajectory") 
 CreateSeriesFromArray( new_series, "/trajectory/node", "position/x", "position/y", tracker_time );
--]]

function CreateSeriesFromArray( new_series, prefix, suffix_X, suffix_Y, timestamp )
 
 --- clear previous values
 new_series:clear()
 
 --- Append points to new_series
 index = 0
 while(true) do

 x = index;
 -- if not nil, get the X coordinate from a series
 if suffix_X ~= nil then 
 series_x = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_X) )
 if series_x == nil then break end
 x = series_x:atTime(timestamp)	 
 end
 
 series_y = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_Y) )
 if series_y == nil then break end 
 y = series_y:atTime(timestamp)
 
 new_series:push_back(x,y)
 index = index+1
 end
end

--[[ Similar to the built-in function GetSeriesNames(), but select only the names with a give prefix. --]]

function GetSeriesNamesByPrefix(prefix)
 -- GetSeriesNames(9 is a built-in function
 all_names = GetSeriesNames()
 filtered_names = {}
 for i, name in ipairs(all_names) do
 -- check the prefix
 if name:find(prefix, 1, #prefix) then
 table.insert(filtered_names, name);
 end
 end
 return filtered_names
end

--[[ Modify an existing series, applying offsets to all their X and Y values

 series: an existing timeseries, obtained with TimeseriesView.find(name)
 delta_x: offset to apply to each x value
 delta_y: offset to apply to each y value 
 
--]]

function ApplyOffsetInPlace(series, delta_x, delta_y)
 -- use C++ indeces, not Lua indeces
 for index=0, series:size()-1 do
 x,y = series:at(index)
 series:set(index, x + delta_x, y + delta_y)
 end
end
"/>
|
||||||
|
<scripts/>
|
||||||
|
</plugin>
|
||||||
|
<plugin ID="CSV Exporter"/>
|
||||||
|
</Plugins>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
<customMathEquations>
|
||||||
|
<snippet name="IMU_LatAccelVal_ms^2">
|
||||||
|
<global></global>
|
||||||
|
<function>return value * -9.8</function>
|
||||||
|
<linked_source>/can/1/IMU_01_10ms/IMU_LatAccelVal</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/latActive</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="roll compensated lateral acceleration">
|
||||||
|
<global></global>
|
||||||
|
<function>if (v3 == 0 and v4 == 1) then
|
||||||
|
return (value * v1 ^ 2) - (v2 * 9.81)
|
||||||
|
end
|
||||||
|
return 0</function>
|
||||||
|
<linked_source>/controlsState/curvature</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/vEgo</v1>
|
||||||
|
<v2>/liveParameters/roll</v2>
|
||||||
|
<v3>/carState/steeringPressed</v3>
|
||||||
|
<v4>/carControl/latActive</v4>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="IMU_LatAccelVal_Ms^2">
|
||||||
|
<global></global>
|
||||||
|
<function>if (v1 == 0 and v2 == 1) then
|
||||||
|
return value * -9.8
|
||||||
|
end
|
||||||
|
return 0</function>
|
||||||
|
<linked_source>/can/1/IMU_01_10ms/IMU_LatAccelVal</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/latActive</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="IMU_LatAccelVal_Ms^3">
|
||||||
|
<global></global>
|
||||||
|
<function>return value * -9.8</function>
|
||||||
|
<linked_source>/can/1/IMU_01_10ms/IMU_LatAccelVal</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/latActive</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="IMU_LatAccelVal_ms^2_roll_compensated">
|
||||||
|
<global></global>
|
||||||
|
<function>
|
||||||
|
|
||||||
|
if (v1 == 0 and v2 == 1) then
|
||||||
|
return (value * -9.8) - (v3 * 9.81)
|
||||||
|
end
|
||||||
|
return 0</function>
|
||||||
|
<linked_source>/can/1/IMU_01_10ms/IMU_LatAccelVal</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/steeringPressed</v1>
|
||||||
|
<v2>/carControl/latActive</v2>
|
||||||
|
<v3>/liveParameters/roll</v3>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="Actual lateral accel (roll compensated)">
|
||||||
|
<global></global>
|
||||||
|
<function>return (value * v1 ^ 2) - (v2 * 9.81)</function>
|
||||||
|
<linked_source>/controlsState/curvature</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/vEgo</v1>
|
||||||
|
<v2>/liveParameters/roll</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
<snippet name="Desired lateral accel (roll compensated)">
|
||||||
|
<global></global>
|
||||||
|
<function>return (value * v1 ^ 2) - (v2 * 9.81)</function>
|
||||||
|
<linked_source>/controlsState/desiredCurvature</linked_source>
|
||||||
|
<additional_sources>
|
||||||
|
<v1>/carState/vEgo</v1>
|
||||||
|
<v2>/liveParameters/roll</v2>
|
||||||
|
</additional_sources>
|
||||||
|
</snippet>
|
||||||
|
</customMathEquations>
|
||||||
|
<snippets/>
|
||||||
|
<!-- - - - - - - - - - - - - - - -->
|
||||||
|
</root>
|
||||||
|
|
||||||
Reference in New Issue
Block a user