From da36cc0ea9c341f491655c444ee21396e37dc00f Mon Sep 17 00:00:00 2001 From: "E. A. Graham Jr." <10370165+EAGrahamJr@users.noreply.github.com> Date: Tue, 21 May 2024 12:27:56 -0700 Subject: [PATCH] Fix stepper gear ratios. Math was totally wrong and the tests were inverted to match the wrongness. --- .../crackers/kobots/parts/movement/Rotator.kt | 12 ++----- .../kobots/parts/movement/RotatorTest.kt | 31 ++++++++++++++----- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/crackers/kobots/parts/movement/Rotator.kt b/src/main/kotlin/crackers/kobots/parts/movement/Rotator.kt index ed15702..709fa19 100644 --- a/src/main/kotlin/crackers/kobots/parts/movement/Rotator.kt +++ b/src/main/kotlin/crackers/kobots/parts/movement/Rotator.kt @@ -72,23 +72,17 @@ open class BasicStepperRotator( val stepStyle: StepStyle = StepStyle.SINGLE ) : Rotator, StepperActuator { - private val maxSteps: Float - private val degreesToSteps: Map private val stepsToDegrees = mutableMapOf>() init { require(gearRatio > 0f) { "gearRatio '$gearRatio' must be greater than zero." } - maxSteps = theStepper.stepsPerRotation / gearRatio + val stepRatio = theStepper.stepsPerRotation * gearRatio / 360 // calculate how many steps off of "zero" each degree is degreesToSteps = (0..359).map { deg: Int -> - val steps = (maxSteps * deg / 360).roundToInt() - stepsToDegrees.compute(steps) { _, v -> - val theList = v ?: mutableListOf() - theList += deg - theList - } + val steps = (deg * stepRatio).roundToInt() + stepsToDegrees.compute(steps) { _, v -> (v ?: mutableListOf()).apply { add(deg) } } deg to steps }.toMap() } diff --git a/src/test/kotlin/crackers/kobots/parts/movement/RotatorTest.kt b/src/test/kotlin/crackers/kobots/parts/movement/RotatorTest.kt index 14da09d..054ad0f 100644 --- a/src/test/kotlin/crackers/kobots/parts/movement/RotatorTest.kt +++ b/src/test/kotlin/crackers/kobots/parts/movement/RotatorTest.kt @@ -53,7 +53,7 @@ class RotatorTest : FunSpec( * The gear ratio is 1:1 and the stepper motor has 200 steps per rotation. The rotator is set to move from * 0 to 360 degrees, and it's starting position is assumed to be 0 degrees. The target angle is 83 degrees. */ - test("max steps < 360, 1:1 gear ratio") { + test("stepper 200, 1:1 gear ratio, 83 deg") { every { mockStepper.stepsPerRotation } answers { 200 } val rotor = BasicStepperRotator(mockStepper) @@ -64,12 +64,12 @@ class RotatorTest : FunSpec( } /** - * With a gear ratio of 1:1.11 and the motor has 200 steps per rotation. The rotator is to be moved 90 + * With a gear ratio of .9 and the motor has 200 steps per rotation. The rotator is to be moved 90 * degrees in a forward direction. The stepper is currently at 0 degrees. */ - test("max steps < 360, 1:11:1 gear ratio") { + test("steooer 200, .9 gear ratio, 90 deg") { every { mockStepper.stepsPerRotation } answers { 200 } - val rotor = BasicStepperRotator(mockStepper, 1.11f) + val rotor = BasicStepperRotator(mockStepper, .9f) rotor.test(90) verify(exactly = 45) { @@ -78,15 +78,30 @@ class RotatorTest : FunSpec( } /** - * Motor has 2048 steps per rotation and a gear ratio of 1.28 (simulated from real-world). The target is + * With a gear ratio of 2.5 and the motor has 200 steps per rotation. The rotator is to be moved 45 + * degrees in a forward direction. The stepper is currently at 0 degrees. + */ + test("stepper 200, 2.5 gear ratio, 45 deg") { + every { mockStepper.stepsPerRotation } answers { 200 } + + val rotor = BasicStepperRotator(mockStepper, 2.5f) + + rotor.test(45) + verify(atMost = 63, atLeast = 62) { + mockStepper.step(StepperMotorInterface.Direction.FORWARD, any()) + } + } + + /** + * Motor has 2048 steps per rotation and a gear ratio of .78 (simulated from real-world). The target is * 90 degrees. */ - test("max steps > 360, 1.28:1 gear ratio") { + test("stepper 2048, .78 gear ratio, 90 deg") { every { mockStepper.stepsPerRotation } answers { 2048 } - val rotor = BasicStepperRotator(mockStepper, 1.28f) + val rotor = BasicStepperRotator(mockStepper, .78f) rotor.test(90) - verify(exactly = 400) { + verify(atLeast = 398, atMost = 400) { mockStepper.step(StepperMotorInterface.Direction.FORWARD, any()) } }