Showing posts with label software. Show all posts
Showing posts with label software. Show all posts

Monday, February 12, 2018

Loose Thoughts About Time

 In the last post I mentioned feeling that the phones were good to plus or minus a few milliseconds on a 50 millisecond loop.  I don't have any hard data on that, and I'm not really in the mood to go play alien autopsy on the robotics innards with a probe and a scope.

But ... I've been playing around with Python and a Raspberry Pi a little, and thought it might be interesting.  Yeah, I know, it isn't the same thing.  Python is interpreted yada yada yada...   But I'm doing this for fun so it's an experiment worth pursuing just a little bit.  

The first picture shows the basic setup.  Using a cobbler from Adafruit (This is NOT an endorsement, but it works and here's the link : https://www.adafruit.com/product/2028) and some generic LED circuit from I don't remember where,  I added the following Python code.

On a side note, there's a gyro or a BMP280 or something, a potentiometer, and a humidity sensor also on that breakout board.  We'll get to those some other day. :-D 

Anyway, it's crude and ugly, but sometimes you just gotta let your hair down - metaphorically of course - and beyond here be pythons, or at least a screenshot of the useful part.  I put it in as a screenshot because I like the darker theme for IDLE.  I think I used this one, but it's my own hardware so I didn't document it.  Link to dark theme: https://gist.github.com/dsosby/1122904 .
The fun thing here is the millis and stopmillis ... we're basically timing the precision of the "sleep" command.  Now, I think we _all_ can think of better ways to look at time, but for a really crude idea of what's going on, this will get us started.   Here's what we see right off the bat.  When I ran it 50 times at 0.05 seconds each, I was seeing some reports of 51ms, but mostly 50's.  Roundoff error maybe?  Well,run it with blinks of 10 seconds duration instead of 50 milliseconds ... and the very first one comes back at 10010 milliseconds.  This seems plausible to me. 
Remember, the Pi and our Phones are roughly comparable - typically an ARM processor running a Linux derivative at around 1GHZ.   

Yeah, I'm not actually satisfied with the experiment either, and yeah it's going to bother me. 

The "righter" way, of course, is to do what we have in our robotics code and let it lounge around in a do-nothing state until 50 milliseconds elapses then set a physical output and watch it jump around on an oscilloscope.  Then keep shrinking the time until the error is large enough to be a pain.  This might be a fun thing to do with our students in between seasons, but even with what we have, I'm a little more comfortable believing we shouldn't really trust our hardware to be both accurate and precise down to 1-2 milliseconds.




Sunday, November 19, 2017

The Theory of our Autonomous Modes

This one will be short, I promise.  But I wanted to write it down where we can all get to it.

As you know, there are autonomous and driver controlled opmodes in FTC robotics. 
The obvious way to think about programming an autonomous mode is to treat it very linearly - the opmode starts, different bits of logic are put in place, and eventually you drop out the bottom like on a bobsled run or a ski slope. 
In our case, we can think of it as four ski slopes - Red "left", Red "right", Blue "left", and Blue "right."

That ski slope approach works, but it means a lot of repeated code - every sensor read, every motor drive, every turn, each one of these has some code duplicated from elsewhere.  And if you find a bug in how you handle turns in one "slope" you get to fix it for all the turns in that slope plus for all the turns in all the other slopes (or "autonomous opmodes") too. 

That can be a lot.   On the Thursday before a competition it can be too much.

Last season we took a little different approach.  We weren't doing radically different things for most of these steps.  In fact, we were really only doing 5-6 different things for even a really complicated autonomous mode.

Team 11959 had the more complicated autonomous mode last year, and it really was a stitched together sequence of "drive straight," "turn," "detect something on the ground," "stop," "detect something on the side," and "move a servo or motor."   I count that as 6 items.



BUT ... by the time you worked it all together you had 3 turns, 5 straight segments, 4 detect somethings, and 2 move a servo or motor.   14-15 steps altogether.

Here's the approach we ended up using.
Create a variable that tells you what "segment" you're in. 
Create a set of arrays.  One array for turns, one array for straight segments.  The turn array says your "turn" is how many degrees, how forceful, and whether it is clockwise or counter clockwise.

 Let's pretend we have a 6 section autonomous mode that 1) goes forward 10 inches at 25% power, turns right (clockwise) to a heading of 45 degrees at 40% power, goes straight for 50 inches at 30% power, then turns counterclockwise (left) to a heading of 2 degrees at 30% power, then sits still for other things to happen:
TurnArray =  [0, 45,  0,   2, 0,0];
TurnPower =  [0, 40,  0, -30, 0,0];
StraightPwr= [25, 0, 30,   0, 0,0];
StraightDist=[10, 0, 50,   0, 0,0];

Inside the autonomous, we run one loop that steps through each of our states.  It would look a little like this:
static final NUMSTEPS = 4;
int i;
while( i < NUMSTEPs)
{    
  stageComplete = 0;
  switch ( i ) {
    case 0,2:

      //
      stageComplete = driveForward(StraightPwr[i],StraightDist[i]); 
      break;
    case 1,3:
      stageComplete = gyroTurn(TurnArray[i], TurnPower[i]);
      break;

    case 4:
      stageComplete = detectItem();
      break
    case 5:
      stageComplete = moveLever();

      break;
   }
  if (stageComplete) i++;
}


Naturally, we then need ONE instance each of the function to "drive straight," Turn," "detectItem," and "moveLever" ... AND each one of those needs to return a boolean indicating whether the task has been done successfully.  The clever engineer puts a time limit on each one too, so we never get stuck waiting for it to push against the wall or a stuck 'bot.

This whole thing lends itself nicely to being evaluated every 50 ms inside of a "while(OpmodeIsActive)" type loop.   Another "service" that would be nice to see every 30-50 milliseconds is "readSensors()" so all of the data reads are still in one place, and happening at a speed consistent with the limits of the sensor(s).

The really nice thing is that all of the complicated code for making a turn is in one place.  All of the power compensation or other stuff for going straight is in one section, and there is ONE call to each of them.  If we change the interface, we only have to update ONE call to it in each opmode -- 4 altogether, most likely.  Much better than 30-40.

Adding more straight sections or more turns or more whatever, is a matter of populating 4-5 arrays correctly, changing one constant, and updating the switch statement.   







Thursday, October 26, 2017

Software Team 2017 10 25

Wednesday's practice was ... loud.  But we survived.

Here's where we are, and it applies to both teams

Configuration Management:
Howard forked the ftc app from the FTC github, then added an opmode containing the new time-domain based code.  He then went back to the judenki github and forked the ftc app from his account and created a JudenKi branch.  This was downloaded onto one of the laptops, opened in Android Studio, and "built" but not downloaded.
At Wednesday's practice we had the students create a KernelPanic branch (see the pic below) and downloaded that to a different laptop.  Now we have two branches of the same fork, and we should be able to have the students develop in each of these independently and keep the branch updated independently.

In theory, we can then merge the branches into the "master" and keep everything updated together without the hassles we had last year.

Each team then created a Teleop version of the opmode in their own branch - (we discussed the distinction between Autonomous and Teleop), added it to their project, commit the changes, then try to push them back up to github.   We were bandwidth constrained, and that just didn't work.  I don't know if everyone is using the wifi to watch Spongebob covers of Aerosmith videos or what, but Howard took two of the laptops home and will do the github pushes before Saturday's practice.

We also discussed the importance of viewing code as a "data pump" where data comes in, things happen to it, and data goes out.  Our pump works best if we think pretty hard about what we need that data pump to do as we design it.

A WORD ABOUT Time Domain processing:
We have ONE loop, and ONE place to look for "whileopmodeisactive".  This should prevent some of the spinning/no-shutdown or whatever again this year.
PLAN FOR SATURDAY:
1) may need Jim's input, but want to add a Drive class to each and put our common software in it.  We can probably keep this coordinated with some good old cut and paste technology, but ... we shall see what happens.
2) create a "controller input inventory" form ... so when we start adding driver control functions we'll have a documented map to start with ... we have about 20-30 possible inputs, and that provides a huge number of combinations.  If things get hectic in C-2 ("C minus 2" or 2 days before a competition), KNOWING what buttons have been assigned keeps things mas tranquillo (more calm).
3) want to start adding the things we need to make it drive autonomous.  Will need to get a preliminary sensor inventory and will put some students (Propose John and maybe Ethan) to start working up an algorithm for accumulating wheel encoder counts.   I would like to be able to continue reading sensors every 50ms while the thing is turning, and I believe the included method only allows you to command a turn of a certain distance or duration - which it does while in a really tight while loop of its own (meaning nothing else happens during that 1-3 seconds).

I think that may be ambitious enough for Saturday.  If we get all that done, we'll give some instruction on theory (maybe some object oriented stuff?  Maybe some UML with Bluej?   We'll figure something out).

See you Saturday!


Sunday, October 22, 2017

FTC 8578 and 11959 Software Mentor roles and description 2.0

(revised 11 Feb 2018) 

What we need from software mentors ... a simplified version.
This, once more, is my personal vision, and does not reflect that of Columbus FTC or any of the mentors - unless purely by coincidence. It also obsoletes and supersedes an earlier, vastly more complicated version.

In general, our need for mentors is as follows:

Team Mentors
Each team, whether there are 1, 2, or n, needs a dedicated mentor to supervise the software development for that team.

Auxiliary Mentors
 These individuals are useful in many roles. One hopes that they'll work with the students and with the software and grow into "full time" mentors. "Full Time" has no rigid definition, but practically it means making 7/8 or more of the practices.

Computer Setup Tasks
One of those mentors - or a separate one - should accept the following responsibilities - before September, and evaluate the need for an update in mid November and again over the Christmas-New Year's holiday:
  1. make sure the computers have a common or at least similar OS
  2. make sure the version of Android Studio is correct and that Android Studio is configured correctly.
  3. make sure all teams are using a legal and servicable version of the FTC software
Architecture and Training Tasks 
An astonishing percentage of the people I've met who style themselves software architects have huge troubles designing the code equivalent of a privvy, to the point where I'm reluctant to use the term. Regardless, a member - either the one above or a different one needs to ...
  1.  keep on top of the configuration management schema. This takes constant effort, as it gets ignored almost instantly. This means helping make sure that commits are done at the end of each practice and that pushes to github are done often enough to make the catastrophic failure of any given computer a non-event.
  2.  Keep on top of the architecture. To succeed, that is, to add the most value to the students, they need to spend their time thinking about the difficult problems and not chasing down 16 instances of the same bug. This in turn means that we have to leverage some of the object oriented properties of Java. 
  3. Provide training in Linux Command Line, Android Studio, Java, principles of systems engineering, and basics of software engineering. For example, it is profoundly useful for the students to understand how long is 100 milliseconds, some of the basics of how geometry and algebra apply to making the robot do what we need, and on up to some rudimentary PID controller, first order filter, and other things of that ilk.

Java Is as Java Does

We would not seek a battle, as we are; Nor, as we are, we say we will not shun it. Henry to Montjoy,   Henry V ,  Shakespeare Last season I ...