Intro Program - Development Notes
Updated to the September 2006 CTP using the conversion tool.
Worked on the code a little to improve the behaviour.
Started the Maze Simulator
Checked that services are running for simulated differential drive
and the bumpers
Created a new service called Intro using dssnewservice:
dssnewservice /service:Intro /dir:samples\Intro
-----------------------------------------------------------------
Follow Robotics Tutorial 1
Step 1 -- Add references
We don't want to use a real robot, so use simulator instead.
Add Reference takes a while.
Add references to the PROXY, not the original service.
The proxy calls the service using SOAP.
Don't reference these because they are the "physical" services:
SimulatedBumper.Y2006.M05.proxy
SimulatedDifferentialDrive.Y2006.M06.proxy
Step 2 -- Add a partner
Insert code for the partner into the Intro.cs.
Add an entry in the manifest to create the actual partner
Copy the code from the manifest for SimulatedBumper:
http://schemas.microsoft.com/robotics/2006/05/simulatedbumper.html
Steps 3, 4, 5 were OK.
Note that step 5 says to put the handler at the bottom of the
code. I don't know why or if this is important. Proably not.
Compiled and built OK.
Ran in debugger and an error flashed up:
Program exited with code 20
Tried to run it manually:
dsshost -port:51000 -tcpport:51001 -manifest:"samples/Intro/Intro.manifest.xml"
D:\Microsoft Robotics Studio (August 2006)>dsshost -port:50000 -tcpport:50001 -manifest:"samples/Intro/Intro.manifest.xml"
Initializing Dss Node with manifest file:///D:/Microsoft Robotics Studio (August 2006)/samples/Intro/Intro.manifest.xml
Initialization failed in DSS boot loader
Socket.Listen() failed
Can't run dsshost because it is already running with the simulator
on the same port!
Can run it on different ports, but what is the point? This creates a new
instance of the bumper service!
Need to connect to the existing simulated bumper.
Found that everything can be run at once. Instead of adding the
Bumper service to the manifest in Step 2, add the following:
http://schemas.tempuri.org/2006/08/mazesimulator.html
http://schemas.microsoft.com/robotics/2006/01/simpledashboard.html
This creates an instance of the Maze Simulator and a Simple Dashboard.
The Maze Simulator then creates Bumper and Differential Drive services.
NOTE: I copied the manifest for MazeSimulator to the config directory
to make it easier when typing dsshost commands, but this is not necessary.
-----------------------------------------------------------------
Follow Robotics Tutorial 2
Error: Page title is "Tutorial 1 - Connecting with Services"
The following references do not seem to be needed:
System.Runtime.Serialization
System.Xml
Code fragment for Step 1 does not show the existing partnership for the
bumper. Not a problem, but it might confuse some people. The order is
not important.
This tutorial is not much use unless you can press the bumper.
If you drive the robot into a wall, there is a flood of bumper
messages (and motor off messages) but they don't stop until you
stop the robot or back away. This is because the bumper is still
in contact with the wall. Even then, there can be a backlog of
commands in the queue and it takes a long time before the console
stops displaying bump messages!
Does this tutorial actually send motor commands???
-----------------------------------------------------------------
Follow Robotics Tutorial 3
Not easy!!!
What is the difference between a drive and a motor? This is not
explained. A differential drive has two motors.
This code uses a generic contact sensor. We don't really need to do
this to get our code working.
Have to trigger wandering by pressing a bumper. This is a nuisance
when you don't have a physical robot.
_randomGen() and ValidatePowerLevel() are not defined.
Got them from the tutorial solution.
Started it off by running the robot into a wall. At first it
seemed OK, but it backed up WAY too far. Then it got stuck up
against a wall with a series of bumper/front and bumper/back
messages. I don't understand. It seemed to be jerking off!
The problem seems to be that the robot "climbs" the wall, and
this tilts it so that the opposite bumper comes into contact
with the ground. If it gets a message from the wrong bumper,
it will drive in the wrong direction and this just makes things
worse!
Eventually it left the wall, but quickly turned again and the
same thing happened.
I tried changing the geometry of the bumpers. If you make them
higher, then the robot gets caught on the wall much more often.
I ended up making them thinner so that they have more ground
clearance, but it did not solve the problem.
Perhaps a better solution would be to keep track of which way
the robot is driving, and then always reverse when you get a
bumper message. I have not tried this out.
There are heaps of bumper messages. This code is very naive.
It just keeps sending commands without waiting to see if they
have had any effect. That's the problem with a multi-threaded
message passing system. How can you block?
Seems to turn while wandering. Why? The only commands to the
motors are move forward/backward or rotate on the spot. (See
below -- I figured it out.)
Time periods are way too long. Needs to reverse direction briefly
before turning so that the bumper disengages. The code suggests
that it does this, but I am not sure.
I didn't see any bumper release messages.
Problem seems to be that there are too many messages queued up.
The console is WAY behind and there are hundreds of messages
flying past. When a bump gets hit, there should be a "dead"
period while the robot performs its moves. Then let the bumpers
operate again.
Put in a "dead zone" which made it better, but it still does turns
and other moves long after it has escaped from the wall. There are
bumper packets flying all over the place! Need to poll the bumper
after moving back, then flush the queue if it is not set.
Added a Stop immediately after it detects a bumper pressed.
This should allow the robot to settle down instead of driving
hard into the wall and jumping around.
Anyway, it is doing something. Not working well, but at least
the code is running against the Simulator rather than a real
robot.
-----------------------------------------------------------------
Robotics Tutorial 4
Don't need this because I am using the Dashboard. However, it
would be good to add because then you would not have to enter
the host name and port into the dashboard every time you run
the program. Maybe later ...
-----------------------------------------------------------------
Robotics Tutorial 5
This is the "Explorer". It talks about overruns due to message
flooding! There is code to dump the queue, but it is complicated.
Explorer code is under misc, not in Tutorial 5 directory.
dsshost -port:51000 -tcpport:51001 -manifest:"samples/Explorer.manifest.xml"
Does not work.
Started an Explorer service manually from the Control Panel.
It ran and seemed to be doing stuff (according to its state).
However, there were errors in the Console Output that the
simulated robot does not implement a RotateHandler. So it
appears to be calling the simulator, just nothing happening :-(
Posted a message to the Newsgroup about Rotate, and was
told to copy some code from elsewhere and "good luck".
Posted a message to the Newsgroup about flooding.
George supplied a code snippet from Traxster Motor.cs,
but it is still difficult to understand.
bumper.ContactSensorArrayOperations is a Portset.
In the class there are P0..P6. These represent the
ports for the various operations that can be performed.
They are NOT different contact sensors!
However, I had to use the make the internal variable
bumperNotificationPort a global instead of _bumper AND I
had to use the Replace port (P3) instead of the Update port
(P4). I don't understand why.
Now there appears to be a problem that there are two threads
running and they are both issuing motor commands. So I put in
a global variable to synchronize against. However, the robot
still runs into walls and then continues to bump up against
them. Not sure if this is because the wrong sensor gets
triggered or not.
The console seems to be a long way behind.
Sometimes the robot moves in an arc. How? The only motor
commands are to move forward/backward or to rotate! After
playing with the robot using the Dashboard, I finally figured
this one out. The simulation is too realistic! It actually
incorporates inertia and the motors do not come up to speed
instantaneously.
My reasoning is as follows:
1. The robot has inertia. This means it takes a while to get
going, and once it is going, it takes a while to stop. It's
one of Newton's Laws.
2. The motors take a while to come up to speed, especially when
they have to change direction. So immediately after a rotate,
one of the wheels is always going the wrong way when the robot
decides to drive off. This wheel will slowly come up to the
same speed as the other one, and in the meantime the robot
drives in an arc. Ain't physics wonderful?
These are real physical issues, and they show how well the
simulator actually emulates the real world.
This effect could be eliminated by stopping between the rotate
and translate commands. However, you would have to wait for a
little while for inertia because stopping is not instantaneous.
Eventually resolved most of the flooding issues, commented out
most of the logging so that the console has a chance to keep up.
Document what I have done and post to the Internet.
It's not perfect, but it's a start!