Sord's bEEtle was the reigning champion of the Hallway race for months before being edged by a tenth of a second. Now he's laid out the details for all to share. The first part is about the steering. Staying on the track is key. The second part talks about the wiggle, which makes the bEEtle go very fast.

While staying on the track will only help you in the races, the wiggle effect can make your wheeled rover go faster anywhere. Enjoy.     -Sprocket

Building
The bEEtle
by Sord

The beetle has four physical components: a steering wheel, a large motor, and two track sensors. The motor should be set at 100% and the two track sensors need their range set (I found 1.3 to work well), but all other settings are set dynamically during the race and are not affected by the initial value.

Steering

Since our main goal is simply to stay on the track while going really fast, most of the beetles wiring is steering related. The beetle uses the system of feeling for the edges of the track and turning away whenever an edge is found. But rather than having a fixed angle on the feelers, the beetle attempts to set them to the widest angle possible.

Step 1 The first step is to setup the track sensors so that their angle is set based on a variable, rather than being a fixed value. First we add a variable that we will use to update the angles. For one sensor, the variable can be wired directly to the track sensor. I picked the left track sensor because its angle should be in a positive range and I'd like to set the variable to a positive value.
Step 2 For the other track sensor, run the variables value through the value2 of a subtract component to get the inverse. Use the output of the subtract to set the track sensors angle. The subtract component's value1 also needs to be fixed at 0, but since that is the default, it doesn't need to be changed.

At this point, we can set the angle of both track sensors by setting the variables value. The next step is to have the angle updated based on if the track sensors are on the track or off the track.

Step 3 We will need another variable to hold the current step size that we should reduce or expand our angle. Since track sensors default to the off state, we will set the initial variable value to the value we want when both track sensors are off the track. My assumption is that if both sensors are off track, then I am scanning too wide of an angle (one sensor is off the left side and the other is off the right side). The are of course other possibilities, but they generally mean I have lost the track and don't have a good chance of recovery (we'll eventually try anyway, but it's not where I want to focus my efforts). So, if I'm scanning too wide, I need to reduce my angle, so I set the initial value to a negative number, -4 in this case.
Step 4 Now, eventually we will reduce the angle to the point that one of the track sensors is back on the track. At this point we want to stop (or at least slow down) the reduction rate. So in response to a TurnOn event, we will increment the variable by +3. Once both track sensors are hooked up this way, if only one registers as on track, we will still continue to reduce our angle (the variable will have a value of -1), but if both sensors are on track, we will start to increase our angle as the variable will now have a value of +2.
Step 5 Of course, if the track sensor goes back off the track, we need to undo our +3 increment. So in response to a TurnOff event, we will increment the variable by -3.
Step 6 That setup one track sensor to modify our step size variable, so now we repeat the same wiring for the other track sensor (TurnOn sends an incrementBy of +3 and TurnOff sends an incrementBy of -3).
Step 7 We now have a fully operational step size variable, but we need to do something with it. Originally I had a loop timer setup to query the step variable, but whenever I wanted to try a different step size, I needed to update all four wires coming from the track sensors. To make my life easier, I decided to route the step value through a multiply component so I could scale the step size by just changing one wire. So, add a multiply component and wire the step variable to set the value of input1.
Step 8 Add a loop timer and set its TickTime to 0.1 seconds. This is the frequency that the angle will be updated.
Step 9 Wire the loop timer to set the input2 on the multiply whenever a tick event happens (meaning every 0.1 seconds).
Step 10 Now we can wire the multiply component to increment the current angle variable by the output of the multiply whenever the set event happens. Note that this is the set event and not the change event. Most of the time the output of the multiply will not be changing, so we must look for the set event (caused by the loop timer setting the input2 value). We will also get some extra events when a track sensor changes our step size, but the extra events just give a one time boost to the rate of change and can be ignored.
Step 11 Our track sensors now will constantly update themselves to try and maintain a lock on the edges of the track. The one last thing we need to do is some sanity checking so that we don't go outside some reasonable bounds. To do this we add a rangeTest component and set the minimum and maximum values to some sane values. I happened to pick a range of [10-75], but I'm sure these values could be tweaked to improve performance under unexpected conditions (like being bumped).
Step 12 Wire our current angle variable to set the input of the rangeTest. Then wire the rangeTest to set the variable to the rangeTest's maximum value if the aboveRange event happens. This will prevent the angle from exceeding our maximum value.
Step 13 Also wire the rangeTest to set the current angle variable to the rangeTest's minimum value if the belowRange event happens. This prevents the angle from dropping below our minimum.
Step 14 Our track sensor will now do their best to stay right at the edges of the track. Next we need to wire up the actual steering. Fortunately this part is much easier. However, for the first step I took a shortcut and used the fact that a track sensor's ON state is equal to the value 1 and that the OFF state is equal to 0. You could also set the values based on the turnOn and turnOff events, it just would require 4 wires instead of two. To use my shortcut, just wire the left track sensor to set the input1 of a subtract component to the track sensor's state.
Step 15 Then wire the right track sensor to set the input2 of the subtract component to the right track sensor's state.
Step 16 The output of the subtract will now be -1, 0, or +1 depending on the states of the track sensors. It will be -1 if the left sensor is off the track (=0) and the right sensor is on (=1) since (0-1 = -1). This works out great since if our left sensor is off the track, we want to steer to the right, which would be a negative steering angle. Of course, -1 isn't enough of a steering angle, so we need to multiply it by some factor. So wire the subtract to set the input1 of a multiply to the output of the subtract and set the input2 of the multiply to a fixed value (I used 8 for the beetle).
Step 17 The final step is to wire the output of the multiply to set the angle of the steering wheel. You now have a fully functional racing rover. Try it out. If it doesn't work, you probably missed changing one of the default values for a wire. Common problems would be setting a variables value instead of setting the incrementBy property, or having a multiply set a fixed value instead of passing on its output.
The Wiggle If you do some testing, you may find that it doesn't go quite as fast as some of the other rovers. That's because a design flaw in the physics engine gives turning rovers a speed boost, so it is beneficial to always be turning. It is a fairly easy change to add a continuous wiggle to a rover, so that will be our first enhancement.
Step 1 The first thing to do is to setup an oscillator. I did this using two one shot timers. Each timer will set the other time when it triggers cause an endless loop of events. To start, add two timers and set one of them to start with a TickTime of 0.1 seconds.
Step 2 Add a wire that will set the TickTime of the second timer to 0.1 seconds when the first timer's tick event happens.
Step 3 Then add a wire from the second timer back to the first that sets the first timer to 0.1 seconds when the second timer's tick event happens.
Step 4 You now have an oscillator and can start generating steering inputs from it. However, since we don't want to override the input we already have, we use an add component to add the wiggle to whatever steering we are already doing. Have one of the timers set the input1 of the add component to a small positive steering (I used +3) when the tick event happens.
Step 5 Set the other timer to also set the input1 of the add to a small negative value (I used -3) when the tick event happens.
Step 6 Finally, delete the wire from the multiply to the steering and instead route it though the new add component. The multiply should set input2 on the add to the multiply's output and the add should set the steering angle to the add's output.

Test out your enhanced rover and you should see a significant improvement.

Other Stuff

The other enhancement I made to the beetle was to detect a lost track condition (usually plowing into a wall) and to backup and attempt to get back on the track. This enhancement is of questionable merit since the race is probably lost if it ever has to be used. But it is an interesting concept and I'm sure it can get put to good use in many other circumstances.

To detect a lost track, I hook both track sensors to an Or component, if the Or triggers a turnOff, then both track sensors are off the track and I set a timer for 0.5 seconds. If I don't get a turnOn in that time (which would pause the timer), I reverse the engine and turn the steering wheel to one side. I also set a second timer that, once expired, sets the engine back to forward and turns the steering wheel to the other side.

You can reach Sord at sord@bigfoot.com

MindRover TM , MindRover: The Europa Project TM , and Cognitoy TM are trademarks of CogniToy, LLC, 1999.