Прототип страницы расчета ПУУД
This commit is contained in:
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package space.nstart.pcp.pcp_types_lib.dto.ballistics
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
/** Запрос на ручной расчет программы управления угловым движением. */
|
||||||
|
data class AngularMotionCalculationRequestDTO(
|
||||||
|
val satelliteId: Long,
|
||||||
|
val approximateTime: LocalDateTime,
|
||||||
|
val mode: AngularMotionModeDTO = AngularMotionModeDTO.CONST_ORIENT,
|
||||||
|
val latitudeDeg: Double,
|
||||||
|
val longitudeDeg: Double,
|
||||||
|
val heightM: Double = 0.0,
|
||||||
|
val durationSec: Double,
|
||||||
|
val leadAngleDeg: Double = 0.0,
|
||||||
|
val azimuthDeg: Double = 0.0,
|
||||||
|
val sdi: Double? = null,
|
||||||
|
val pointInCenter: Boolean = false,
|
||||||
|
val focusMm: Double? = null,
|
||||||
|
val stepPuudSec: Double? = null,
|
||||||
|
val stepSdiSec: Double? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
enum class AngularMotionModeDTO {
|
||||||
|
CONST_ORIENT,
|
||||||
|
AZIMUTH,
|
||||||
|
SMOOTH_SDI,
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
package space.nstart.pcp.pcp_types_lib.dto.ballistics
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
|
||||||
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import kotlin.test.assertFalse
|
||||||
|
|
||||||
|
class AngularMotionCalculationRequestDTOJacksonTest {
|
||||||
|
|
||||||
|
private val mapper = jacksonObjectMapper().registerModule(JavaTimeModule())
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `deserializes calculation request contract`() {
|
||||||
|
val request = mapper.readValue<AngularMotionCalculationRequestDTO>(
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"satelliteId": 123,
|
||||||
|
"approximateTime": "2026-06-15T10:30:00",
|
||||||
|
"mode": "CONST_ORIENT",
|
||||||
|
"latitudeDeg": 55.75,
|
||||||
|
"longitudeDeg": 37.61,
|
||||||
|
"heightM": 0,
|
||||||
|
"durationSec": 60,
|
||||||
|
"leadAngleDeg": 0,
|
||||||
|
"azimuthDeg": 0,
|
||||||
|
"pointInCenter": false,
|
||||||
|
"focusMm": 5500,
|
||||||
|
"stepPuudSec": 0.125,
|
||||||
|
"stepSdiSec": 20
|
||||||
|
}
|
||||||
|
""".trimIndent(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(123L, request.satelliteId)
|
||||||
|
assertEquals(LocalDateTime.of(2026, 6, 15, 10, 30), request.approximateTime)
|
||||||
|
assertEquals(AngularMotionModeDTO.CONST_ORIENT, request.mode)
|
||||||
|
assertEquals(55.75, request.latitudeDeg)
|
||||||
|
assertEquals(37.61, request.longitudeDeg)
|
||||||
|
assertFalse(request.pointInCenter)
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-80
@@ -7,8 +7,8 @@ import org.springframework.web.bind.annotation.RequestBody
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RequestParam
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import space.nstart.pcp.angularmotion.AngularMotionMode
|
|
||||||
import space.nstart.pcp.pcp_request_service.configuration.CustomValidationException
|
import space.nstart.pcp.pcp_request_service.configuration.CustomValidationException
|
||||||
|
import space.nstart.pcp.pcp_types_lib.dto.ballistics.AngularMotionCalculationRequestDTO
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
@@ -33,8 +33,8 @@ class AngularMotionController(
|
|||||||
)
|
)
|
||||||
|
|
||||||
@PostMapping("/calculate")
|
@PostMapping("/calculate")
|
||||||
fun calculate(@RequestBody request: Map<String, Any?>): AngularMotionCalculationResultDTO =
|
fun calculate(@RequestBody request: AngularMotionCalculationRequestDTO): AngularMotionCalculationResultDTO =
|
||||||
angularMotionService.calculate(AngularMotionRequestMapper.calculationRequest(request))
|
angularMotionService.calculate(request)
|
||||||
|
|
||||||
private fun parseTime(value: String?, required: Boolean): LocalDateTime? {
|
private fun parseTime(value: String?, required: Boolean): LocalDateTime? {
|
||||||
val raw = value?.trim().orEmpty()
|
val raw = value?.trim().orEmpty()
|
||||||
@@ -52,80 +52,3 @@ class AngularMotionController(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object AngularMotionRequestMapper {
|
|
||||||
fun calculationRequest(payload: Map<String, Any?>): AngularMotionCalculationRequestDTO =
|
|
||||||
AngularMotionCalculationRequestDTO(
|
|
||||||
satelliteId = payload.requiredLong("satelliteId"),
|
|
||||||
approximateTime = parseLocalDateTime(payload.requiredString("approximateTime"), "approximateTime"),
|
|
||||||
mode = payload.optionalEnum("mode") ?: AngularMotionMode.CONST_ORIENT,
|
|
||||||
latitudeDeg = payload.requiredDouble("latitudeDeg"),
|
|
||||||
longitudeDeg = payload.requiredDouble("longitudeDeg"),
|
|
||||||
heightM = payload.optionalDouble("heightM") ?: 0.0,
|
|
||||||
durationSec = payload.requiredDouble("durationSec"),
|
|
||||||
leadAngleDeg = payload.optionalDouble("leadAngleDeg") ?: 0.0,
|
|
||||||
azimuthDeg = payload.optionalDouble("azimuthDeg") ?: 0.0,
|
|
||||||
sdi = payload.optionalDouble("sdi"),
|
|
||||||
pointInCenter = payload.optionalBoolean("pointInCenter") ?: false,
|
|
||||||
focusMm = payload.optionalDouble("focusMm"),
|
|
||||||
stepPuudSec = payload.optionalDouble("stepPuudSec"),
|
|
||||||
stepSdiSec = payload.optionalDouble("stepSdiSec"),
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun Map<String, Any?>.requiredString(field: String): String {
|
|
||||||
val value = this[field]?.toString()?.trim().orEmpty()
|
|
||||||
if (value.isEmpty()) {
|
|
||||||
throw CustomValidationException("Не задан параметр $field")
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Map<String, Any?>.requiredLong(field: String): Long =
|
|
||||||
optionalLong(field) ?: throw CustomValidationException("Не задан параметр $field")
|
|
||||||
|
|
||||||
private fun Map<String, Any?>.requiredDouble(field: String): Double =
|
|
||||||
optionalDouble(field) ?: throw CustomValidationException("Не задан параметр $field")
|
|
||||||
|
|
||||||
private fun Map<String, Any?>.optionalLong(field: String): Long? {
|
|
||||||
val value = this[field] ?: return null
|
|
||||||
return when (value) {
|
|
||||||
is Number -> value.toLong()
|
|
||||||
is String -> value.trim().takeIf { it.isNotEmpty() }?.toLongOrNull()
|
|
||||||
else -> null
|
|
||||||
} ?: throw CustomValidationException("Параметр $field должен быть целым числом")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Map<String, Any?>.optionalDouble(field: String): Double? {
|
|
||||||
val value = this[field] ?: return null
|
|
||||||
return when (value) {
|
|
||||||
is Number -> value.toDouble()
|
|
||||||
is String -> value.trim().takeIf { it.isNotEmpty() }?.toDoubleOrNull()
|
|
||||||
else -> null
|
|
||||||
}?.takeIf { it.isFinite() } ?: throw CustomValidationException("Параметр $field должен быть числом")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Map<String, Any?>.optionalBoolean(field: String): Boolean? {
|
|
||||||
val value = this[field] ?: return null
|
|
||||||
return when (value) {
|
|
||||||
is Boolean -> value
|
|
||||||
is String -> value.trim().takeIf { it.isNotEmpty() }?.toBooleanStrictOrNull()
|
|
||||||
else -> null
|
|
||||||
} ?: throw CustomValidationException("Параметр $field должен быть true или false")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Map<String, Any?>.optionalEnum(field: String): AngularMotionMode? {
|
|
||||||
val value = this[field]?.toString()?.trim()?.takeIf { it.isNotEmpty() } ?: return null
|
|
||||||
return runCatching { AngularMotionMode.valueOf(value) }
|
|
||||||
.getOrElse { throw CustomValidationException("Некорректный режим ПУУД '$value'") }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseLocalDateTime(value: String, field: String): LocalDateTime {
|
|
||||||
val normalized = if (value.length == 16) "$value:00" else value
|
|
||||||
return runCatching { LocalDateTime.parse(normalized) }
|
|
||||||
.getOrElse {
|
|
||||||
throw CustomValidationException(
|
|
||||||
"Некорректный формат времени $field='$value'. Ожидается yyyy-MM-dd'T'HH:mm или yyyy-MM-dd'T'HH:mm:ss",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
-18
@@ -3,24 +3,6 @@ package space.nstart.pcp.pcp_request_service.angular
|
|||||||
import space.nstart.pcp.angularmotion.AngularMotionMode
|
import space.nstart.pcp.angularmotion.AngularMotionMode
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
/** Запрос на ручной расчет программы управления угловым движением. */
|
|
||||||
data class AngularMotionCalculationRequestDTO(
|
|
||||||
val satelliteId: Long,
|
|
||||||
val approximateTime: LocalDateTime,
|
|
||||||
val mode: AngularMotionMode = AngularMotionMode.CONST_ORIENT,
|
|
||||||
val latitudeDeg: Double,
|
|
||||||
val longitudeDeg: Double,
|
|
||||||
val heightM: Double = 0.0,
|
|
||||||
val durationSec: Double,
|
|
||||||
val leadAngleDeg: Double = 0.0,
|
|
||||||
val azimuthDeg: Double = 0.0,
|
|
||||||
val sdi: Double? = null,
|
|
||||||
val pointInCenter: Boolean = false,
|
|
||||||
val focusMm: Double? = null,
|
|
||||||
val stepPuudSec: Double? = null,
|
|
||||||
val stepSdiSec: Double? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class AngularMotionSatelliteDTO(
|
data class AngularMotionSatelliteDTO(
|
||||||
val satelliteId: Long,
|
val satelliteId: Long,
|
||||||
val code: String,
|
val code: String,
|
||||||
|
|||||||
+9
-3
@@ -14,6 +14,8 @@ import space.nstart.pcp.angularmotion.SurveyId
|
|||||||
import space.nstart.pcp.pcp_request_service.configuration.CustomValidationException
|
import space.nstart.pcp.pcp_request_service.configuration.CustomValidationException
|
||||||
import space.nstart.pcp.pcp_request_service.service.SatelliteCatalogClient
|
import space.nstart.pcp.pcp_request_service.service.SatelliteCatalogClient
|
||||||
import space.nstart.pcp.pcp_request_service.service.SatelliteService
|
import space.nstart.pcp.pcp_request_service.service.SatelliteService
|
||||||
|
import space.nstart.pcp.pcp_types_lib.dto.ballistics.AngularMotionCalculationRequestDTO
|
||||||
|
import space.nstart.pcp.pcp_types_lib.dto.ballistics.AngularMotionModeDTO
|
||||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.ExactTimePositionRequestDTO
|
import space.nstart.pcp.pcp_types_lib.dto.ballistics.ExactTimePositionRequestDTO
|
||||||
import space.nstart.pcp.pcp_types_lib.dto.ballistics.OrbPointDTO
|
import space.nstart.pcp.pcp_types_lib.dto.ballistics.OrbPointDTO
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
@@ -81,7 +83,8 @@ class AngularMotionService(
|
|||||||
)
|
)
|
||||||
val sourcePoints = loadOrbitalPoints(request, config)
|
val sourcePoints = loadOrbitalPoints(request, config)
|
||||||
val stepper = RungeStepper(sourcePoints.toMutableList(), EarthType.PZ90d02)
|
val stepper = RungeStepper(sourcePoints.toMutableList(), EarthType.PZ90d02)
|
||||||
val calculator = AngularMotionCalculatorFactory.create(request.mode, stepper, EarthType.PZ90d02, config)
|
val mode = request.mode.toCalculationMode()
|
||||||
|
val calculator = AngularMotionCalculatorFactory.create(mode, stepper, EarthType.PZ90d02, config)
|
||||||
val surveyId = request.toSurveyId()
|
val surveyId = request.toSurveyId()
|
||||||
val result = try {
|
val result = try {
|
||||||
calculator.calculate(surveyId)
|
calculator.calculate(surveyId)
|
||||||
@@ -125,8 +128,9 @@ class AngularMotionService(
|
|||||||
if (request.longitudeDeg !in -180.0..180.0) {
|
if (request.longitudeDeg !in -180.0..180.0) {
|
||||||
throw CustomValidationException("longitudeDeg must be in [-180; 180]")
|
throw CustomValidationException("longitudeDeg must be in [-180; 180]")
|
||||||
}
|
}
|
||||||
if ((request.mode == AngularMotionMode.AZIMUTH || request.mode == AngularMotionMode.SMOOTH_SDI) &&
|
val sdi = request.sdi
|
||||||
(request.sdi == null || abs(request.sdi) < 1.0e-4)
|
if ((request.mode == AngularMotionModeDTO.AZIMUTH || request.mode == AngularMotionModeDTO.SMOOTH_SDI) &&
|
||||||
|
(sdi == null || abs(sdi) < 1.0e-4)
|
||||||
) {
|
) {
|
||||||
throw CustomValidationException("Для азимутального режима и Smooth SDI требуется ненулевая СДИ")
|
throw CustomValidationException("Для азимутального режима и Smooth SDI требуется ненулевая СДИ")
|
||||||
}
|
}
|
||||||
@@ -180,6 +184,8 @@ class AngularMotionService(
|
|||||||
|
|
||||||
private fun Double.toDegrees(): Double = this * 180.0 / PI
|
private fun Double.toDegrees(): Double = this * 180.0 / PI
|
||||||
|
|
||||||
|
private fun AngularMotionModeDTO.toCalculationMode(): AngularMotionMode = AngularMotionMode.valueOf(name)
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val MAP_INTERVAL_MINUTES = 5L
|
const val MAP_INTERVAL_MINUTES = 5L
|
||||||
}
|
}
|
||||||
|
|||||||
-70
@@ -1,70 +0,0 @@
|
|||||||
package space.nstart.pcp.pcp_request_service.angular
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.assertThrows
|
|
||||||
import space.nstart.pcp.angularmotion.AngularMotionMode
|
|
||||||
import space.nstart.pcp.pcp_request_service.configuration.CustomValidationException
|
|
||||||
import java.time.LocalDateTime
|
|
||||||
import kotlin.test.Test
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
import kotlin.test.assertFalse
|
|
||||||
|
|
||||||
class AngularMotionRequestMapperTest {
|
|
||||||
@Test
|
|
||||||
fun `maps calculation payload sent by UI`() {
|
|
||||||
val request = AngularMotionRequestMapper.calculationRequest(
|
|
||||||
mapOf(
|
|
||||||
"satelliteId" to 123L,
|
|
||||||
"approximateTime" to "2026-06-15T10:30:00",
|
|
||||||
"mode" to "CONST_ORIENT",
|
|
||||||
"latitudeDeg" to 55.75,
|
|
||||||
"longitudeDeg" to 37.61,
|
|
||||||
"heightM" to 0,
|
|
||||||
"durationSec" to 60,
|
|
||||||
"leadAngleDeg" to 0,
|
|
||||||
"azimuthDeg" to 0,
|
|
||||||
"focusMm" to 5500,
|
|
||||||
"stepPuudSec" to 0.125,
|
|
||||||
"stepSdiSec" to 20,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
assertEquals(123L, request.satelliteId)
|
|
||||||
assertEquals(LocalDateTime.of(2026, 6, 15, 10, 30), request.approximateTime)
|
|
||||||
assertEquals(AngularMotionMode.CONST_ORIENT, request.mode)
|
|
||||||
assertEquals(55.75, request.latitudeDeg)
|
|
||||||
assertEquals(37.61, request.longitudeDeg)
|
|
||||||
assertFalse(request.pointInCenter)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `maps datetime without seconds`() {
|
|
||||||
val request = AngularMotionRequestMapper.calculationRequest(
|
|
||||||
mapOf(
|
|
||||||
"satelliteId" to 123L,
|
|
||||||
"approximateTime" to "2026-06-15T10:30",
|
|
||||||
"latitudeDeg" to 55.75,
|
|
||||||
"longitudeDeg" to 37.61,
|
|
||||||
"durationSec" to 60,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
assertEquals(LocalDateTime.of(2026, 6, 15, 10, 30), request.approximateTime)
|
|
||||||
assertEquals(AngularMotionMode.CONST_ORIENT, request.mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `rejects unknown calculation mode with validation error`() {
|
|
||||||
assertThrows<CustomValidationException> {
|
|
||||||
AngularMotionRequestMapper.calculationRequest(
|
|
||||||
mapOf(
|
|
||||||
"satelliteId" to 123L,
|
|
||||||
"approximateTime" to "2026-06-15T10:30:00",
|
|
||||||
"mode" to "UNKNOWN",
|
|
||||||
"latitudeDeg" to 55.75,
|
|
||||||
"longitudeDeg" to 37.61,
|
|
||||||
"durationSec" to 60,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+2
-2
@@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RequestMapping
|
|||||||
import org.springframework.web.bind.annotation.RequestParam
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
import org.springframework.web.bind.annotation.ResponseBody
|
import org.springframework.web.bind.annotation.ResponseBody
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
import space.nstart.pcp.pcp_types_lib.dto.ballistics.AngularMotionCalculationRequestDTO
|
||||||
import space.nstart.pcp.slots_service.dto.dynamicplan.DynamicPlanCalculationRequestDTO
|
import space.nstart.pcp.slots_service.dto.dynamicplan.DynamicPlanCalculationRequestDTO
|
||||||
import space.nstart.pcp.slots_service.service.DynamicPlanService
|
import space.nstart.pcp.slots_service.service.DynamicPlanService
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -94,7 +95,6 @@ class AngularMotionRestController(
|
|||||||
|
|
||||||
@PostMapping("/calculate")
|
@PostMapping("/calculate")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
fun calculate(@RequestBody request: Map<String, Any?>) =
|
fun calculate(@RequestBody request: AngularMotionCalculationRequestDTO) =
|
||||||
dynamicPlanService.calculateAngularMotion(request)
|
dynamicPlanService.calculateAngularMotion(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Value
|
|||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import org.springframework.web.reactive.function.client.WebClient
|
import org.springframework.web.reactive.function.client.WebClient
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
|
import space.nstart.pcp.pcp_types_lib.dto.ballistics.AngularMotionCalculationRequestDTO
|
||||||
import space.nstart.pcp.slots_service.configuration.CustomErrorException
|
import space.nstart.pcp.slots_service.configuration.CustomErrorException
|
||||||
import space.nstart.pcp.slots_service.dto.dynamicplan.DynamicPlanCalculationRequestDTO
|
import space.nstart.pcp.slots_service.dto.dynamicplan.DynamicPlanCalculationRequestDTO
|
||||||
import tools.jackson.databind.JsonNode
|
import tools.jackson.databind.JsonNode
|
||||||
@@ -143,7 +144,7 @@ class DynamicPlanService(webClientBuilderProvider: ObjectProvider<WebClient.Buil
|
|||||||
.bodyToMono(JsonNode::class.java)
|
.bodyToMono(JsonNode::class.java)
|
||||||
.block() ?: ObjectMapper().createArrayNode()
|
.block() ?: ObjectMapper().createArrayNode()
|
||||||
|
|
||||||
fun calculateAngularMotion(request: Any): JsonNode =
|
fun calculateAngularMotion(request: AngularMotionCalculationRequestDTO): JsonNode =
|
||||||
webClientBuilder.build()
|
webClientBuilder.build()
|
||||||
.post()
|
.post()
|
||||||
.uri("$ballisticsServiceUrl/api/angular-motion/calculate")
|
.uri("$ballisticsServiceUrl/api/angular-motion/calculate")
|
||||||
|
|||||||
@@ -379,6 +379,7 @@
|
|||||||
durationSec: Number(el('angular-motion-duration').value),
|
durationSec: Number(el('angular-motion-duration').value),
|
||||||
leadAngleDeg: Number(el('angular-motion-lead-angle').value || 0),
|
leadAngleDeg: Number(el('angular-motion-lead-angle').value || 0),
|
||||||
azimuthDeg: Number(el('angular-motion-azimuth').value || 0),
|
azimuthDeg: Number(el('angular-motion-azimuth').value || 0),
|
||||||
|
pointInCenter: false,
|
||||||
focusMm: Number(el('angular-motion-focus').value || 5500),
|
focusMm: Number(el('angular-motion-focus').value || 5500),
|
||||||
stepPuudSec: Number(el('angular-motion-step').value || 0.125),
|
stepPuudSec: Number(el('angular-motion-step').value || 0.125),
|
||||||
stepSdiSec: Number(el('angular-motion-step-sdi').value || 20),
|
stepSdiSec: Number(el('angular-motion-step-sdi').value || 20),
|
||||||
|
|||||||
Reference in New Issue
Block a user