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!