loading
 
RoboRealm + Rovio
from United States  [214 posts]
9 years
Hello,

Just in case some of you got a Rovio from Santa, I thought you might
find it interesting to see how easy it is to get it running with
RoboRealm.  WowWee has made the Rovio API available at:

http://www.wowweesupport.com/pdf/Rovio_API_Specifications_v1.2.pdf

As you can see from the document, the API is simply a series of
parameterized HTTP commands which makes it easy to control the Rovio
from any language that can send HTTP requests.  (You can test them out
by simply entering one of the commands in your web browser's location
box.)

Once you set up your Rovio and can access it from a web browser, you
can proceed below.  To keep things simple, I turned off Rovio's user
authentication by way of the "Settings->Security" tab.  Next, fire up
RoboRealm and use the camera selector to choose "Wowwee Ltd. Rovio"
for your video source--I guess the Rovio installation sets up a vitual
camera by this name.

Inspired by the RoboRealm Obstacle Avoidance tutorial, I used the
attached .robo file to determine the best path for Rovio to follow in
a cluttered enviroment.  I also use the Rovio's forward facing IR
detector to warn of objects straight ahead.  I then wrote a simple C#
program together with the RoboRealm API to use a number of variables
from the .robo file to steer the robot.  You can see several test
videos I made at the following links.  The videos use a split screen
with the view from Rovio's camera on the left.

http://www.youtube.com/watch?v=_Zl7yCYxSsg

http://www.youtube.com/watch?v=qn_UwVjAbCo

http://www.youtube.com/watch?v=SaPIvQGkS6I

--patrick

program.robo
LakeRobot from United States  [1 posts] 9 years
How about posting the example C# code?  I'd love to see it.

John
from United States  [214 posts] 8 years
To keep the post size manageable, here are just the essential pieces
of my code.  It would great if others could post back any improvements
or variations.

Have fun!

--patrick

Notes:

1) The Rovio camera needs to be in the down position so it can see the
   carpet immediately in front of it.  I also set it for 320x240
   resolution, High quality and 25 fps.

2) The code assumes that RoboRealm is already up and running with the
   attached .robo file loaded.

3) The constant "RovioBaseUri" in the declarations needs to be set to
   your Rovio's IP address.  Also, I have Rovio's user authentication
   turned off to keep life simple.  (My Rovio is behind a firewall.)

4) My main form has a timer control called RovioTimer, with the
   interval set to 100ms.  (You can play with this value of
   course.)  As you will see below, it fires the "Explore" method on
   every tick.  The Rovio API doesn't seem to have a motor control
   mode of cruising until stopped, so you have to continually tell it
   drive with each timer tick--even if you just want to go straight
   for awhile.

5) The one situation where Rovio is most likely to get into trouble
   when using the following "Explore" algorithm is getting a front
   wheel caught on an object (e.g. door frame) that was outside its
   field of view when approaching.  Unfortunately the Rovio's camera
   has a fairly narrow field of view...

Assembly/DLL References:

RR_COM_API.dll (Found in your RoboRealm Program folder.)
System.Web

// Key Name Spaces

using System.Net;
using System.Web;
using System.Threading;
using System.IO;

// Global Declarations

public static RR_COM_APILib.API_Wrapper RoboRealm;
public static HttpWebRequest RovioRequest = null;
public static HttpWebResponse RovioResponse = null;
public const string RovioBaseUri = "http://192.168.1.2/";
public int RR_Highest_x, RR_Highest_y, RR_Mid_x, RR_Blob_COG_x RR_Blob_COG_y;
public int RR_COG_x, RR_COG_y, RR_Target_area, RR_Max_radius, RR_Blob_area;
public static int RovioSpeed = 5;
public static int RovioDriveCode = 1;
public static int RovioDriveSleep = 100;
public bool isMoving = false;
public static bool IRobstacleDetected = false;
public static string lastMessage = "";
public string lastAction = "";
public string lastMove = "";
public int lastDirection = 0;
public ArrayList SensorFlags = new ArrayList();

// Key Methods

private void Rovio_Load(object sender, EventArgs e)
{
  RoboRealm = new RR_COM_APILib.API_Wrapper();
  RoboRealm.Connect("localhost");
}

private void RovioDrive(int navCode, int speed)
{
  RovioRequest = (HttpWebRequest)WebRequest.Create(RovioBaseUri + "/rev.cgi?Cmd=nav&action=18&drive=" + navCode.ToString() + "&speed=" + speed.ToString());
  RovioResponse = (HttpWebResponse)RovioRequest.GetResponse();
  String ver = RovioResponse.ProtocolVersion.ToString();
  StreamReader reader = new StreamReader(RovioResponse.GetResponseStream());
  string str = reader.ReadLine();
  while (str != null)
  {
    str = reader.ReadLine();
  }
}

public static bool RovioObstacleDetected()
{
  string status = getRovioNavStatus();
  if (status.Substring(status.Length - 1, 1) == "6") return true;
  else return false;
}

public static void RRsetVariable(string variable, string value)
{
  if (value != "" && value != lastMessage)
  {
     lastMessage = value;
     RoboRealm.SetVariable(variable, value);
  }
}

private void RovioTimer_Tick(object sender, EventArgs e)
{
  Explore();
}

private void Explore()
{
  int leftThreshold = 25;
  int rightThreshold = 25;
  int leftRightThreshold = 30;
  int leftCheck;
  int rightCheck;
  int forwardThreshold = 40;
  int reverseThreshold = 25;
  int turnThreshold = 40;
  int displaceThreshold = 40;
  int widthThreshold = 80;
  int pathAreaThreshold = 10000;

  RovioSpeed = 5;
  int RovioTurnSpeed = Math.Max(RovioSpeed, 5);

  RR_Blob_COG_x = Convert.ToInt16(RoboRealm.GetVariable("COG_X"));
  RR_Blob_COG_y = Convert.ToInt16(RoboRealm.GetVariable("COG_Y"));
  RR_Highest_x = Convert.ToInt16(RoboRealm.GetVariable("HIGHEST_MIDDLE_X"));
  RR_Highest_y = Convert.ToInt16(RoboRealm.GetVariable("HIGHEST_MIDDLE_Y"));
  RR_Mid_x = Convert.ToInt16(RoboRealm.GetVariable("IMAGE_WIDTH")) / 2;
  RR_Max_radius = Convert.ToInt16(RoboRealm.GetVariable("MAX_RADIUS"));
  RR_Blob_area = Convert.ToInt32(RoboRealm.GetVariable("AREA"));

  // Set up our sensor flags.
  SensorFlags.Clear();

  // Does the Rovio IR detect an obstacle?
  if (RovioObstacleDetected()) SensorFlags.Add("IR obstacle");

  // Is the path corridor too narrow?
  if (RR_Max_radius < widthThreshold) SensorFlags.Add("too narrow");

  // Have we run out of carpet ahead?
  if (RR_Highest_y < reverseThreshold || RR_Blob_area < pathAreaThreshold) SensorFlags.Add("dead end");

  // Are we almost out of carpet ahead?
  if (RR_Highest_y < forwardThreshold) SensorFlags.Add("road ends ahead");

  // Is the current path corridor displaced left or right? (This
  // indicates an obstacle nearby to one side.)
  if (Math.Abs(RR_Blob_COG_x - RR_Mid_x) > displaceThreshold) SensorFlags.Add("crooked path");

  // What's our best escape direction.
  leftCheck = RR_Mid_x - leftThreshold;
  rightCheck = RR_Mid_x + rightThreshold;

  if (RR_Highest_x <= leftCheck) SensorFlags.Add("escape left");
  else SensorFlags.Add("escape right");

  // Is there a preferred path to the left or right?
  if (RR_Highest_y - RR_Blob_COG_y > turnThreshold && RR_Blob_COG_y < leftRightThreshold)
  {
      if (RR_Highest_x <= leftCheck)
      {
      SensorFlags.Add("turn left");
      }
      else if (RR_Highest_x >= rightCheck)
      {
      SensorFlags.Add("turn right");
      }
  }

  // Now act accordingly.

  // Make sure we don't get trapped in a left-right oscillation.
  if (SensorFlags.Contains("escape right") && lastAction == "left")
  {
      SensorFlags.Remove("escape right");
      SensorFlags.Add("escape left");
  }
  else if (SensorFlags.Contains("escape left") && lastAction == "right")
  {
      SensorFlags.Remove("escape left");
      SensorFlags.Add("escape right");
  }

  // First, avoid any IR obstacles or dead ends.
  if (SensorFlags.Contains("IR obstacle"))
  {
      if (SensorFlags.Contains("escape right"))
      {
      RovioDrive(4, RovioTurnSpeed);
      RovioDrive(6, RovioTurnSpeed);
      lastAction = "right";
      }
      else
      {
      RovioDrive(3, RovioTurnSpeed);
      RovioDrive(5, RovioTurnSpeed);
      lastAction = "left";
      }
      Console.WriteLine("Avoid obstacle");
      RRsetVariable("ACTION", "IR Obstacle Detected");
  }
  // Now the dead ends.
  else if (SensorFlags.Contains("dead end"))
  {
      if (SensorFlags.Contains("escape right"))
      {
      RovioDrive(6, RovioTurnSpeed);
      lastAction = "right";
      }
      else
      {
      RovioDrive(5, RovioTurnSpeed);
      lastAction = "left";
      }
      Console.WriteLine("Dead end.");
      RRsetVariable("ACTION", "Dead End Detected");
  }
  // Is the path ahead too narrow?
  else if (SensorFlags.Contains("too narrow"))
  {
      if (SensorFlags.Contains("escape right"))
      {
      RovioDrive(6, RovioTurnSpeed);
      lastAction = "right";
      }
      else
      {
      RovioDrive(5, RovioTurnSpeed);
      lastAction = "left";
      }
      Console.WriteLine("Too narrow");
      RRsetVariable("ACTION", "Too Narrow");
  }
  // Are we running out of carpet ahead?
  else if (SensorFlags.Contains("road ends ahead"))
  {
      if (SensorFlags.Contains("escape right"))
      {
      RovioDrive(6, RovioTurnSpeed);
      lastAction = "right";
      }
      else
      {
      RovioDrive(5, RovioTurnSpeed);
      lastAction = "left";
      }
      Console.WriteLine("Running out of carpet");
      RRsetVariable("ACTION", "Not Enough Room");
  }
  // Is the current path corridor displaced left or right?
  else if (SensorFlags.Contains("crooked path"))
  {
      if (RR_Blob_COG_x - RR_Mid_x < 0)
      {
      RovioDrive(7, RovioSpeed);
      Console.WriteLine("Skew left");
      RRsetVariable("ACTION", "Skew Left");
      lastAction = "skew left";
      }
      else
      {
      RovioDrive(8, RovioSpeed);
      Console.WriteLine("Skew right");
      RRsetVariable("ACTION", "Skew Right");
      lastAction = "skew right";
      }

  }
  // All clear ahead so check to see if we should go left, right or straight.
  else if (SensorFlags.Contains("turn left"))
  {
      RovioDrive(7, RovioSpeed);
      Console.WriteLine("Skew left");
      RRsetVariable("ACTION", "Skew Left");
      lastAction = "skew left";
  }
  else if (SensorFlags.Contains("turn right"))
  {
      RovioDrive(8, RovioSpeed);
      Console.WriteLine("Skew right");
      RRsetVariable("ACTION", "Skew Right");
      lastAction = "skew right";
  }
  else
  {
      RovioDrive(1, RovioSpeed);
      Console.WriteLine("Go straight");
      RRsetVariable("ACTION", "Go Straight");
      lastAction = "straight";
  }
}


program.robo
Carmelo Milian from United States  [9 posts] 8 years
How do I do this step?
3) The constant "RovioBaseUri" in the declarations needs to be set to
   your Rovio's IP address.  Also, I have Rovio's user authentication
   turned off to keep life simple.  (My Rovio is behind a firewall.)

Carmelo Milian from United States  [9 posts] 8 years
Is there a Book, or Real Roborealm tutotial available?
from United States  [214 posts] 8 years
Hey Carmelo,

If you already have your Rovio set up and you can get to its web interface using a regular browser, then the IP address you use to do that is the same IP address you use in the sample code I posted above.

However, I should point out just in case you didn't already know, that RoboRealm now has a complete Rovio Module so you don't need to do the HttpRequest stuff I did in my sample code.  The Rovio Module in RoboRealm is under the Control->Robots category.  There is also a help page for it in the Documentation page on this site.

As for tutorials, have you looked at the Tutorial section on this site?  It is really helpful to actually do the tutorials with your robot or camera.

--patrick
Carmelo Milian from United States  [9 posts] 8 years
Hi,

I did look at the tutorials, but they are more of examples of applications. I was thinking more on a what if I dont know the product at all. introduction, how to use variables, programming structure, etc etc. I do know C, C++ and Basic. Bus havnt figure out how to aply it here.
Carmelo Milian from United States  [9 posts] 8 years
I keep getting the error ScriptSite.dll! Plase palce on the c:\winnt...

I did copy this file from the Folder to the Windows\system32 directory and I still get the message. Is there an install for this application? or is it only the stand alone version I downloaded?
Carmelo Milian from United States  [9 posts] 8 years
Problem Solved !!! Registering the DLL as specified on the forum.
Carmelo Milian from United States  [9 posts] 8 years
HI Patrick, I am getting it know. I was able to do a short program but I have one problem. Maybe you can help me. My Rovio responds to my statements. However, the movement of my rovio is not a constant one. Is lagging, like if momvement variable was switch on and off constantlly.

Any Ideas?
program.robo
from United States  [214 posts] 8 years
Hey Carmelo,

Do you mean that your Rovio moves forward too close to the red object, then backward too far away, then forward too close, and so on?  If so, one possible cause is a lag in the video.  I have noticed that when using the default settings of 320x240, Medium quality and 30 frames per second, there is a very noticeable lag between the movement of the robot and the updating of the video.  The best response I've been able to get is by setting the quality to Low and the Framerate to 6.

--patrick
Carmelo Milian from United States  [9 posts] 8 years
No, I am refering to Short moves between any distance. Instead of going from x to y it stops and goes many times in between.
from United States  [214 posts] 8 years
Hi Carmelo,

I managed to keep my Rovio connected to RoboRealm long enough to test your .robo file and I did not experience the start/stop movement you reported.  Instead I get smooth motion forward until the red blob is too big, then smooth motion backward until it is too small etc.

--patrick
Yuriko Aoki from Japan  [1 posts] 8 years
Hello Patrick,
  Can you send the C# program to me?(yurikoyoki@gmail.com ) I'm very interested in your program but  I'm a beginner in VS.
  Thanks!

regards,
Yuriko

This forum thread has been closed due to inactivity (more than 4 months) or number of replies (more than 50 messages). Please start a New Post and enter a new forum thread with the appropriate title.

 New Post   Forum Index