PID contrllers settings page was added

This commit is contained in:
2024-03-08 23:07:18 +07:00
parent c8abfd94c3
commit 027116e18e
4 changed files with 92 additions and 42 deletions

View File

@@ -18,6 +18,7 @@ import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -30,12 +31,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size import androidx.compose.ui.geometry.Size
import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize import androidx.compose.ui.unit.toSize
import com.helible.pilot.R
import com.helible.pilot.components.BlankPage import com.helible.pilot.components.BlankPage
import com.helible.pilot.dataclasses.DeviceState import com.helible.pilot.dataclasses.DeviceState
import com.helible.pilot.dataclasses.DeviceStatus import com.helible.pilot.dataclasses.DeviceStatus
@@ -55,8 +58,9 @@ fun PidSettingsPage(
var pValue by remember { mutableStateOf("") } var pValue by remember { mutableStateOf("") }
var iValue by remember { mutableStateOf("") } var iValue by remember { mutableStateOf("") }
var dValue by remember { mutableStateOf("") } var dValue by remember { mutableStateOf("") }
var selectedRegulator by remember { mutableStateOf(1) } var selectedRegulator by remember { mutableStateOf("") }
val dropdownMenuItems = listOf("PID 1", "PID 2", "PID 3") val dropdownMenuItems =
listOf("Контроллер высоты", "Контроллер крена", "Контроллер рысканья")
LaunchedEffect(null) { LaunchedEffect(null) {
requestPidSettings() requestPidSettings()
@@ -64,21 +68,23 @@ fun PidSettingsPage(
LaunchedEffect(deviceState?.pidSettings) { LaunchedEffect(deviceState?.pidSettings) {
if (deviceState?.pidSettings != null) { if (deviceState?.pidSettings != null) {
val pidSettings = deviceState.pidSettings val pidSettings = deviceState.pidSettings
when(selectedRegulator){ when (selectedRegulator) {
1 -> { dropdownMenuItems[0] -> {
pidSettings.p1.p.toString().also { pValue = it } pidSettings.heightControllerParams.p.toString().also { pValue = it }
pidSettings.p1.i.toString().also { iValue = it } pidSettings.heightControllerParams.i.toString().also { iValue = it }
pidSettings.p1.d.toString().also { dValue = it } pidSettings.heightControllerParams.d.toString().also { dValue = it }
} }
2 -> {
pidSettings.p2.p.toString().also { pValue = it } dropdownMenuItems[1] -> {
pidSettings.p2.i.toString().also { iValue = it } pidSettings.yawControllerParams.p.toString().also { pValue = it }
pidSettings.p2.d.toString().also { dValue = it } pidSettings.yawControllerParams.i.toString().also { iValue = it }
pidSettings.yawControllerParams.d.toString().also { dValue = it }
} }
3 -> {
pidSettings.p3.p.toString().also { pValue = it } dropdownMenuItems[2] -> {
pidSettings.p3.i.toString().also { iValue = it } pidSettings.pitchControllerParams.p.toString().also { pValue = it }
pidSettings.p3.d.toString().also { dValue = it } pidSettings.pitchControllerParams.i.toString().also { iValue = it }
pidSettings.pitchControllerParams.d.toString().also { dValue = it }
} }
} }
} }
@@ -87,7 +93,6 @@ fun PidSettingsPage(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(10.dp)
) )
{ {
if (deviceState?.status != DeviceStatus.Idle) { if (deviceState?.status != DeviceStatus.Idle) {
@@ -96,13 +101,32 @@ fun PidSettingsPage(
textAlign = TextAlign.Center textAlign = TextAlign.Center
) )
} else if (deviceState.pidSettings == null) { } else if (deviceState.pidSettings == null) {
Column { CircularProgressIndicator(modifier = Modifier.padding(10.dp))
CircularProgressIndicator(modifier = Modifier.padding(10.dp)) Text(text = "Синхронизация...")
Text(text = "Синхронизация...")
}
} else { } else {
val pidSettings = deviceState.pidSettings val pidSettings = deviceState.pidSettings
Column(modifier = Modifier.padding(horizontal = 10.dp).padding(bottom = 10.dp)) {
Text(
"Рекомендации по настройке ПИД регуляторов",
style = MaterialTheme.typography.titleMedium,
modifier = Modifier
.padding(vertical = 10.dp)
)
Text(
text = LocalContext.current.getString(R.string.p_pid_value_description),
style = MaterialTheme.typography.bodyMedium
)
Text(
text = LocalContext.current.getString(R.string.i_pid_value_description),
style = MaterialTheme.typography.bodyMedium
)
Text(
text = LocalContext.current.getString(R.string.d_pid_value_description),
style = MaterialTheme.typography.bodyMedium
)
}
OutlinedDropdownMenu( OutlinedDropdownMenu(
label = "ПИД регулятор", label = "ПИД регулятор",
suggestions = dropdownMenuItems, suggestions = dropdownMenuItems,
@@ -110,22 +134,24 @@ fun PidSettingsPage(
Log.i("BluetoothVM", selected) Log.i("BluetoothVM", selected)
when (dropdownMenuItems.indexOf(selected)) { when (dropdownMenuItems.indexOf(selected)) {
0 -> { 0 -> {
selectedRegulator = 1 selectedRegulator = dropdownMenuItems[0]
pidSettings.p1.p.toString().also { pValue = it } pidSettings.heightControllerParams.p.toString().also { pValue = it }
pidSettings.p1.i.toString().also { iValue = it } pidSettings.heightControllerParams.i.toString().also { iValue = it }
pidSettings.p1.d.toString().also { dValue = it } pidSettings.heightControllerParams.d.toString().also { dValue = it }
} }
1 -> { 1 -> {
selectedRegulator = 2 selectedRegulator = dropdownMenuItems[1]
pidSettings.p2.p.toString().also { pValue = it } pidSettings.yawControllerParams.p.toString().also { pValue = it }
pidSettings.p2.i.toString().also { iValue = it } pidSettings.yawControllerParams.i.toString().also { iValue = it }
pidSettings.p2.d.toString().also { dValue = it } pidSettings.yawControllerParams.d.toString().also { dValue = it }
} }
2 -> { 2 -> {
selectedRegulator = 3 selectedRegulator = dropdownMenuItems[2]
pidSettings.p3.p.toString().also { pValue = it } pidSettings.pitchControllerParams.p.toString().also { pValue = it }
pidSettings.p3.i.toString().also { iValue = it } pidSettings.pitchControllerParams.i.toString().also { iValue = it }
pidSettings.p3.d.toString().also { dValue = it } pidSettings.pitchControllerParams.d.toString().also { dValue = it }
} }
} }
}, },
@@ -167,23 +193,35 @@ fun PidSettingsPage(
Button( Button(
onClick = { onClick = {
when (selectedRegulator) { when (selectedRegulator) {
1 -> { dropdownMenuItems[0] -> {
val newPidSettings = pidSettings.copy( val newPidSettings = pidSettings.copy(
p1 = PidParams(p.toFloat(), i.toFloat(), d.toFloat()) heightControllerParams = PidParams(
p.toFloat(),
i.toFloat(),
d.toFloat()
)
) )
setPidSettings(newPidSettings) setPidSettings(newPidSettings)
} }
2 -> { dropdownMenuItems[1] -> {
val newPidSettings = pidSettings.copy( val newPidSettings = pidSettings.copy(
p2 = PidParams(p.toFloat(), i.toFloat(), d.toFloat()) yawControllerParams = PidParams(
p.toFloat(),
i.toFloat(),
d.toFloat()
)
) )
setPidSettings(newPidSettings) setPidSettings(newPidSettings)
} }
3 -> { dropdownMenuItems[2] -> {
val newPidSettings = pidSettings.copy( val newPidSettings = pidSettings.copy(
p3 = PidParams(p.toFloat(), i.toFloat(), d.toFloat()) pitchControllerParams = PidParams(
p.toFloat(),
i.toFloat(),
d.toFloat()
)
) )
setPidSettings(newPidSettings) setPidSettings(newPidSettings)
} }
@@ -199,7 +237,7 @@ fun PidSettingsPage(
} }
private fun isValidValue(k: String): Boolean { private fun isValidValue(k: String): Boolean {
return k.toFloatOrNull() != null && k.toFloat() >= 0f && k.toFloat() <= 2f return k.toFloatOrNull() != null && k.toFloat() >= 0f && k.toFloat() <= 15f
} }
@Preview(showBackground = true) @Preview(showBackground = true)

View File

@@ -1,10 +1,11 @@
package com.helible.pilot.dataclasses package com.helible.pilot.dataclasses
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class PidSettings ( data class PidSettings (
val p1: PidParams, @Json(name = "p1") val heightControllerParams: PidParams,
val p2: PidParams, @Json(name = "p2") val yawControllerParams: PidParams,
val p3: PidParams @Json(name = "p3") val pitchControllerParams: PidParams
) )

View File

@@ -0,0 +1,8 @@
package com.helible.pilot.dataclasses
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class StopMessage(
val stop: Boolean = true
)

View File

@@ -1,4 +1,7 @@
<resources> <resources>
<string name="app_name">Digital Pilot</string> <string name="app_name">Digital Pilot</string>
<string name="calibration_description">Расположите устройство на ровной горизонтальной поверхности, чтобы сани вертолета полностью лежали на ней. Нажмите кнопку калибровки ниже и ждите её окончания, не создавая тряски.</string> <string name="calibration_description">Расположите устройство на ровной горизонтальной поверхности, чтобы сани вертолета полностью лежали на ней. Нажмите кнопку калибровки ниже и ждите её окончания, не создавая тряски.</string>
<string name="p_pid_value_description">Сначала подберите значение коэффицента P, которое балансирует между слишком низкой и слишком высокой чувствительностью.</string>
<string name="i_pid_value_description">Затем подберите значение коэффицента I, которое уберёт нежелательный дрейв, но не повлияет на отзывчивость.</string>
<string name="d_pid_value_description">После установите значение коэффицента D таким образом, чтобы обеспечить более стабильное и плавное управление.</string>
</resources> </resources>