|
RoboRealm + Rovio from United States [214 posts] |
15 year
|
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] |
15 year
|
How about posting the example C# code? I'd love to see it.
John
|
|
|
from United States [214 posts] |
15 year
|
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] |
15 year
|
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] |
15 year
|
Is there a Book, or Real Roborealm tutotial available?
|
|
|
from United States [214 posts] |
15 year
|
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] |
15 year
|
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] |
15 year
|
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] |
15 year
|
Problem Solved !!! Registering the DLL as specified on the forum.
|
|
|
Carmelo Milian from United States [9 posts] |
15 year
|
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] |
15 year
|
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] |
15 year
|
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] |
15 year
|
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] |
15 year
|
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
|
|