untested motor controller
This commit is contained in:
parent
b24ebba1f6
commit
754275d7b2
|
|
@ -1,5 +1,7 @@
|
|||
package dev.asdf00.visionfive.hc
|
||||
|
||||
import kotlin.math.abs
|
||||
|
||||
class Controller(private val senseBot: GpioPin, private val senseTop: GpioPin, private val motor: PinGroup) {
|
||||
constructor(senseBot: GpioPin, senseTop: GpioPin, m0: GpioPin, m1: GpioPin, m2: GpioPin, m3: GpioPin) : this(
|
||||
senseBot,
|
||||
|
|
@ -8,7 +10,7 @@ class Controller(private val senseBot: GpioPin, private val senseTop: GpioPin, p
|
|||
)
|
||||
|
||||
init {
|
||||
motor.intState = initialStep
|
||||
motor.intState = INITIAL_STEP
|
||||
}
|
||||
|
||||
private var internalState = -1
|
||||
|
|
@ -18,11 +20,71 @@ class Controller(private val senseBot: GpioPin, private val senseTop: GpioPin, p
|
|||
get() = if (internalState < 0) Double.NaN else internalState.toDouble() / maxStep.toDouble()
|
||||
set(target) {
|
||||
if (internalState < 0)
|
||||
throw IllegalStateException("call Controller#runInitSequence before using it")
|
||||
TODO()
|
||||
throw IllegalStateException("call Controller#runCalibrationSequence before using it")
|
||||
if (target < 0 || target > 1)
|
||||
throw IllegalArgumentException("state must always be between 0 and 1")
|
||||
if (target isCloseTo 0) {
|
||||
// full close
|
||||
runToBot()
|
||||
internalState = 0
|
||||
} else if (target isCloseTo 1) {
|
||||
// full open
|
||||
runToTop()
|
||||
internalState = maxStep
|
||||
} else {
|
||||
// normal case
|
||||
val dif = (maxStep.toDouble() * target).toInt() - internalState
|
||||
if (dif > 0) {
|
||||
val realDif = stepAnti(dif)
|
||||
if (realDif != dif) {
|
||||
// maybe log correction
|
||||
// recalibrate if deviation was too much
|
||||
if (abs(internalState.toDouble() / maxStep.toDouble() - target) > RECALIB_DATA) {
|
||||
// turn to middle
|
||||
val mDif = stepClock(maxStep / 2)
|
||||
if (mDif != maxStep / 2) {
|
||||
// something has gone VERY wrong here
|
||||
internalState = -1
|
||||
throw IllegalStateException("unrecoverable state")
|
||||
}
|
||||
runCalibrationSequence()
|
||||
// and try again after calibration
|
||||
@Suppress("RecursivePropertyAccessor")
|
||||
this.state = target
|
||||
return
|
||||
}
|
||||
internalState = maxStep
|
||||
} else {
|
||||
internalState += realDif
|
||||
}
|
||||
} else if (dif < 0) {
|
||||
val realDif = stepClock(dif)
|
||||
if (realDif != dif) {
|
||||
// maybe log correction
|
||||
// recalibrate if deviation was too much
|
||||
if (abs(internalState.toDouble() / maxStep.toDouble() - target) > RECALIB_DATA) {
|
||||
// turn to middle
|
||||
val mDif = stepAnti(maxStep / 2)
|
||||
if (mDif != maxStep / 2) {
|
||||
// something has gone VERY wrong here
|
||||
internalState = -1
|
||||
throw IllegalStateException("unrecoverable state")
|
||||
}
|
||||
runCalibrationSequence()
|
||||
// and try again after calibration
|
||||
@Suppress("RecursivePropertyAccessor")
|
||||
this.state = target
|
||||
return
|
||||
}
|
||||
internalState = 0
|
||||
} else {
|
||||
internalState -= realDif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun runInitSequence() {
|
||||
fun runCalibrationSequence() {
|
||||
val prevState = runToBot()
|
||||
val range = runToTop()
|
||||
stepClock(range - prevState)
|
||||
|
|
@ -77,18 +139,18 @@ class Controller(private val senseBot: GpioPin, private val senseTop: GpioPin, p
|
|||
}
|
||||
|
||||
private fun doStep(step: LongArray) {
|
||||
assert(motor.intState == initialStep, { "step must ALWAYS start on initial step state" })
|
||||
assert(motor.intState == INITIAL_STEP) { "step must ALWAYS start on initial step state" }
|
||||
for (l in step) {
|
||||
motor.intState = l
|
||||
Thread.sleep(stepDelay)
|
||||
Thread.sleep(STEP_DELAY)
|
||||
}
|
||||
assert(motor.intState == initialStep, { "step must ALWAYS end on initial step state" })
|
||||
assert(motor.intState == INITIAL_STEP) { "step must ALWAYS end on initial step state" }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val stepDelay = 10L
|
||||
|
||||
private val initialStep = 0b1001L
|
||||
private const val STEP_DELAY = 10L
|
||||
private const val INITIAL_STEP = 0b1001L
|
||||
private const val RECALIB_DATA = 0.01
|
||||
|
||||
private val clockStep = longArrayOf(
|
||||
0b0001,
|
||||
|
|
@ -113,3 +175,7 @@ class Controller(private val senseBot: GpioPin, private val senseTop: GpioPin, p
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
infix fun Double.isCloseTo(other: Double) = this.isCloseTo(other, 0e-6)
|
||||
infix fun Double.isCloseTo(other: Int) = this isCloseTo other.toDouble()
|
||||
fun Double.isCloseTo(other: Double, epsilon: Double) = this >= other - epsilon && this <= other + epsilon
|
||||
Loading…
Reference in New Issue
Block a user