DD: Android Things Rubik’s Cube Solver (3)

I have received the next shipments, which includes a second claw and 2 more servos.

Now that I have 3 non-defective servos (and a 4th one still on transit), I can at least test the concepts of face twist and cube rotation. This is a first step towards manipulating a cube programmatically, and then solve it, but this step has proven to be more complex that anticipated, and for partly unexpected reasons.

One claw face twist

I received the servos first, so the first thing I tried was to have one functional claw perform a face twist while I held the cube. This test worked out quite nicely.

The code for that is actually quite simple:

fun twistFace() {
    claw.turnClockWise()
    Thread.sleep(600)
    claw.release()
    Thread.sleep(800)
    claw.resetRotation()
    Thread.sleep(600)
    claw.grab()
}

Given that setting the servo is an asynchronous operation, I am just having a Thread.sleep to check how long it does take to execute the move. I expect this to be cleaner as I move along.

And then a few days later I received the second claw, so it was time to test the same concept but with 2 claws.

One would thing that cube twists and cube rotations with 2 claws was going to be easy after the previous test.

Well, spoiler alert, I was wrong.

Using two claws

When I assembled the second claw, I noticed that the servos were quite different in terms of configuration. This may happen because they came from different manufacturers, even when they are built on the same spec. In any case I had to tweak the pulse duration individually for each claw to open and close the same way. I was hoping to have the same configuration for each claw, but it is not going to be possible.

After some trial and error, the current configuration for my servos is:

rightClaw = Claw(pca9685, 0, 1)
rightClaw.setGripPulseDurationRange(1.0, 2.5)
leftClaw = Claw(pca9685, 2, 3)
leftClaw.setGripPulseDurationRange(1.0, 2.0)

In the meantime I also created a very simple UI for the NXP iMX7D with 4 buttons to:

  • Reset the claws: putting both claws on the position open and centered on rotation
  • Grab the cube: The claws open and then close, but not fully, just enough to grab the cube
  • Twist: Same move as before, but the other claw is always holding
  • Turn: Same move, except that this time the second claw releases and then grabs it again}

And -as the naive engineer I am- once the opening and closing of both claws was properly configured. I went straight away to try a face twist and this is what happened.

The servos have some “room” and when they release, the reattachment position is different. Not by much, but enough to make the re-grab at the end of the face twist fail.

I did not notice that I was subcounsciously correcting this myself when I was the one holding the cube.

So, to just be able to visualize this problem, I added a new method to the app, one that simply releases and regrabs the cube, first one claw and then the other.

Even this simple test proved that it was going to be trickier than expected.

So, where am I now and what is next?

Still missing one more servo, maybe once I have it properly screwed to the claw the movement gap will be smaller, but as I said on the tweet, I am afraid I’ll need proper brackets.

The physical part of this project is turning out to be the most challenging one so far and I want to think about it, maybe use wood and proper brackets is the solution, but I also want to have some rails to adjust the claw distance…. and no, Lego does not have enough resolution to do that, a Lego dot is too big.

The next goal is to be able to scramble a cube using a few different face moves. Once I get passed the first twist I reckon it will be easy.

I’m also afraid I’ll have to swallow those words.

DD: Android Things Rubik’s Cube Solver (2)

Time for an update! I just received the first claw with 2 servos and I had the urge to put it together as soon as I saw the package.

The specs of the claw stated that it was 55mm wide when open, and most modern cubes are ~56mm, so -as expected- it is too small to handle a standard cube, but hey, it was cheap.

Since I was expecting this, I had already ordered some mini cubes (30mm) and in the meantime I also have some 2x2x2 to try with, so not too much of an issue. I even got a spare mini DaYan, which a pretty good speed cube, and you can soften the springs to make it easier to move and require less torque from the servos (which I indeed did)

Now, into the details: I got the claw with 2 MG996 servos. As it happens these servos have a range of 180 degrees, which means that:

  • I need to tweak the pulse duration range to get the complete angle radio
  • I will only be able to do 2 types of moves, either R & R’ or R and 2R, but not the 3 of them, since I’d need at least and angle range of 270 for that (to go from -90 to 180

Anyway, I got the claw doing the basic move, which is (starting from 0 degrees turn and cube held):

  • Turn 90 degrees
  • Release
  • Get back to 0 degrees
  • Grab

These movements are what is needed to perform a turn of one face and the return to the start position.

One important point to make is that whenever you use a motor, you should use an external power source and not the 5v output from a board. That output is meant to power electronic circuits and can’t drain much power. Best case you’ll reboot the board, worse case you’ll damage it. So here it is, again, in bold:

When using any motor, use an external power source

While Android Things has 2 PWM outputs I could, in theory, have used them directly, but looking ahead I know I’ll need 4 PWM, so it is a good idea to have them connected to a PWM expander, a PCA9685, for which I wrote a driver for Android Things a while ago as part of PlattyThings.

Note how it has special pins for power input (use them!) and it has pins to connect up to 16 servos to it.

Now into the bad news: one servo was defective. As soon as any minor torque was needed it started spinning loose. That has made impossible to test actual turning of the face with a cube while holding the cube myself.

On the bright side, I did learn how a servo is built internally, which is interesting.

While I do have some other motors, nothing really fit. I have a 360 continuous rotation servo, but that would need me timing the twist, I also have some stepper motors, but that will require a lot of GPIO ports and a different connection to the claw (it is designed to fit with a servo) and finally some mini servos (MG90S), which I suspect do not have enough torque, so I did not even try.

Ultimately I decided to order a new servo from another model – a MG946- that in theory has a wider rotation range to solve both problems.

Other considerations is if I should make the structure for the solver using cardboard or Lego. I just tried and the servos fit quite well into the Lego system, so maybe that’s what it’s going to be.

And that is it for now until the next shipment arrives. It will probably be some mini cubes or the second claw.