Rubik's Cube Solving Robot

 
#21

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.

#22

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. Winky

Respect. Winky

#23

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

#24

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

Code:


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"Winky;
x = Convert.ToInt16(EZ_Builder.Scripting.VariableManager.GetVariable("$CameraObjectX"Winky);
y = Convert.ToInt16(EZ_Builder.Scripting.VariableManager.GetVariable("$CameraObjectY"Winky);
} 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();
}

#25

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...

Code:


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();
}

#26

@DJ,

Thanks, the information is useful.

I didn't want to reinvent the wheel... I had idea to explore the color profiles so we are on the same page Smile

btw I'm already using the camera guidelines to reduce the ROI area.

#27

Oh, almost forgot... to edit the color filters for each color, this is how you do it...

Code:


EZ_B.Classes.CustomColorConfig GetColor(EZ_B.Classes.CustomColorConfig color) {

string colorName = color.ColorName;

using (EZ_Builder.UCForms.FormCameraCustomColor fc = new EZ_Builder.UCForms.FormCameraCustomColor(_cameraControl.Camera)) {

fc.Configuration = color;

if (fc.ShowDialog() == DialogResult.OK) {

// set the color name to the original incase the user changed it
fc.Configuration.ColorName = colorName;

return fc.Configuration;
}

return color;
}
}