ROBOTC.net forums
http://robotc.net/forums/

Heuristic algorithm
http://robotc.net/forums/viewtopic.php?f=15&t=5616
Page 2 of 3

Author:  Ernest3.14 [ Thu Jul 18, 2013 12:07 am ]
Post subject:  Re: Heuristic algorithm

That's interesting. Using the code you provided, I got these errors:
Quote:
*Warning*:Assignment '+' embedded in expression. Expression 'printRow + map[x][y]' is type 'string'
**Error**:Invalid 'string' L-Value 'printRow' in '(printRow + map[x][y])'

They are both on line 105, in `void PrintWavefrontMap()`:
Code:
printRow = printRow + map[x][y] + " ";

On my machine it seems like RobotC doesn't like it when you chain two operators (something to do with overloading behind the scenes?). Changing the aforementioned conditional to this made the code compile for me.
Code:
else if(map[x][y] < 10)
{
   printRow = printRow + map[x][y];
   printRow = printRow + " ";
}

Author:  Ernest3.14 [ Thu Jul 18, 2013 12:24 am ]
Post subject:  Re: Heuristic algorithm

Quote:
Another question is why the nxt lego mindstrom won't go straight line without using sensor?

The motors aren't very accurate (surprisingly accurate, really, given the size), and there's just a tiny bit of deviation, which eventually accumulates into a large error.

Author:  Azhari [ Thu Jul 18, 2013 12:25 am ]
Post subject:  Re: Heuristic algorithm

Ernest3.14 wrote:
That's interesting. Using the code you provided, I got these errors:
Quote:
*Warning*:Assignment '+' embedded in expression. Expression 'printRow + map[x][y]' is type 'string'
**Error**:Invalid 'string' L-Value 'printRow' in '(printRow + map[x][y])'

They are both on line 105, in `void PrintWavefrontMap()`:
Code:
printRow = printRow + map[x][y] + " ";

On my machine it seems like RobotC doesn't like it when you chain two operators (something to do with overloading behind the scenes?). Changing the aforementioned conditional to this made the code compile for me.
Code:
else if(map[x][y] < 10)
{
   printRow = printRow + map[x][y];
   printRow = printRow + " ";
}


why we got different error?

Author:  Azhari [ Thu Jul 18, 2013 12:39 am ]
Post subject:  Re: Heuristic algorithm

Ernest3.14 wrote:
Quote:
Another question is why the nxt lego mindstrom won't go straight line without using sensor?

The motors aren't very accurate (surprisingly accurate, really, given the size), and there's just a tiny bit of deviation, which eventually accumulates into a large error.


it the surface also affected the movement?
Is the battery level also affected?

any suggestion?

4/10 try only success...

Author:  Azhari [ Thu Jul 18, 2013 10:39 pm ]
Post subject:  Re: Heuristic algorithm

Azhari wrote:
Ernest3.14 wrote:
That's interesting. Using the code you provided, I got these errors:
Quote:
*Warning*:Assignment '+' embedded in expression. Expression 'printRow + map[x][y]' is type 'string'
**Error**:Invalid 'string' L-Value 'printRow' in '(printRow + map[x][y])'

They are both on line 105, in `void PrintWavefrontMap()`:
Code:
printRow = printRow + map[x][y] + " ";

On my machine it seems like RobotC doesn't like it when you chain two operators (something to do with overloading behind the scenes?). Changing the aforementioned conditional to this made the code compile for me.
Code:
else if(map[x][y] < 10)
{
   printRow = printRow + map[x][y];
   printRow = printRow + " ";
}


why we got different error?


i'm already solved it.

tfriez says,

tfriez wrote:
With 3.50 and the stacks/pointers change, the string manipulation got a little messed up in this program. Try this function:

Code:
void PrintWavefrontMap()
{
   for(int y=0; y < y_size; y++)
   {
      string printRow = "";
      string buffer = "";
      for(int x=0; x < x_size; x++)
      {
         if(map[x][y] < 10)
         {
            sprintf(buffer,"%s%d ", printRow, map[x][y]);
            printRow = buffer;
         }
         else if(map[x][y] == robot_mark)
         {
            sprintf(printRow,"%s%c",printRow,'R');
            printRow = buffer;
         }
         else if(map[x][y] == goal_mark)
         {
            sprintf(printRow,"%s%c",printRow,'G');
            printRow = buffer;
         }
         else if(map[x][y] == wall_mark)
         {
            sprintf(printRow,"%s%c",printRow,'X');
            printRow = buffer;
         }
         else if(map[x][y] == '*')
         {
            sprintf(printRow,"%s%c",printRow,'*');
            printRow = buffer;
         }
         else
         {
            sprintf(printRow,"%s%d",printRow, map[x][y]);
            printRow = buffer;
         }
      }
      nxtDisplayString(y, printRow);
   }
}


thanks for your help, now i can focus on using A* algorithm that i'm not sure how to coding it yet... :D
i will share my coding after i'm complete as contribution for other :)

Author:  Azhari [ Thu Jul 18, 2013 10:55 pm ]
Post subject:  Re: Heuristic algorithm

why the display output come out different?

Code:

//GLOBAL ARRAY representation of grid world using a 2-Dimensional array
//0  = open space
//1  = barrier
//2  = goal
//99 = robot
int map[x_size][y_size] =
 {{0,0,0,0,0},
  {0,1,99,1,0},
  {0,1,1,1,0},
  {0,0,0,0,0},
  {0,0,0,0,0},
  {0,0,0,0,0},
  {0,0,0,0,0},
  {0,0,2,0,0},
  {0,0,0,0,0},
  {0,0,0,0,0}};



and

Code:

//FUNCTION print wavefront map to NXT screen
void PrintWavefrontMap()
{
   for(int y=0; y < y_size; y++)
   {
      string printRow = "";
      string buffer = "";
      for(int x=0; x < x_size; x++)
      {
         if(map[x][y] < 10)
         {
            sprintf(buffer,"%s%d ", printRow, map[x][y]);
            printRow = buffer;
         }
         else if(map[x][y] == 99)
         {
            sprintf(printRow,"%s%c",printRow,'R');
            printRow = buffer;
         }
         else if(map[x][y] == 2)
         {
            sprintf(printRow,"%s%c",printRow,'G');
            printRow = buffer;
         }
         else if(map[x][y] == 1)
         {
            sprintf(printRow,"%s%c",printRow,'X');
            printRow = buffer;
         }
         else if(map[x][y] == '*')
         {
            sprintf(printRow,"%s%c",printRow,'*');
            printRow = buffer;
         }
         else
         {
            sprintf(printRow,"%s%d",printRow, map[x][y]);
            printRow = buffer;
         }
      }
      nxtDisplayString(y, printRow);
   }
}



Attachments:
File comment: My coding
nxt.png
nxt.png [ 28.57 KiB | Viewed 11626 times ]
File comment: Video
nxt2.PNG
nxt2.PNG [ 28.59 KiB | Viewed 11626 times ]

Author:  Ernest3.14 [ Fri Jul 19, 2013 3:22 pm ]
Post subject:  Re: Heuristic algorithm

Looks as if the output is sideways? Try switching your x and y and see what happens.
Code:
void PrintWavefrontMap()
{
    for(int x=0; x < x_size; x++)
    {
        //stuff
        for(int y=0; y < y_size; y++)
        { //stuff }
        //more stuff
    }
}

Author:  Azhari [ Mon Jul 22, 2013 10:34 pm ]
Post subject:  Re: Heuristic algorithm

Ernest3.14 wrote:
Looks as if the output is sideways? Try switching your x and y and see what happens.
Code:
void PrintWavefrontMap()
{
    for(int x=0; x < x_size; x++)
    {
        //stuff
        for(int y=0; y < y_size; y++)
        { //stuff }
        //more stuff
    }
}


i'm already change and it become more confusing then before :?
don't know which path it take. :?:

Author:  Ernest3.14 [ Tue Jul 23, 2013 12:36 am ]
Post subject:  Re: Heuristic algorithm

Sorry about the last post--my machine didn't have RobotC, so I kinda just glanced at your code :P

I ran your code through the debugger. It's really handy. :) Check your `else if` conditionals. For example:
Quote:
Code:
else if(map[x][y] == 99)
{
    sprintf(printRow,"%s%c",printRow,'R');
    printRow = buffer;
}


Are you sure you want to assign `printRow` to `buffer` again? Take a closer look at what is inside `buffer` when you do this.

Author:  Ernest3.14 [ Tue Jul 23, 2013 12:39 am ]
Post subject:  Re: Heuristic algorithm

Another hint: you check first whether the number is less than 10. But later on, you check if it is 1 or 2. If you run this through the debugger it will be very clear; if the number is indeed a 1 or 2, then it never reaches the bottom of that logic. You'll have to check those first, and then do an `if... else...` at the end to include everything else.

Author:  Azhari [ Tue Jul 23, 2013 5:41 am ]
Post subject:  Re: Heuristic algorithm

Ernest3.14 wrote:
Another hint: you check first whether the number is less than 10. But later on, you check if it is 1 or 2. If you run this through the debugger it will be very clear; if the number is indeed a 1 or 2, then it never reaches the bottom of that logic. You'll have to check those first, and then do an `if... else...` at the end to include everything else.


maybe you should see for yourself..

Attachments:

Capture_20130723.wmv [ 622.63 KiB | Viewed 11562 times ]

Author:  Ernest3.14 [ Tue Jul 23, 2013 2:28 pm ]
Post subject:  Re: Heuristic algorithm

Interesting. Try switching out the `for` loop in your `PrintWavefrontMap()` for this:

Code:
for(int x=0; x < x_size; x++)
{
   if(map[x][y] == 99)
   {
      sprintf(buffer,"%s%c",printRow,'R');
      printRow = buffer;
   }
   else if(map[x][y] == 2)
   {
      sprintf(buffer,"%s%c",printRow,'G');
      printRow = buffer;
   }
   else if(map[x][y] == 1)
   {
      sprintf(buffer,"%s%c",printRow,'X');
      printRow = buffer;
   }
   else if(map[x][y] == '*')
   {
      sprintf(buffer,"%s%c",printRow,'*');
      printRow = buffer;
   }
   else
   {
      sprintf(buffer,"%s%d",printRow, map[x][y]);
      printRow = buffer;
   }
}

Author:  Azhari [ Wed Jul 24, 2013 12:47 am ]
Post subject:  Re: Heuristic algorithm

Ernest3.14 wrote:
Interesting. Try switching out the `for` loop in your `PrintWavefrontMap()` for this:

Code:
for(int x=0; x < x_size; x++)
{
   if(map[x][y] == 99)
   {
      sprintf(buffer,"%s%c",printRow,'R');
      printRow = buffer;
   }
   else if(map[x][y] == 2)
   {
      sprintf(buffer,"%s%c",printRow,'G');
      printRow = buffer;
   }
   else if(map[x][y] == 1)
   {
      sprintf(buffer,"%s%c",printRow,'X');
      printRow = buffer;
   }
   else if(map[x][y] == '*')
   {
      sprintf(buffer,"%s%c",printRow,'*');
      printRow = buffer;
   }
   else
   {
      sprintf(buffer,"%s%d",printRow, map[x][y]);
      printRow = buffer;
   }
}


THANKS! It work like magic :bigthumb: :lol:

Author:  Azhari [ Wed Jul 24, 2013 12:54 am ]
Post subject:  Re: Heuristic algorithm

Here the work coding

Code:

#pragma config(StandardModel, "REMBOT")
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

//GLOBAL VARIABLES grid world dimensions
const int x_size = 10;
const int y_size = 5;

//GLOBAL ARRAY representation of grid world using a 2-Dimensional array
//0  = open space
//1  = barrier
//2  = goal
//99 = robot
int map[x_size][y_size] =
{{0,0,0,0,0},
   {0,1,99,1,0},
   {0,1,1,1,0},
   {0,0,0,0,0},
   {0,0,0,0,0},
   {0,0,0,0,0},
   {0,0,0,0,0},
   {0,0,2,0,0},
   {0,0,0,0,0},
   {0,0,0,0,0}};

//FUNCTION move forward for a variable number of grid blocks
void moveForward(int blocks)
{
   //convert number of blocks to encoder counts
   //wheel circumference = 17.6 cm
   //one block = 20 cm / 35.cm
   int countsToTravel = (20/17.6)*(360)*blocks;

   //encoder target for countsToTravel
   nMotorEncoder[motorB] = 0;
   nMotorEncoder[motorC] = 0;
   nMotorEncoderTarget[motorB] = countsToTravel;
   nMotorEncoderTarget[motorC] = countsToTravel;
   motor[motorB] = 50;
   motor[motorC] = 50;
   while(nMotorRunState[motorB] != runStateIdle && nMotorRunState[motorC] != runStateIdle) {}

   //stop for half second at end of movement
   motor[motorB] = 0;
   motor[motorC] = 0;
   wait1Msec(500);
}

//FUNCTION left point turn 90 degrees
void turnLeft90()
{
   //distance one wheel must travel for 90 degree point turn = 10.68 cm
   //wheel circumference = 17.6 cm
   int countsToTravel = (8.6/17.6)*(360);

   //encoder target for countsToTravel
   nMotorEncoder[motorB] = 0;
   nMotorEncoder[motorC] = 0;
   nMotorEncoderTarget[motorB] = countsToTravel;
   nMotorEncoderTarget[motorC] = countsToTravel;
   motor[motorB] = 50;
   motor[motorC] = -50;
   while(nMotorRunState[motorB] != runStateIdle && nMotorRunState[motorC] != runStateIdle) {}

   //stop for half second at end of movement
   motor[motorB] = 0;
   motor[motorC] = 0;
   wait1Msec(500);
}

//FUNCTION right point turn 90 degrees
void turnRight90()
{
   //distance one wheel must travel for 90 degree point turn = 10.68 cm
   //wheel circumference = 17.6 cm
   int countsToTravel = (8.6/17.6)*(360);

   //encoder target for countsToTravel
   nMotorEncoder[motorB] = 0;
   nMotorEncoder[motorC] = 0;
   nMotorEncoderTarget[motorB] = countsToTravel;
   nMotorEncoderTarget[motorC] = countsToTravel;
   motor[motorB] = -50;
   motor[motorC] = 50;
   while(nMotorRunState[motorB] != runStateIdle && nMotorRunState[motorC] != runStateIdle) {}

   //stop for half second at end of movement
   motor[motorB] = 0;
   motor[motorC] = 0;
   wait1Msec(500);
}

//FUNCTION print wavefront map to NXT screen
void PrintWavefrontMap()
{
   for(int y=0; y < y_size; y++)
   {
      string printRow = "";
      string buffer = "";
      for(int x=0; x < x_size; x++)
      {
         if(map[x][y] == 99)
         {
            sprintf(buffer,"%s%c",printRow,'R');
            printRow = buffer;
         }
         else if(map[x][y] == 2)
         {
            sprintf(buffer,"%s%c",printRow,'G');
            printRow = buffer;
         }
         else if(map[x][y] == 1)
         {
            sprintf(buffer,"%s%c",printRow,'X');
            printRow = buffer;
         }
         else if(map[x][y] == '*')
         {
            sprintf(buffer,"%s%c",printRow,'*');
            printRow = buffer;
         }
         else
         {
            sprintf(buffer,"%s%d",printRow, map[x][y]);
            printRow = buffer;
         }
      }
      nxtDisplayString(y, printRow);
   }
}

//FUNCTION wavefront algorithm to find most efficient path to goal
void WavefrontSearch()
{
   int goal_x, goal_y;
   bool foundWave = true;
   int currentWave = 2; //Looking for goal first

   while(foundWave == true)
   {
      foundWave = false;
      for(int y=0; y < y_size; y++)
      {
         for(int x=0; x < x_size; x++)
         {
            if(map[x][y] == currentWave)
            {
               foundWave = true;
               goal_x = x;
               goal_y = y;

               if(goal_x > 0) //This code checks the array bounds heading WEST
                  if(map[goal_x-1][goal_y] == 0)  //This code checks the WEST direction
                  map[goal_x-1][goal_y] = currentWave + 1;

               if(goal_x < (x_size - 1)) //This code checks the array bounds heading EAST
                  if(map[goal_x+1][goal_y] == 0)//This code checks the EAST direction
                  map[goal_x+1][goal_y] = currentWave + 1;

               if(goal_y > 0)//This code checks the array bounds heading SOUTH
                  if(map[goal_x][goal_y-1] == 0) //This code checks the SOUTH direction
                  map[goal_x][goal_y-1] = currentWave + 1;

               if(goal_y < (y_size - 1))//This code checks the array bounds heading NORTH
                  if(map[goal_x][goal_y+1] == 0) //This code checks the NORTH direction
                  map[goal_x][goal_y+1] = currentWave + 1;
            }
         }
      }
      currentWave++;
      PrintWavefrontMap();
      wait1Msec(500);
   }
}

//FUNCTION follow most efficient path to goal
//and update screen map as robot moves
void NavigateToGoal()
{
   //Store our Robots Current Position
   int robot_x, robot_y;

   //First - Find Goal and Target Locations
   for(int x=0; x < x_size; x++)
   {
      for(int y=0; y < y_size; y++)
      {
         if(map[x][y] == 99)
         {
            robot_x = x;
            robot_y = y;
         }
      }
   }

   //Found Goal and Target, start deciding our next path
   int current_x = robot_x;
   int current_y = robot_y;
   int current_facing = 0;
   int next_Direction = 0;
   int current_low = 99;

   while(current_low > 2)
   {
      current_low = 99; //Every time, reset to highest number (robot)
      next_Direction = current_facing;
      int Next_X = 0;
      int Next_Y = 0;

      //Check Array Bounds West
      if(current_x > 0)
         if(map[current_x-1][current_y] < current_low && map[current_x-1][current_y] != 1) //Is current space occupied?
      {
         current_low = map[current_x-1][current_y];  //Set next number
         next_Direction = 3; //Set Next Direction as West
         Next_X = current_x-1;
         Next_Y = current_y;
      }

      //Check Array Bounds East
      if(current_x < (x_size -1))
         if(map[current_x+1][current_y] < current_low && map[current_x+1][current_y] != 1) //Is current space occupied?
      {
         current_low = map[current_x+1][current_y];  //Set next number
         next_Direction = 1; //Set Next Direction as East
         Next_X = current_x+1;
         Next_Y = current_y;
      }

      //Check Array Bounds South
      if(current_y > 0)
         if(map[current_x][current_y-1] < current_low && map[current_x][current_y-1] != 1)
      {
         current_low = map[current_x][current_y-1];  //Set next number
         next_Direction = 2; //Set Next Direction as South
         Next_X = current_x;
         Next_Y = current_y-1;
      }

      //Check Array Bounds North
      if(current_y < (y_size - 1))
         if(map[current_x][current_y+1] < current_low && map[current_x][current_y+1] != 1) //Is current space occupied?
      {
         current_low = map[current_x][current_y+1];  //Set next number
         next_Direction = 0; //Set Next Direction as North
         Next_X = current_x;
         Next_Y = current_y+1;
      }

      //Okay - We know the number we're heading for, the direction and the coordinates.
      current_x = Next_X;
      current_y = Next_Y;
      map[current_x][current_y] = '*';

      //Track the robot's heading
      while(current_facing != next_Direction)
      {
         if (current_facing > next_Direction)
         {
            turnLeft90();
            current_facing--;
         }
         else if(current_facing < next_Direction)
         {
            turnRight90();
            current_facing++;
         }
      }
      moveForward(1);
      PrintWavefrontMap();
      wait1Msec(500);
   }
}

task main()
{
   WavefrontSearch();    //Build map of route with wavefront algorithm
   NavigateToGoal(); //Follow most efficient path to goal
   wait1Msec(5000);  //Leave time to view the LCD screen
}



Attachments:

Capture_20130724.wmv [ 622.63 KiB | Viewed 11537 times ]

Author:  Azhari [ Wed Jul 24, 2013 1:49 am ]
Post subject:  Re: Heuristic algorithm

Next task is if there a sudden new an obstacle in the path how the bot should react,

The concept would be like this.

if they a new obstacle in front when the coding run.

* * * * * R # 5 6
* x x 7 6 5 4 3 4 5
* S x 6 5 4 3 G 3 4
12 x x 7 6 5 4 3 4 6
11 10 9 8 7 6 5 4 5 6


* = path that been taken
X = Obstacle
S = Starting Point
R = Robot
# = New Obstacle


the new obstacle will be updated to the map
and the calculation will be reset again.

11 10 9 8 7 6 R X 5 6
12 x x 7 6 5 * 3 4 5
13 S x 6 5 4 * * 3 4
12 x x 7 6 5 4 3 4 6
11 10 9 8 7 6 5 4 5 6

i will share the coding if i'm already success

Page 2 of 3 All times are UTC - 5 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/