Rubik's Cube Solving Robot

bhouston

Canada

I found this robot on Thingiverse; www.thingiverse.com/thing:2471044 and thought it would be a fun project. Check it out they've really created a great robot. Printing it takes about 70 hrs. and then you need to go shopping for baking supplies (Raspberry Pi's and such). So I thought why not make it run with EZ-Robot hardware (most people here have lots of that) and software. I modified the camera holder to accept an EZ-Robot camera and the arms to accept EZ-Robot HDD servo horns and connected everything to an IoTiny. Building it was pretty straight forward. Programing it to solve the cube was another matter, so I got ahold of forum member ptp and asked if he would be interested in helping out and he was. He doesn't have a 3D printer however so I built him the robot and sent it to him. He has been busy working on an EZ-Robot plug-in to solve the cube as well as calibrate the arms and grippers. We are hoping to have the Plug-in ready to share by the end of the month, so start printing. This would be a fun project for both kids and adults. We'll keep you posted.

By — Last update

ARC Pro

Upgrade to ARC Pro

Stay on the cutting edge of robotics with ARC Pro, guaranteeing that your robot is always ahead of the game.

PRO
USA
#17  

@Andy,

The Inmoov project is almost a lifetime project, I still have some questions:

  1. Finger control & usability
  2. Legs are for walking ?
#18  

I know this is a challenging project. Way over my head if I had tried to conceive it. However I looked at your coding to try to learn something. You make it look so easy. What a wonderful process. :)

PRO
USA
#19  

@Dave,

Thanks for the words.

The idea is to make others challenges more EZ:)

I believe your are talking about the EZ-script:


:loop
WaitForChange($CubeVisionSequenceCounter)
SayWait("I see ")
REPEAT($x,0,8,1)
  $cell=$CubeVisionColors[$x]
  
  if ($cell=1)
    $color = "Blue"
  ElseIf ($cell=2)
    $color = "Red"
  ElseIf ($cell=3)
    $color = "Orange"
  ElseIf ($cell=4)
    $color="Yellow"
  ElseIf ($cell=5)
    $color="Green"
  ElseIf ($cell=6)
    $color="White"
  endif
  
  SayWait($color)
ENDREPEAT
goto(loop)

i used the KISS principle (https://en.wikipedia.org/wiki/KISS_principle):)

The $CubeVisionSequenceCounter is incremented every time a complete different sequence is found.

So the idea is to monitor that variable and do something after.

@DJ: I couldn't find a blocky equivalent for WaitForChange

PRO
USA
#20  

I always tell my friends Robots is more software than hardware.

There are so many sensors, but what makes them unique is the software (Firmware , API, Framework or Program).

One good example is the 3d camera:

  1. PrimeSense/ Microsoft Kinect1/ Asus (1st generation) (Gone)
  2. Microsoft Kinect2 (Will be gone after 2018)
  3. Intel Realsense Cameras
  4. Orbbec Cameras
  5. Google Tango

All of them have more or less the same sensors, but... only 1 st generation and Microsoft Kinect V2 handles skeleton tracking.

So the software is the real thing.

#21  

KISS, yes. This's a concept I struggle with. Most of the time I overbuild and over think. It always works out better when I later reverse engineer and remove all the complexity I worked so hard implementing. LOL eek

EZ Robot and the rest of us are fortunate the group of guys like you have chosen to stick around here and show us amateurs the path. ;)

Respect. ;)

PRO
Synthiam
#22  

Use either one of these, and they can include white. They have a histogram option, which may provide more consistency in varying lighting conditions.

  1. Simply create a profile for each color, adjust the sliders to isolate the color and give it a name.
  2. The camera control can be configured to specify a maximum number of objects to detect (in this case 9)
  3. Your plugin can watch the variables and see the location and color of each variable.
  4. Sort the variables by X ascending and Y ascending using linq

User-inserted image

PRO
Synthiam
#23  

Voila, here you go. Once you create a profile for each color and give them a name, this will sort them for you...


    class Square {

      public enum ColorListEnum {
        Red,
        Green,
        Blue,
        White
      }

      public ColorListEnum Color;
      public int X;
      public int Y;

      public Square(string color, int x, int y) {

        if (color == "red")
          Color = ColorListEnum.Red;
        else if (color == "green")
          Color = ColorListEnum.Green;
        else if (color == "blue")
          Color = ColorListEnum.Blue;
        else if (color == "white")
          Color = ColorListEnum.White;
        else
          throw new Exception(string.Format("Unknown color {0}", color));

        X = x;
        Y = y;
      }
    }

    Square[] GetCubeColors() {

      if (EZ_Builder.Scripting.VariableManager.GetVariable("$CameraIsTracking") != "1")
        throw new Exception("Camera not detected any objects");

      int count = Convert.ToInt16(EZ_Builder.Scripting.VariableManager.GetVariable("$CameraObjectCount"));

      if (count != 9)
        throw new Exception(string.Format("Camera only detected {0}/9 squares", count));

      // Get all the variables and put them into our class of colors with X and Y
      Square[] squareList = new Square[9];
      for (int i = 0; i < count; i++) {

        string colorName;
        int x;
        int y;

        if (i == 0) {

          colorName = EZ_Builder.Scripting.VariableManager.GetVariable("$CameraObjectColor");
          x = Convert.ToInt16(EZ_Builder.Scripting.VariableManager.GetVariable("$CameraObjectX"));
          y = Convert.ToInt16(EZ_Builder.Scripting.VariableManager.GetVariable("$CameraObjectY"));
        } else {

          colorName = EZ_Builder.Scripting.VariableManager.GetVariable("$CameraObjectColor_" + i.ToString());
          x = Convert.ToInt16(EZ_Builder.Scripting.VariableManager.GetVariable("$CameraObjectX_" + i.ToString()));
          y = Convert.ToInt16(EZ_Builder.Scripting.VariableManager.GetVariable("$CameraObjectY_" + i.ToString()));
        }

        squareList[i] = new Square(colorName, x, y);
      }

      // Sort the list of colors by X ascending and Y ascendinng
      var sorted = from o in squareList orderby o.X ascending, o.Y ascending select o;      

      return sorted.ToArray();
    }

PRO
Synthiam
#24  

One last thing, you can also do this entirely inside the plugin, rather than depending on people creating Color Profiles. If you'd like to see how, let me know and i can show you the EZ_B.CameraDetection namespace.

Simply do something like this...


    EZ_Builder.UCForms.FormCameraDevice _cameraControl;

    void detach() {

      if (_cameraControl != null) {

        EZ_Builder.EZBManager.Log("Detaching from {0}", _cameraControl.Text);

        _cameraControl.Camera.OnNewFrame -= Camera_OnNewFrame;

        _cameraControl = null;
      }

      Invokers.SetEnabled(button3, true);
      Invokers.SetText(button3, "Attach Camera");
    }

    void attach() {

      detach();

      Control[] cameras = EZ_Builder.EZBManager.FormMain.GetControlByType(typeof(EZ_Builder.UCForms.FormCameraDevice));

      if (cameras.Length == 0) {

        MessageBox.Show("There are no camera controls in this project.");

        return;
      }

      foreach (EZ_Builder.UCForms.FormCameraDevice camera in cameras)
        if (camera.Camera.IsActive) {

          _cameraControl = camera;

          _cameraControl.Camera.OnNewFrame += Camera_OnNewFrame;

          EZ_Builder.EZBManager.Log("Attached to: {0}", _cameraControl.Text);

          Invokers.SetEnabled(button3, true);

          Invokers.SetText(button3, "Detach Camera");

          return;
        }

      MessageBox.Show("There are no active cameras in this project. This control will connect to the first active camera that it detects in the project");
    }

    class Square {

      public enum ColorListEnum {
        Red,
        Green,
        Blue,
        White
      }

      public ColorListEnum Color;
      public int X;
      public int Y;

      public Square(string color, int x, int y) {

        if (color == "red")
          Color = ColorListEnum.Red;
        else if (color == "green")
          Color = ColorListEnum.Green;
        else if (color == "blue")
          Color = ColorListEnum.Blue;
        else if (color == "white")
          Color = ColorListEnum.White;
        else
          throw new Exception(string.Format("Unknown color {0}", color));

        X = x;
        Y = y;
      }
    }

    Square [] CubeColors;

    // Set up your own color definition profiles or let the user adjust them
    EZ_B.Classes.CustomColorConfig [] _colorConfigs = new EZ_B.Classes.CustomColorConfig[] {
      new EZ_B.Classes.CustomColorConfig("red",true, 10, 10, 50, 0.2f, 0.2f, 0.1f, 0.9f),
      new EZ_B.Classes.CustomColorConfig("green",true, 10, 10, 50, 0.2f, 0.2f, 0.1f, 0.9f),
      new EZ_B.Classes.CustomColorConfig("white",true, 10, 10, 50, 0.2f, 0.2f, 0.1f, 0.9f),
      new EZ_B.Classes.CustomColorConfig("blue",true, 10, 10, 50, 0.2f, 0.2f, 0.1f, 0.9f)
    };

    void Camera_OnNewFrame() {

      if (_isClosing)
        return;

      List<EZ_B.ObjectLocation> detectedObjects = new List<EZ_B.ObjectLocation>();

      foreach (var colorConfig in _colorConfigs)
        detectedObjects.AddRange(_cameraControl.Camera.CameraCustomColorDetection.GetObjectLocationByColor(true, colorConfig));

      if (detectedObjects.Count != 9)
        throw new Exception(string.Format("Camera only detected {0}/9 squares", detectedObjects.Count));

      // Get all the variables and put them into our class of colors with X and Y
      Square[] squareList = new Square[9];
      for (int i = 0; i < detectedObjects.Count; i++) {

        var detectedObject = detectedObjects[i];

        squareList[i] = new Square(detectedObject.ColorName, detectedObject.CenterX, detectedObject.CenterY);
      }

      // Sort the list of colors by X ascending and Y ascending and assign to a global variable for using elsewhere
      CubeColors = (from o in squareList orderby o.X ascending, o.Y ascending select o).ToArray();
    }