Moving Explor3r – Part III

In this third post about Moving Explor3r, we will use Extension properties to set speed in the motors of our robot.

Extension Properties

Extension properties provide a way to extend classes with APIs that can be accessed using property syntax, rather than the function syntax. Even though they’re called properties, they can’t have any state, because there’s no proper place to store it; it’s not possible to add extra fields to existing instances of Java objects.
Kotlin in Action, page 56

In the code we’ve been working in previous posts, when we wanted to set speed we used degrees and added a comment to make it clear that we meant RPM.

motorA.speed = 360 // 1 RPM
motorD.speed = 360 // 1 RPM

Let’s create an extension property for EV3LargeRegulatedMotor:

var EV3LargeRegulatedMotor.speedInRPM : Int
    get() = speed / 360
    set(speed: Int) {
        this.speed = 360 * speed
    }

And now let’s use it in our code:

package com.kotlinrobots.extensionprops

import lejos.hardware.motor.EV3LargeRegulatedMotor
import lejos.hardware.port.MotorPort
import lejos.utility.Stopwatch

fun Stopwatch.elapsedSecondsIsLessThan(seconds: Int): Boolean = this.elapsedSeconds() < seconds
fun Stopwatch.elapsedSeconds(): Int = this.elapsed() / 1000

var EV3LargeRegulatedMotor.speedInRPM : Int
    get() = speed / 360
    set(speed: Int) {
        this.speed = 360 * speed
    }

fun main(args: Array<String>) {

    val motorA = EV3LargeRegulatedMotor(MotorPort.A)
    val motorD = EV3LargeRegulatedMotor(MotorPort.D)
    val watch = Stopwatch()

    motorA.speedInRPM = 1
    motorD.speedInRPM = 1

    watch.reset()

    while (watch.elapsedSecondsIsLessThan(10)) {
        println("Seconds : ${watch.elapsedSeconds()}")

        when (watch.elapsedSeconds()) {
            in 3..5, in 7..9 -> {
                motorA.backward()
                motorD.backward()
            }
            else -> {
                motorA.forward()
                motorD.forward()
            }
        }
    }

    motorA.stop()
    motorD.stop()
}

We made our code more readable just by adding one extension property and a couple of extension functions. We can even move that code to another file named Utils.kt: 

package com.kotlinrobots.extensionprops

import lejos.hardware.motor.EV3LargeRegulatedMotor
import lejos.utility.Stopwatch

fun Stopwatch.elapsedSecondsIsLessThan(seconds: Int): Boolean = this.elapsedSeconds() < seconds
fun Stopwatch.elapsedSeconds(): Int = this.elapsed() / 1000

var EV3LargeRegulatedMotor.speedInRPM : Int
    get() = speed / 360
    set(speed: Int) {
        this.speed = 360 * speed
    }

Run it again, and see that the robot is still working as before.

Source code

Miguel

Leave a Reply

Your email address will not be published. Required fields are marked *