PDA

View Full Version : [Question(s)] Something more effiicent that if/else for multiple sensor mapping?

defwheezer
01-12-2011, 11:34 AM
What I am trying to do:

Setup: 3 fixed IR sensors (left, center, and right) in a semicircle , facing out, underneath a rotatable head.

1.) query each sensor for "in range" yes/no result,
2.) Decide which direction to rotate based object detection by each sensor,
3.) Rotate (head) to appropriate direction

Problematically it's easy enough to go through a long if/elseif loop to test each (of the 2^3) combination of results leading to a unique condition, but it seem this is so common a task in robotics that there must be a more elegant solution than the armstrong if/elseif loop.

The basic matrix is:

sensor State (object detected)
IR1 N Y N N Y N Y Y
IR2 N N Y N Y Y N Y
IR3 N N N Y N Y Y Y

Condition 0 1 2 3 4 5 6 7
Armstrong if/elseif

if (IR1 = N & IR2 = N & IR3 = N) then
{condition = 0}
elseif (IR1 = Y & IR2 = N & IR3 = N) then
{condition = 1}
elseif....
Seems like there must be a better way than the if/elseif!

Thanks for any thoughts on this, and sorry in advance if it's just an ignorant noOb question.

gunnk
01-12-2011, 01:16 PM
Try a little math to convert from the 0/1 states of the individual sensors:

condition = 4 * IR1 + 2 * IR2 + IR3

That gives you 0-7 depending on which sensors are live. I'm just treating your original status strings as binary numbers (000-111) and converting to decimal numbers (0-7)

Does that help?

defwheezer
01-12-2011, 02:09 PM
Try a little math to convert from the 0/1 states of the individual sensors:

condition = 4 * IR1 + 2 * IR2 + IR3

That gives you 0-7 depending on which sensors are live. I'm just treating your original status strings as binary numbers (000-111) and converting to decimal numbers (0-7)

Does that help?

Thanks, that is exactly the type of solution I was hoping for, and precisely why I asked this forum!

Pi Robot
01-12-2011, 03:32 PM
Depending on the programming language you are using, you could also try a matrix solution. Think of the [IR1 IR2 IR3] as the components of a 3-element vector, then set up a N x 3 matrix that multiplies this vector to give the responses you want. One advantage of this approach is that you could convert it into a neural network later on and have the robot learn the appropriate responses to the inputs.

--patrick

defwheezer
01-12-2011, 05:01 PM
Depending on the programming language you are using, you could also try a matrix solution. Think of the [IR1 IR2 IR3] as the components of a 3-element vector, then set up a N x 3 matrix that multiplies this vector to give the responses you want. One advantage of this approach is that you could convert it into a neural network later on and have the robot learn the appropriate responses to the inputs.

--patrick

Interesting suggestion- I'm doing this particular project in VS C#- can you point me to a (very simple) example of this type of approach?

Thanks,

-Carl

Pi Robot
01-13-2011, 09:30 AM
Hey Carl,

My version of C# (VS2005) doesn't have any built in matrix/vector math. I use to use a .NET library called GeneralMatrix but it is really not necessary for this example. Instead, you can first define a MatrixMultiply method, something like this:

private int[] MatrixMultiply(ref int[,] M, int rows, int[] V)
{
int[] result = new int[V.Length];

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < V.Length; j++)
{
result[i] += M[i, j] * V[j];
}
}

return result;
}Then you can run a test like this:

int[] IR;
int[] DriveCommand;
int[] DefaultDriveCommand;
int[,] M;

DefaultDriveCommand = new int[] { 1, 1 };
IR = new int[] {1, 0, 0};
M = new int[,] { {1, -2, -2},
{-2, -2, 1}
};

DriveCommand = MatrixMultiply(ref M, 2, IR);
for (int i = 0; i < 2; i++) DriveCommand[i] += DefaultDriveCommand[i];

for (int i = 0; i < 2; i++) Console.WriteLine(DriveCommand[i]);
Here I am assuming that DriveCommand is a vector with two values, one for each drive motor. We set a DefaultDriveCommand of {1, 1} which says drive forward if the coast is clear. The IR sensor values are set in the IR vector which has three values. And the control matrix M is a 2x3 matrix that maps IR values to drive commands. We multiply the IR vector by M, then add the DefaultDriveCommand vector to get the final drive commands. You can play with the values of M and set different IR vectors to see the results. The example above indicates there is an obstacle on the left and the resulting drive command is {2, -1} which would turn the robot to the right.

--patrick

defwheezer
01-21-2011, 10:47 AM
Hey Carl,

My version of C# (VS2005) doesn't have any built in matrix/vector math. I use to use a .NET library called GeneralMatrix but it is really not necessary for this example. Instead, you can first define a MatrixMultiply method, something like this:

private int[] MatrixMultiply(ref int[,] M, int rows, int[] V)
{
int[] result = new int[V.Length];
...
for (int i = 0; i < 2; i++) Console.WriteLine(DriveCommand[i]);
--patrick

Thanks Patrick- I am currently basking in the glory of having the simple method (condition = 4 * IR1 + 2 * IR2 + IR3; switch statement on condition) working so well already on my chimp bot. I will give this a try when time permits as it looks flexible in terms of 2-3D vectoring and NN learning...will plop this into a test form in VCS, when I have time, and 'see' how it works; need to review matrix/vector math too.

Pi Robot
01-21-2011, 02:43 PM
Great! It would be cool to see a video of your robot in action.

--patrick