24C Round Up Code

If you’re keeping track of the position of your robot on the field you ought to be able to enter in a position you want the robot to be into a function and have it get there in the quickest way possible, correct?

~Jordan

I would say so. I wonder how much this would really help though. Assuming you are keeping track of your position with encoders and keeping track of direction with a gyro you are still pretty limited to what you know. It seems as though things that mess up dead reckon runs (that use the same sensors) would just as easily mess this style of code up (ie. a robot beats you to a goal that you are both going for and your wheels slip when you crash into them)

For this bitmap are you just using a variable to represent x and a variable to represent y or are you doing something more complex?

~DK

If you could figure out how to use the accelerometer to track position, using that along with the gyroscopic sensor would be pretty awesome.

~Jordan

Several people have tried to get the accelerometer to track the position of the robot, including myself, and I’ve never seen anyone who has succeeded.

Here are some threads that you can look at:

https://vexforum.com/t/programming-vex-accelerometer-1-0/18310/1
[

This is probably the biggest advantage of such a system, and can be very useful. If you are going to try to do this, I suggest that you look up wavefront propagation, and A Star path finding algorithms to look for the best path.

](ROBOTC)

It’s my understanding that KTOR was able to succeed with this. (But that’s just what I heard from a fellow team member.)

~Jordan

Both Wavefront Propagation and A* would be good starting points for the Programming Skills Challenge. They are fairly easy to understand and implement by high school students. They both assume, however, a map with fixed obstacles. Using them in the autonomous portion of a match and taking into account other moving robots and game pieces would make this much more complex.

Jay

So I graphed out 24c’s function against a power of 3 function used by team 80 this year. (Originally posted by Quasar) I made this graph to explain power curves and logarithms to the kids this year and just added the 24c function on it since it peaked my interst.

(I also made sure I put an integer rounding at the end to have it be the same math as what the motors saw. That’s why it’s a bit jagged. 24c starts as floats but the setting of the motor is putting it into an integer so the explicit conversion at the end rounds the numbers down if I remember my conversions right.)

About the graph:

  • The red line is straight value of the joystick if you just said motor = joystick ,
  • the green line is a power of 3 calculation,
  • the blue line is just a half power function,
  • the purple line is 24c’s function using power of 5 and offset of 15.

You can see the difference from the red line how much less power you have through the range of of the joystick yet right near the end you get right back to full power. This helped our kids not jerk around the robot and give a greater control. You get a wider range of that mid-power control value without having to be so precise.

So a few questions:
In practice were you happy with the about 1/3 power you got for most of the joystick range? By the time you were nearly at the edge, you were getting right back to almost full power. Was that 15-50 range the sweet spot for you for maximum maneuverability?

Did you really hover around the middle or most of the time just gun the joystick to full blast?

Was the motor value of 15 a minimum to get the robot started or keep it moving? Even so, if you’re that close to the center of the stick, just setting it to zero seems to be a pretty good idea.

Again, thanks for posting your code!

The previous comments about using #defines for constants is always good practice - but since you are off that PIC onto a bigger beefier chip, the extra few milliseconds may not make that huge of a difference. But using #defines for constants is still very good practice.

You could also replace a bunch of if/elses with a switch/case. But whatever works for you is really what is best. And of course if it works and has no bugs is the best program of all. I personally don’t like using a lot of breaks from the if conditions in case you want some common clean up actions before looping back to your while test and then breaking out cleanly. But sometimes it is the best course of action.

Side note: I was taught old school to think about McCabe complexity calculations and keep your code more streamlined so not a lot of breaks or side jaunts away from the main logic stream. In theory, your code should have fewer errors, but the jury is out on that. However, the next guy along should be able to read and understand your code easier (and more importantly fix it without having the on call guy call you at 3am when it probably broke and you just want a good night’s sleep). (Maybe that’s what we should be teaching these kids about programming - how to program so you don’t get those pesky on-call calls when you least want them!)

A good beginner tutorial on A* pathfinding can be found here

Suggestion: use the buttons on the LCD to select your autonomous - it saves a sensor port…

Great code - I’ve learned a lot looking at it, and reading jgraber’s comments…

//Andrew

Regarding the “break” methodology promoted by me, from “Best Perl Practices” book.

I looked up McCabe complexity in wikipedia:

Break statement methodology reduces the McCabe complexity, or at least, just points out that it is low. It allows the style of a CASE statement, but with arbitrary IF (condition) that may not fit a CASE statement.
For the following examples, I’m refering to following the code by eye.
Consider a Case statement:

  • when you find the applicable case, do block, then jump to bottom.
    Consider an IF (cond) {block} ELSEIF (cond) { block}… tree:
  • when you find the applicable case, do block, then find the correctly matching endif/closing brace.
  • If there are random linear statements between If statements, they are hard to notice.
    Consider a list of IF (cond) { block; break}:
  • when the condition applies, do that, then jump to bottom (just like CASE)
  • No need to look for any other conditions.

Using a “fake loop” or another set of block braces {} around the break-tree, inside the main while loop, is a good way to implement the “common clean up”. The break should drop you out of that loop, and into the clean up code.