mirror of https://github.com/rusefi/bldc.git
1855 lines
95 KiB
QML
1855 lines
95 KiB
QML
import QtQuick 2.7
|
|
import QtQuick.Controls 2.2
|
|
import QtQuick.Layouts 1.3
|
|
import Qt.labs.settings 1.0 as QSettings
|
|
import Vedder.vesc.vescinterface 1.0
|
|
import Vedder.vesc.bleuart 1.0
|
|
import Vedder.vesc.commands 1.0
|
|
import Vedder.vesc.configparams 1.0
|
|
import Vedder.vesc.utility 1.0
|
|
Item {
|
|
id: mainItem
|
|
anchors.fill: parent
|
|
//anchors.margins: 10 //fix this
|
|
property BleUart mBle: VescIf.bleDevice()
|
|
property Commands mCommands: VescIf.commands()
|
|
property var fwVersion: mCommands.getFwVersion()
|
|
property ConfigParams mMcConf: VescIf.mcConfig()
|
|
property ConfigParams mAppConf: VescIf.appConfig()
|
|
property ConfigParams mInfoConf: VescIf.infoConfig()
|
|
property bool isHorizontal: width > height
|
|
property bool scheduleConfWrite: false
|
|
property bool fixedThrottle: false
|
|
property var parentTabBar: parent.tabBarItem
|
|
|
|
Component.onCompleted: {
|
|
parentTabBar.visible = true
|
|
parentTabBar.enabled = true
|
|
readSettings()
|
|
}
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
|
|
TabBar {
|
|
id: tabBar
|
|
currentIndex: swipeView.currentIndex
|
|
Layout.fillWidth: true
|
|
implicitWidth: 0
|
|
clip: true
|
|
property int buttons: 5
|
|
property int buttonWidth: 100
|
|
|
|
TabButton {
|
|
text: qsTr("Ride")
|
|
width: Math.max(tabBar.buttonWidth,tabBar.width / tabBar.buttons)
|
|
}
|
|
TabButton {
|
|
text: qsTr("Tune")
|
|
width: Math.max(tabBar.buttonWidth,tabBar.width / tabBar.buttons)
|
|
}
|
|
TabButton {
|
|
text: qsTr("Bike CFG")
|
|
width: Math.max(tabBar.buttonWidth,tabBar.width / tabBar.buttons)
|
|
}
|
|
TabButton {
|
|
text: qsTr("Logging")
|
|
width: Math.max(tabBar.buttonWidth,tabBar.width / tabBar.buttons)
|
|
}
|
|
TabButton {
|
|
text: qsTr("Firmware")
|
|
width: Math.max(tabBar.buttonWidth,tabBar.width / tabBar.buttons)
|
|
}
|
|
}
|
|
|
|
SwipeView {
|
|
id: swipeView
|
|
currentIndex: tabBar.currentIndex
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
clip: true
|
|
Page {
|
|
RtDataSetup {
|
|
anchors.fill: parent
|
|
updateData: swipeView.currentIndex == 0
|
|
}
|
|
}
|
|
Page {
|
|
background: Rectangle {
|
|
opacity: 0.0
|
|
}
|
|
|
|
ColumnLayout {
|
|
anchors.topMargin: 5
|
|
anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
|
|
TabBar {
|
|
id: profilesBar
|
|
currentIndex: profileSwipeView.currentIndex
|
|
property var lastProfileIndex: currentIndex
|
|
Layout.fillWidth: true
|
|
implicitWidth: 0
|
|
clip: true
|
|
property int buttons: 3
|
|
property int buttonWidth: 100
|
|
|
|
TabButton {
|
|
text: qsTr("Street\nlegal")
|
|
width: Math.max(
|
|
profilesBar.buttonWidth,
|
|
profilesBar.width / profilesBar.buttons)
|
|
}
|
|
TabButton {
|
|
text: qsTr("Trail")
|
|
width: Math.max(
|
|
profilesBar.buttonWidth,
|
|
profilesBar.width / profilesBar.buttons)
|
|
}
|
|
TabButton {
|
|
text: qsTr("Ludicrous")
|
|
width: Math.max(
|
|
profilesBar.buttonWidth,
|
|
profilesBar.width / profilesBar.buttons)
|
|
}
|
|
}
|
|
SwipeView {
|
|
id: profileSwipeView
|
|
currentIndex: profilesBar.currentIndex
|
|
Layout.fillHeight: true
|
|
Layout.fillWidth: true
|
|
clip: true
|
|
interactive: false
|
|
// Street Legal
|
|
Page
|
|
{
|
|
ColumnLayout {
|
|
anchors.topMargin: 5
|
|
anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
|
|
ScrollView {
|
|
clip: true
|
|
contentWidth: parent.width
|
|
Layout.fillHeight: true
|
|
|
|
ColumnLayout {
|
|
anchors.topMargin: 5
|
|
anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
visible: true
|
|
spacing: 5
|
|
|
|
Item {
|
|
// Spacer
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
GroupBox {
|
|
id: streetTorqueBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
// anchors.topMargin: 5
|
|
//anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Throttle\nAmps"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: streetTorqueSlider
|
|
stepSize: 10
|
|
from: 20
|
|
value: 30
|
|
to: 100 //max phase amps
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: streetTorqueSlider.handle
|
|
visible: streetTorqueSlider.pressed
|
|
text: streetTorqueSlider.value.toFixed(1)+" A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: streetPasBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "PAS\nAmps"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: streetPasSlider
|
|
stepSize: 1
|
|
from: 0
|
|
value: 20
|
|
to: streetTorqueSlider.value.toFixed(
|
|
1) //% of phase amps
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: streetPasSlider.handle
|
|
visible: streetPasSlider.pressed
|
|
text: streetPasSlider.value.toFixed(1)+" A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: streetPowerBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Power"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: streetPowerSlider
|
|
stepSize: 250
|
|
from: 0
|
|
value: 500
|
|
to: 2500
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: streetPowerSlider.handle
|
|
visible: streetPowerSlider.pressed
|
|
text: streetPowerSlider.value.toFixed(1)+" W"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: streetSpeedBox
|
|
Layout.fillWidth: true
|
|
visible : false
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Speed\nLimit"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: streetSpeedSlider
|
|
stepSize: 1
|
|
from: 20
|
|
value: 20
|
|
to: 60
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: streetSpeedSlider.handle
|
|
visible: streetSpeedSlider.pressed
|
|
text: streetSpeedSlider.value.toFixed(1) + (VescIf.useImperialUnits() ? " mph":" km/h")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: streetThrottleResponseBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Throttle\nResponse"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: streetThrottleResponseSlider
|
|
stepSize: 0.1
|
|
from: 3
|
|
value: 0.9
|
|
to: 0.3
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: streetThrottleResponseSlider.handle
|
|
visible: streetThrottleResponseSlider.pressed
|
|
text: streetThrottleResponseSlider.value.toFixed(1)+" sec"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: streetThrottleExpoBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Throttle\nLinearity"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: streetThrottleExpoSlider
|
|
stepSize: 1
|
|
from: 0
|
|
value: 100
|
|
to: 100
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: streetThrottleExpoSlider.handle
|
|
visible: streetThrottleExpoSlider.pressed
|
|
text: streetThrottleExpoSlider.value.toFixed(1)+"%"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: streetPasResponseBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "PAS\nResponse"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: streetPasResponseSlider
|
|
stepSize: 0.1
|
|
from: 1.5
|
|
value: 0.8
|
|
to: 0.3
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: streetPasResponseSlider.handle
|
|
visible: streetPasResponseSlider.pressed
|
|
text: streetPasResponseSlider.value.toFixed(1)+" sec"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: streetFWExpoBox
|
|
Layout.fillWidth: true
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Field\nWeakening"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: streetFWSlider
|
|
stepSize: 1
|
|
from: 0
|
|
value: 2
|
|
to: 7
|
|
Layout.fillWidth: true
|
|
ToolTip {
|
|
parent: streetFWSlider.handle
|
|
visible: streetFWSlider.pressed
|
|
text: streetFWSlider.value.toFixed(1)+" A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: streetFixedThrottleBox
|
|
Layout.fillWidth: true
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Fixed Throttle\nAmps"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
CheckBox {
|
|
id: streetFixedThrottleCheckbox
|
|
checked: false
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Trail
|
|
Page {
|
|
ColumnLayout {
|
|
anchors.topMargin: 5
|
|
anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
|
|
ScrollView {
|
|
clip: true
|
|
contentWidth: parent.width
|
|
Layout.fillHeight: true
|
|
|
|
ColumnLayout {
|
|
anchors.topMargin: 5
|
|
anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
|
|
Item {
|
|
// Spacer
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
GroupBox {
|
|
id: trailTorqueBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
// anchors.topMargin: 5
|
|
//anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Throttle\nAmps"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: trailTorqueSlider
|
|
stepSize: 10
|
|
from: 20
|
|
value: 70
|
|
to: 100 //max phase amps
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: trailTorqueSlider.handle
|
|
visible: trailTorqueSlider.pressed
|
|
text: trailTorqueSlider.value.toFixed(1)+" A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: trailPasBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "PAS\nAmps"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: trailPasSlider
|
|
stepSize: 1
|
|
from: 0
|
|
value: 60
|
|
to: trailTorqueSlider.value.toFixed(
|
|
1) //% of phase amps
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: trailPasSlider.handle
|
|
visible: trailPasSlider.pressed
|
|
text: trailPasSlider.value.toFixed(1)+" A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: trailPowerBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Power"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: trailPowerSlider
|
|
stepSize: 250
|
|
from: 0
|
|
value: 2000
|
|
to: 2500
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: trailPowerSlider.handle
|
|
visible: trailPowerSlider.pressed
|
|
text: trailPowerSlider.value.toFixed(1)+" W"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: trailSpeedBox
|
|
Layout.fillWidth: true
|
|
visible : false
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Speed\nLimit"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: trailSpeedSlider
|
|
stepSize: 1
|
|
from: 20
|
|
value: 60
|
|
to: 60
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: trailSpeedSlider.handle
|
|
visible: trailSpeedSlider.pressed
|
|
text: trailSpeedSlider.value.toFixed(1) + (VescIf.useImperialUnits() ? " mph":" km/h")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: trailThrottleResponseBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Throttle\nResponse"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: trailThrottleResponseSlider
|
|
stepSize: 0.1
|
|
from: 3
|
|
value: 0.4
|
|
to: 0.3
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: trailThrottleResponseSlider.handle
|
|
visible: trailThrottleResponseSlider.pressed
|
|
text: trailThrottleResponseSlider.value.toFixed(1)+" sec"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: trailThrottleExpoBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Throttle\nLinearity"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: trailThrottleExpoSlider
|
|
stepSize: 1
|
|
from: 0
|
|
value: 100
|
|
to: 100
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: trailThrottleExpoSlider.handle
|
|
visible: trailThrottleExpoSlider.pressed
|
|
text: trailThrottleExpoSlider.value.toFixed(1)+"%"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: trailPasResponseBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "PAS\nResponse"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: trailPasResponseSlider
|
|
stepSize: 0.1
|
|
from: 1.5
|
|
value: 0.6
|
|
to: 0.3
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: trailPasResponseSlider.handle
|
|
visible: trailPasResponseSlider.pressed
|
|
text: trailPasResponseSlider.value.toFixed(1)+" sec"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: trailFWExpoBox
|
|
Layout.fillWidth: true
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Field\nWeakening"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: trailFWSlider
|
|
stepSize: 1
|
|
from: 0
|
|
value: 7
|
|
to: 7
|
|
Layout.fillWidth: true
|
|
ToolTip {
|
|
parent: trailFWSlider.handle
|
|
visible: trailFWSlider.pressed
|
|
text: trailFWSlider.value.toFixed(1)+" A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: trailFixedThrottleBox
|
|
Layout.fillWidth: true
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Fixed Throttle\nAmps"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
CheckBox {
|
|
id: trailFixedThrottleCheckbox
|
|
checked: false
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ludicrous
|
|
Page {
|
|
ColumnLayout {
|
|
anchors.topMargin: 5
|
|
anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
|
|
ScrollView {
|
|
clip: true
|
|
contentWidth: parent.width
|
|
Layout.fillHeight: true
|
|
|
|
ColumnLayout {
|
|
anchors.topMargin: 5
|
|
anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
|
|
Item {
|
|
// Spacer
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
GroupBox {
|
|
id: torqueBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
// anchors.topMargin: 5
|
|
//anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Throttle\nAmps"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: torqueSlider
|
|
stepSize: 10
|
|
from: 20
|
|
value: 100
|
|
to: 100 //max phase amps
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: torqueSlider.handle
|
|
visible: torqueSlider.pressed
|
|
text: torqueSlider.value.toFixed(1)+" A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: pasBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "PAS\nAmps"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: pasSlider
|
|
stepSize: 1
|
|
from: 0
|
|
value: 90
|
|
to: torqueSlider.value.toFixed(
|
|
1) //% of phase amps
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: pasSlider.handle
|
|
visible: pasSlider.pressed
|
|
text: pasSlider.value.toFixed(1)+" A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: powerBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Power"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: powerSlider
|
|
stepSize: 250
|
|
from: 0
|
|
value: 2500
|
|
to: 2500
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: powerSlider.handle
|
|
visible: powerSlider.pressed
|
|
text: powerSlider.value.toFixed(1)+" W"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: speedBox
|
|
Layout.fillWidth: true
|
|
visible : false
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Speed\nLimit"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: speedSlider
|
|
stepSize: 1
|
|
from: 20
|
|
value: 60
|
|
to: 60
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: speedSlider.handle
|
|
visible: speedSlider.pressed
|
|
text: speedSlider.value.toFixed(1) + (VescIf.useImperialUnits() ? " mph":" km/h")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: throttleResponseBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Throttle\nResponse"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: throttleResponseSlider
|
|
stepSize: 0.1
|
|
from: 3
|
|
value: 0.3
|
|
to: 0.3
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: throttleResponseSlider.handle
|
|
visible: throttleResponseSlider.pressed
|
|
text: throttleResponseSlider.value.toFixed(1)+" sec"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: throttleExpoBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Throttle\nLinearity"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: throttleExpoSlider
|
|
stepSize: 1
|
|
from: 0
|
|
value: 95
|
|
to: 100
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: throttleExpoSlider.handle
|
|
visible: throttleExpoSlider.pressed
|
|
text: throttleExpoSlider.value.toFixed(1)+"%"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: pasResponseBox
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "PAS\nResponse"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: pasResponseSlider
|
|
stepSize: 0.1
|
|
from: 1.5
|
|
value: 0.3
|
|
to: 0.3
|
|
Layout.fillWidth: true
|
|
|
|
ToolTip {
|
|
parent: pasResponseSlider.handle
|
|
visible: pasResponseSlider.pressed
|
|
text: pasResponseSlider.value.toFixed(1)+" sec"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: fWExpoBox
|
|
Layout.fillWidth: true
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Field\nWeakening"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
Slider {
|
|
id: fWSlider
|
|
stepSize: 1
|
|
from: 0
|
|
value: 7
|
|
to: 7
|
|
Layout.fillWidth: true
|
|
ToolTip {
|
|
parent: fWSlider.handle
|
|
visible: fWSlider.pressed
|
|
text: fWSlider.value.toFixed(1)+" A"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: fixedThrottleBox
|
|
Layout.fillWidth: true
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
clip: false
|
|
spacing: 5
|
|
Text {
|
|
text: "Fixed Throttle\nAmps"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
CheckBox {
|
|
id: fixedThrottleCheckbox
|
|
checked: false
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
RowLayout {
|
|
id: profilesRow
|
|
clip: false
|
|
visible: true
|
|
spacing: 5
|
|
|
|
Button {
|
|
text: "Read\nSettings"
|
|
Layout.columnSpan: 2
|
|
Layout.preferredWidth: 200
|
|
Layout.preferredHeight: 80
|
|
Layout.fillWidth: true
|
|
onClicked: {
|
|
readSettings()
|
|
}
|
|
}
|
|
Button {
|
|
id: tuneWriteSettingsButton
|
|
text: "Write\nSettings"
|
|
Layout.columnSpan: 2
|
|
Layout.preferredWidth: 200
|
|
Layout.preferredHeight: 80
|
|
Layout.fillWidth: true
|
|
onClicked: {
|
|
writeSettings()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Page {
|
|
background: Rectangle {
|
|
opacity: 0.0
|
|
}
|
|
|
|
ColumnLayout {
|
|
anchors.topMargin: 5
|
|
anchors.bottomMargin: 1
|
|
anchors.fill: parent
|
|
|
|
ScrollView {
|
|
clip: true
|
|
contentWidth: parent.width
|
|
Layout.fillHeight: true
|
|
GridLayout {
|
|
id: grid2
|
|
anchors.fill: parent
|
|
columns: 1
|
|
columnSpacing: 5
|
|
rowSpacing: 10
|
|
GroupBox {
|
|
id: battSelectorBox
|
|
title: qsTr("Battery Presets")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 10
|
|
|
|
Button {
|
|
id: wolfButton
|
|
text: "LUNA X2\n48V"
|
|
Layout.columnSpan: 2
|
|
Layout.preferredWidth: 200
|
|
Layout.preferredHeight: 70
|
|
Layout.fillWidth: true
|
|
|
|
onClicked: {
|
|
battCurrBox.realValue = 60.0
|
|
battCellsBox.realValue = 13
|
|
battOvervoltageBox.realValue = 60.0
|
|
battUndervoltageStartBox.realValue = 40
|
|
battUndervoltageEndBox.realValue = 39
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "LUNA X2.5\n60V"
|
|
Layout.columnSpan: 2
|
|
Layout.preferredWidth: 200
|
|
Layout.preferredHeight: 70
|
|
Layout.fillWidth: true
|
|
onClicked: {
|
|
battCurrBox.realValue = 50.0
|
|
battCellsBox.realValue = 16
|
|
battOvervoltageBox.realValue = 72.0
|
|
battUndervoltageStartBox.realValue = 49.0
|
|
battUndervoltageEndBox.realValue = 48.0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: battCurrentBox
|
|
title: qsTr("Battery")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 0
|
|
|
|
Text {
|
|
text: "Current\nMax"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
|
|
DoubleSpinBox {
|
|
id: battCurrBox
|
|
Layout.fillWidth: true
|
|
decimals: 2
|
|
realValue: 60.0
|
|
realFrom: 0.0
|
|
realTo: 60.0
|
|
prefix: "I: "
|
|
suffix: " A"
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: batt8Box
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 0
|
|
Text {
|
|
text: "Cells"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
DoubleSpinBox {
|
|
id: battCellsBox
|
|
Layout.fillWidth: true
|
|
decimals: 0
|
|
realValue: 13.0
|
|
realFrom: 13.0
|
|
realTo: 20.0
|
|
suffix: "s"
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: battBox
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 0
|
|
|
|
Text {
|
|
text: "Overvoltage"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
|
|
DoubleSpinBox {
|
|
id: battOvervoltageBox
|
|
Layout.fillWidth: true
|
|
decimals: 2
|
|
realValue: 55.0
|
|
realFrom: 0.0
|
|
realTo: 86.0
|
|
prefix: "V: "
|
|
suffix: " V"
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: batt2Box
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 0
|
|
|
|
Text {
|
|
text: "Undervoltage\nCutoff Start"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
|
|
DoubleSpinBox {
|
|
id: battUndervoltageStartBox
|
|
Layout.fillWidth: true
|
|
decimals: 2
|
|
realValue: 40.0
|
|
realFrom: 0.0
|
|
realTo: 86.0
|
|
prefix: "V: "
|
|
suffix: " V"
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
id: batt3Box
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 0
|
|
|
|
Text {
|
|
text: "Undervoltage\nCutoff End"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
|
|
DoubleSpinBox {
|
|
id: battUndervoltageEndBox
|
|
Layout.fillWidth: true
|
|
decimals: 2
|
|
realValue: 39.0
|
|
realFrom: 0.0
|
|
realTo: 86.0
|
|
prefix: "V: "
|
|
suffix: " V"
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: batt4Box
|
|
title: qsTr("Speedo")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 0
|
|
|
|
Text {
|
|
text: "Wheel\nSize"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
|
|
ComboBox {
|
|
id: wheelDiameterBox
|
|
textRole: "text"
|
|
currentIndex: 1
|
|
model: ListModel {
|
|
id: wheelDiameterModel
|
|
ListElement{text:"26\"";value:0.676}
|
|
ListElement{text:"27.5\"";value:0.714}
|
|
ListElement{text:"29\"";value:0.752}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
id: encoderBox
|
|
title: qsTr("Encoder")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 0
|
|
|
|
Button {
|
|
id: encoderOffsetButton
|
|
text: "Offset\ncorrection"
|
|
Layout.preferredHeight: 70
|
|
Layout.preferredWidth: 120
|
|
onClicked: {
|
|
m600detectDialog.open()
|
|
}
|
|
}
|
|
|
|
DoubleSpinBox {
|
|
id: encoderOffsetBox
|
|
Layout.fillWidth: true
|
|
decimals: 1
|
|
realValue: 0.0
|
|
realFrom: 0.0
|
|
realTo: 460.0
|
|
suffix: "°"
|
|
}
|
|
}
|
|
}
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 0
|
|
|
|
Text {
|
|
text: "Invert Motor\nDirection"
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
horizontalAlignment: Text.AlignHCenter
|
|
Layout.minimumWidth: 100
|
|
}
|
|
|
|
Switch {
|
|
id: motorDirectionBox
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
// Spacer
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
}
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
id: bikeCfgRow
|
|
clip: false
|
|
visible: true
|
|
spacing: 5
|
|
|
|
Button {
|
|
text: "Read\nSettings"
|
|
Layout.columnSpan: 2
|
|
Layout.preferredWidth: 200
|
|
Layout.preferredHeight: 80
|
|
Layout.fillWidth: true
|
|
onClicked: {
|
|
readSettings()
|
|
}
|
|
}
|
|
Button {
|
|
id: bikeWriteSettingsButton
|
|
text: "Write\nSettings"
|
|
Layout.columnSpan: 2
|
|
Layout.preferredWidth: 200
|
|
Layout.preferredHeight: 80
|
|
Layout.fillWidth: true
|
|
onClicked: {
|
|
writeSettings()
|
|
bikeWriteSettingsButton.background.color = Utility.getAppHexColor("lightBackground");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Logging
|
|
Page {
|
|
background: Rectangle {
|
|
opacity: 0.0
|
|
}
|
|
|
|
ScrollView {
|
|
clip: true
|
|
contentWidth: parent.width
|
|
Layout.fillHeight: true
|
|
GridLayout {
|
|
id: gridLog
|
|
anchors.fill: parent
|
|
columns: 1
|
|
columnSpacing: 5
|
|
rowSpacing: 10
|
|
|
|
GroupBox {
|
|
id: batt6Box
|
|
title: "Data Logging"
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
|
|
Switch {
|
|
id: rtLogEnBox
|
|
text: "Enable Data Logging"
|
|
anchors.centerIn: parent
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
|
|
onClicked: {
|
|
if (checked) {
|
|
if (VescIf.openRtLogFile(
|
|
rtLogFileText.text)) {
|
|
Utility.startGnssForegroundService()
|
|
VescIf.setWakeLock(true)
|
|
}
|
|
} else {
|
|
VescIf.closeRtLogFile()
|
|
Utility.stopGnssForegroundService()
|
|
|
|
if (!VescIf.useWakeLock()) {
|
|
VescIf.setWakeLock(false)
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
repeat: true
|
|
running: true
|
|
interval: 500
|
|
onTriggered: {
|
|
if (rtLogEnBox.checked
|
|
&& !VescIf.isRtLogOpen()) {
|
|
Utility.stopGnssForegroundService()
|
|
if (!VescIf.useWakeLock()) {
|
|
VescIf.setWakeLock(false)
|
|
}
|
|
}
|
|
rtLogEnBox.checked = VescIf.isRtLogOpen()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 1
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 5
|
|
|
|
Button {
|
|
text: "Choose Log\nDirectory..."
|
|
Layout.preferredHeight: 70
|
|
|
|
Layout.preferredWidth: 120
|
|
onClicked: {
|
|
if (Utility.requestFilePermission()) {
|
|
logFilePicker.enabled = true
|
|
logFilePicker.visible = true
|
|
} else {
|
|
VescIf.emitMessageDialog("File Permissions","Unable to request file system permission.",false,false)
|
|
}
|
|
}
|
|
}
|
|
|
|
TextInput {
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
id: rtLogFileText
|
|
font.pointSize: 12
|
|
text: "./log"
|
|
|
|
QSettings.Settings {
|
|
property alias rtLog: rtLogFileText.text
|
|
property alias rtLogEnable: rtLogEnBox.checked
|
|
property alias m600profileIndex: profilesBar.currentIndex
|
|
|
|
property alias m600streetTorque: streetTorqueSlider.value
|
|
property alias m600streetPas: streetPasSlider.value
|
|
property alias m600streetPower: streetPowerSlider.value
|
|
property alias m600streetSpeed: streetSpeedSlider.value
|
|
property alias m600streetThrottleResponse: streetThrottleResponseSlider.value
|
|
property alias m600streetThrottleExpo: streetThrottleExpoSlider.value
|
|
property alias m600streetPasResponseSlider: streetPasResponseSlider.value
|
|
property alias m600streetFW: streetFWSlider.value
|
|
property alias m600streetFixedThrottle: streetFixedThrottleCheckbox.checked
|
|
|
|
property alias m600trailTorque: trailTorqueSlider.value
|
|
property alias m600trailPas: trailPasSlider.value
|
|
property alias m600trailPower: trailPowerSlider.value
|
|
property alias m600trailSpeed: trailSpeedSlider.value
|
|
property alias m600trailThrottleResponse: trailThrottleResponseSlider.value
|
|
property alias m600trailThrottleExpo: trailThrottleExpoSlider.value
|
|
property alias m600trailPasResponseSlider: streetPasResponseSlider.value
|
|
property alias m600trailFW: trailFWSlider.value
|
|
property alias m600trailFixedThrottle: trailFixedThrottleCheckbox.checked
|
|
|
|
property alias m600ludiTorque: torqueSlider.value
|
|
property alias m600ludiPas: pasSlider.value
|
|
property alias m600ludiPower: powerSlider.value
|
|
property alias m600ludiSpeed: speedSlider.value
|
|
property alias m600ludiThrottleResponse: throttleResponseSlider.value
|
|
property alias m600ludiThrottleExpo: throttleExpoSlider.value
|
|
property alias m600ludiPasResponseSlider: pasResponseSlider.value
|
|
property alias m600ludiFW: fWSlider.value
|
|
property alias m600ludiFixedThrottle: fixedThrottleCheckbox.checked
|
|
|
|
property alias m600battCurrentMaxSetting: battCurrBox.realValue
|
|
property alias m600battCellseSetting: battCellsBox.realValue
|
|
property alias m600overVoltageSetting: battOvervoltageBox.realValue
|
|
property alias m600underVoltageStartSetting: battUndervoltageStartBox.realValue
|
|
property alias m600underVoltageEndSetting: battUndervoltageEndBox.realValue
|
|
property alias m600wheelDiameterSetting: wheelDiameterBox.currentIndex
|
|
property alias m600encoderOffsetSetting: encoderOffsetBox.realValue
|
|
property alias m600motorDirectionSetting: motorDirectionBox.position
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
DirectoryPicker {
|
|
id: logFilePicker
|
|
anchors.fill: parent
|
|
showDotAndDotDot: true
|
|
visible: false
|
|
enabled: false
|
|
|
|
onDirSelected: {
|
|
rtLogFileText.text = fileName
|
|
}
|
|
}
|
|
}
|
|
|
|
// FW update
|
|
Page {
|
|
background: Rectangle {
|
|
opacity: 0.0
|
|
}
|
|
|
|
FwUpdate {
|
|
anchors.fill: parent
|
|
showUploadAllButton: false
|
|
}
|
|
}
|
|
// Support
|
|
}
|
|
}
|
|
|
|
function readSettings() {
|
|
mCommands.getMcconf()
|
|
mCommands.getAppConf()
|
|
|
|
var useImperial = VescIf.useImperialUnits()
|
|
var impFact = useImperial?1.60934:1.0
|
|
|
|
var power = mMcConf.getParamDouble("l_watt_max")
|
|
var torque = mMcConf.getParamDouble("l_current_max")
|
|
var speed = -mMcConf.getParamDouble("l_min_erpm") / impFact
|
|
var pas = mAppConf.getParamDouble("app_pas_conf.current_scaling") * torque
|
|
var throttleResponse = mAppConf.getParamDouble("app_adc_conf.ramp_time_pos")
|
|
var pasResponse = mAppConf.getParamDouble("app_pas_conf.ramp_time_pos")
|
|
var throttleExpo = 100.0-(mAppConf.getParamDouble("app_adc_conf.throttle_exp")) * -20.0
|
|
var battCurr = mMcConf.getParamDouble("l_in_current_max")
|
|
var battOvervoltage = mMcConf.getParamDouble("l_max_vin")
|
|
var battUndervoltageStart = mMcConf.getParamDouble("l_battery_cut_start")
|
|
var battUndervoltageEnd = mMcConf.getParamDouble("l_battery_cut_end")
|
|
var battCells = mMcConf.getParamInt("si_battery_cells")
|
|
var encoderOffset = mMcConf.getParamDouble("foc_encoder_offset")
|
|
var fieldWeak = mMcConf.getParamDouble("foc_fw_current_max")
|
|
var fixedThrottle
|
|
var motorDirection = mMcConf.getParamBool("m_invert_direction")
|
|
|
|
if ((power == streetPowerSlider.value) && (torque == streetTorqueSlider.value)) {
|
|
profilesBar.setCurrentIndex(0)
|
|
streetTorqueSlider.value = torque
|
|
streetPowerSlider.value = power
|
|
streetSpeedSlider.value = speed
|
|
streetPasSlider.value = pas
|
|
streetThrottleResponseSlider.value = throttleResponse
|
|
streetPasResponseSlider.value = pasResponse
|
|
streetFWSlider.value = fieldWeak
|
|
streetThrottleExpoSlider.value = throttleExpo
|
|
}
|
|
if ((power == trailPowerSlider.value) && (torque == trailTorqueSlider.value)) {
|
|
profilesBar.setCurrentIndex(1)
|
|
trailTorqueSlider.value = torque
|
|
trailPowerSlider.value = power
|
|
trailSpeedSlider.value = speed
|
|
trailPasSlider.value = pas
|
|
trailThrottleResponseSlider.value = throttleResponse
|
|
trailPasResponseSlider.value = pasResponse
|
|
trailFWSlider.value = fieldWeak
|
|
trailThrottleExpoSlider.value = throttleExpo
|
|
}
|
|
if ((power == powerSlider.value) && (torque == torqueSlider.value)) {
|
|
profilesBar.setCurrentIndex(2)
|
|
torqueSlider.value = torque
|
|
powerSlider.value = power
|
|
speedSlider.value = speed
|
|
pasSlider.value = pas
|
|
throttleResponseSlider.value = throttleResponse
|
|
pasResponseSlider.value = pasResponse
|
|
fWSlider.value = fieldWeak
|
|
throttleExpoSlider.value = throttleExpo
|
|
}
|
|
battCurrBox.realValue = mMcConf.getParamDouble("l_in_current_max")
|
|
battCellsBox.realValue = mMcConf.getParamInt("si_battery_cells")
|
|
battOvervoltageBox.realValue = mMcConf.getParamDouble("l_max_vin")
|
|
battUndervoltageStartBox.realValue = mMcConf.getParamDouble("l_battery_cut_start")
|
|
battUndervoltageEndBox.realValue = mMcConf.getParamDouble("l_battery_cut_end")
|
|
motorDirectionBox.position = mMcConf.getParamBool("m_invert_direction")
|
|
if(mMcConf.getParamDouble("si_wheel_diameter") <= 0.7){wheelDiameterBox.currentIndex=0}
|
|
if(mMcConf.getParamDouble("si_wheel_diameter") >= 0.7){wheelDiameterBox.currentIndex=1}
|
|
if(mMcConf.getParamDouble("si_wheel_diameter") >= 0.75){wheelDiameterBox.currentIndex=2}
|
|
if(encoderOffset >= 360.1) {
|
|
encoderOffsetBox.realValue = 0.0
|
|
encoderOffsetBox.prefix ="ERROR ("
|
|
encoderOffsetBox.suffix ="°)"
|
|
tabBar.currentIndex = 2
|
|
encoderOffsetButton.background.color = "#ff9595";
|
|
VescIf.emitMessageDialog("Offset Calibration Required","Go to BIKE CFG tab, run Offset Calibration and then Write Settings.\n\nLet the rear wheel rotate freely during calibration.",false, false)
|
|
} else {
|
|
encoderOffsetBox.realValue = encoderOffset
|
|
encoderOffsetBox.prefix =""
|
|
encoderOffsetBox.suffix ="°"
|
|
encoderOffsetButton.background.color = Utility.getAppHexColor("lightBackground");
|
|
}
|
|
}
|
|
|
|
function writeSettings() {
|
|
var useImperial = VescIf.useImperialUnits()
|
|
var impFact = useImperial ? 1.60934 : 1.0
|
|
|
|
if(profilesBar.currentIndex == 0) {
|
|
mMcConf.updateParamDouble("l_current_max", streetTorqueSlider.value)
|
|
mMcConf.updateParamDouble("l_watt_max", streetPowerSlider.value)
|
|
//mMcConf.updateParamDouble("l_min_erpm", -streetSpeedSlider.value * impFact)
|
|
mMcConf.updateParamDouble("foc_fw_current_max", streetFWSlider.value)
|
|
mAppConf.updateParamDouble("app_pas_conf.current_scaling", streetPasSlider.value / streetTorqueSlider.value)
|
|
mAppConf.updateParamDouble("app_adc_conf.ramp_time_pos", streetThrottleResponseSlider.value)
|
|
mAppConf.updateParamDouble("app_pas_conf.ramp_time_pos", streetPasResponseSlider.value)
|
|
mAppConf.updateParamDouble("app_pas_conf.ramp_time_neg", streetPasResponseSlider.value / 2)
|
|
mAppConf.updateParamDouble("app_adc_conf.throttle_exp", (100.0 - streetThrottleExpoSlider.value) / -20.0)
|
|
fixedThrottle = streetFixedThrottleCheckbox.checked
|
|
}
|
|
if(profilesBar.currentIndex == 1) {
|
|
mMcConf.updateParamDouble("l_current_max", trailTorqueSlider.value)
|
|
mMcConf.updateParamDouble("l_watt_max", trailPowerSlider.value)
|
|
//mMcConf.updateParamDouble("l_min_erpm", -trailSpeedSlider.value * impFact)
|
|
mMcConf.updateParamDouble("foc_fw_current_max", trailFWSlider.value)
|
|
mAppConf.updateParamDouble("app_pas_conf.current_scaling", trailPasSlider.value / trailTorqueSlider.value)
|
|
mAppConf.updateParamDouble("app_adc_conf.ramp_time_pos", trailThrottleResponseSlider.value)
|
|
mAppConf.updateParamDouble("app_pas_conf.ramp_time_pos", trailPasResponseSlider.value)
|
|
mAppConf.updateParamDouble("app_pas_conf.ramp_time_neg", trailPasResponseSlider.value / 2)
|
|
mAppConf.updateParamDouble("app_adc_conf.throttle_exp", (100.0 - trailThrottleExpoSlider.value) / -20.0)
|
|
fixedThrottle = trailFixedThrottleCheckbox.checked
|
|
}
|
|
if(profilesBar.currentIndex == 2) {
|
|
mMcConf.updateParamDouble("l_current_max", torqueSlider.value)
|
|
mMcConf.updateParamDouble("l_watt_max", powerSlider.value)
|
|
//mMcConf.updateParamDouble("l_min_erpm", -speedSlider.value * impFact)
|
|
mMcConf.updateParamDouble("foc_fw_current_max", fWSlider.value)
|
|
mAppConf.updateParamDouble("app_pas_conf.current_scaling", pasSlider.value / torqueSlider.value)
|
|
mAppConf.updateParamDouble("app_adc_conf.ramp_time_pos", throttleResponseSlider.value)
|
|
mAppConf.updateParamDouble("app_pas_conf.ramp_time_pos", pasResponseSlider.value)
|
|
mAppConf.updateParamDouble("app_pas_conf.ramp_time_neg", pasResponseSlider.value / 8 + 0.15)
|
|
mAppConf.updateParamDouble("app_adc_conf.throttle_exp", (100.0 - throttleExpoSlider.value) / -20.0)
|
|
fixedThrottle = fixedThrottleCheckbox.checked
|
|
}
|
|
mMcConf.updateParamDouble("l_in_current_max", battCurrBox.realValue)
|
|
mMcConf.updateParamInt("si_battery_cells", battCellsBox.realValue)
|
|
mMcConf.updateParamDouble("l_max_vin",battOvervoltageBox.realValue)
|
|
mMcConf.updateParamDouble("l_battery_cut_start",battUndervoltageStartBox.realValue)
|
|
mMcConf.updateParamDouble("l_battery_cut_end",battUndervoltageEndBox.realValue)
|
|
mMcConf.updateParamDouble("si_wheel_diameter",wheelDiameterModel.get(wheelDiameterBox.currentIndex).value)
|
|
mMcConf.updateParamDouble("foc_encoder_offset",encoderOffsetBox.realValue)
|
|
mMcConf.updateParamBool("m_invert_direction", motorDirectionBox.position)
|
|
scheduleConfWrite = true
|
|
}
|
|
|
|
Connections {
|
|
target: mMcConf
|
|
function onUpdated() {
|
|
confTimer.mcConfRx = true
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: mAppConf
|
|
function onUpdated() {
|
|
confTimer.appConfRx = true
|
|
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: statusTimer
|
|
interval: 1600
|
|
running: false
|
|
repeat: false
|
|
onTriggered: {
|
|
connectedText.text = VescIf.getConnectedPortName()
|
|
connectedRect.color = "#4f4f4f"
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: uiTimer
|
|
interval: 1000
|
|
running: true
|
|
repeat: true
|
|
onTriggered: {
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: confTimer
|
|
interval: 1000
|
|
running: true
|
|
repeat: true
|
|
|
|
property bool mcConfRx: false
|
|
property bool appConfRx: false
|
|
property int writingStage: 0
|
|
|
|
onTriggered: {
|
|
VescIf.setSpeedGaugeUseNegativeValues(false)
|
|
if(tabBar.currentIndex !== 3) {
|
|
if (VescIf.isPortConnected() && VescIf.getLastFwRxParams().hwTypeStr() === "VESC") {
|
|
if(scheduleConfWrite) {
|
|
if(writingStage === 0) {
|
|
mCommands.setMcconf(true)
|
|
writingStage = 1
|
|
} else {
|
|
if(writingStage === 1) {
|
|
mCommands.getMcconf()
|
|
writingStage = 2
|
|
} else {
|
|
if(writingStage === 2) {
|
|
mCommands.setAppConf(true)
|
|
writingStage = 3
|
|
} else {
|
|
if(fixedThrottle) {
|
|
mCommands.sendTerminalCmd("fix_throttle 1")
|
|
} else {
|
|
mCommands.sendTerminalCmd("fix_throttle 0")
|
|
}
|
|
writingStage = 0
|
|
scheduleConfWrite = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!mcConfRx) {
|
|
mCommands.getMcconf()
|
|
}
|
|
if (!appConfRx) {
|
|
mCommands.getAppConf()
|
|
}
|
|
}
|
|
}
|
|
timeText.text=Qt.formatTime(new Date(),"hh:mm")
|
|
}
|
|
}
|
|
Timer {
|
|
id: rtTimer
|
|
interval: 50
|
|
running: true
|
|
repeat: true
|
|
onTriggered: {
|
|
if (VescIf.isPortConnected()) {
|
|
if (VescIf.isRtLogOpen()) {
|
|
interval = 50
|
|
mCommands.getValues()
|
|
mCommands.getValuesSetup()
|
|
} else {
|
|
if (tabBar.currentIndex == 0) {
|
|
interval = 50
|
|
mCommands.getValuesSetup()
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Dialog {
|
|
id: m600detectDialog
|
|
standardButtons: Dialog.Ok | Dialog.Cancel
|
|
modal: true
|
|
focus: true
|
|
closePolicy: Popup.CloseOnEscape
|
|
title: "Detect Magnetic Encoder Offset"
|
|
x:10
|
|
y:Math.max((parent.height-height)/2,10)
|
|
parent: ApplicationWindow.overlay
|
|
width: parent.width - 20
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: 10
|
|
spacing: 10
|
|
Text {
|
|
id: detectLambdaLabel
|
|
color:{color=Utility.getAppHexColor("lightText")}
|
|
verticalAlignment: Text.AlignVCenter
|
|
Layout.fillWidth: true
|
|
wrapMode: Text.WordWrap
|
|
text:
|
|
"This will turn the motor slowly. Lift the rear wheel and make " +
|
|
"sure that nothing is in the way.\nAfter detection, write the settings and powercycle the controller"
|
|
}
|
|
}
|
|
|
|
onAccepted: {
|
|
mCommands.measureEncoder(15.0)
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: mCommands
|
|
|
|
function onEncoderParamReceived(res) {
|
|
VescIf.emitStatusMessage("Encoder Result Received", true)
|
|
encoderOffsetBox.realValue = res.offset
|
|
encoderOffsetBox.prefix =""
|
|
encoderOffsetBox.suffix ="°"
|
|
encoderOffsetBox.decimals = 1
|
|
encoderOffsetButton.background.color = Utility.getAppHexColor("lightBackground");
|
|
bikeWriteSettingsButton.background.color = "#ff9595";
|
|
}
|
|
}
|
|
}
|