Another year, another successful VEX Nationals.
Last weekend, a few dozen volunteers, 70 high school teams and hundreds of students, staff and parents took over the Massey University Recreation Centre in Albany for the annual national competition.
This is the event many teams have been working all year towards, attending the scrimmages supported by our dedicated AURA volunteers, spending time with AURA mentors and pouring their creative efforts into their robots.
AURA provided the bulk of the volunteering force, with over 20 volunteers working over the four days ensuring the competition ran smoothly. It was great to see both some of our graduate members taking time away from lawyering and engineering to volunteer, and some of our incoming undergraduate members giving back to the competitive community they’ve been part of for so long. With new members like these, AURA will continue to be a powerhouse for both volunteering and competition efforts for years to come.
While all of our volunteers did a fantastic job, special commendations must be given to:
Jess Chase, our Volunteer Officer, who was officially recognised as the Volunteer of the Year, and who organised all of the volunteers for this years competition.
Nathan Allen, whose technical expertise and competition software integration efforts made all of our efforts so much more efficient.
Rui Wen, for his help in communicating with visiting Chinese teams.
George Gillard, who was on the organising committee for nationals.
We’re happy that so many great high school teams will be joining us this year when we travel to the VEX Robotics World Championships this April in Louisville, Kentucky. Hopefully, we will continue New Zealand’s outstanding performance and bring home another stack of trophies in both the High School and University division.
I was pretty humbled today, when I was contacted with a question. I wrote quite a long answer, so I thought I’d share a little of what I’ve learnt over the past 7 years of Vex programming with you all.
How do you do a ‘good’ turn?
Well, this is basically the only question when it comes to programming robots. It’s simple to program a robot in a perfect world, however the difficulty comes in when you have real-world factors to deal with. The major factors are:
• Battery power: consecutive runs have diminished battery voltage, resulting in reduced motor power
• Motor/physical inconsistencies: motors are not all built the same, and friction in the robot’s drive trains are generally different also.
In a perfect world, programming robots would be simple. You could, for example, pick any motor you wanted, install it in your robot, go forward for 1 second, then turn off. This would put your robot in the same spot every single time you did it, no matter which motor you chose. That would just be magic, right? Therefore, the major goal is to learn techniques to counteract some of these pesky real-world issues.
First of all, don’t use timed movements. It sounds like a great idea at first, because of its simplicity, but it is literally not worth your time. Sensors are the key here, and in particular, my favourite vex sensor, encoders. Encoders count the number of wheel rotations, allowing you to effectively track where your robot is. Quadrature Encoders, like those used in Vex, have the ability to track the direction of rotation as well as the magnitude. One thing to note about encoders is that they should be placed as close to the wheels as possible, because the further away they are, the more ‘slack’ they will have. Preferably, the encoders will be on the same axle as the wheel, and the wheel’s normal square inserts are replaced with metal inserts used for gears. If you haven’t done this already to your wheels, you really should – it makes a huge difference, in both programming and driver control.
So, the question now becomes, how do I use encoders to turn/drive straight?
1. Translate your units into something easily understandable
Many people skip this stage, and end up spending many hours more than they need to, developing their routine – all because they are attempting to use abstract units. Do not fall into this trap. In this case, the output from the encoders is not any recognised unit, so we will say its output is in “ticks”. It is very easy to visualise measurements in degrees and centimetres (or inches if you prefer), and makes adjustments much easier. To begin setting up your units, turn on the robot and spin around exactly 10 times on the spot, then record the encoder values you got back for each wheel. Absolute these values and take the average, and lets call this value
X. What you are looking for is the number of encoder “ticks” per degree of robot rotation, which is
X/3600, or the number of ticks recorded by the encoders divided by the number of degrees turned. In your code, assign this variable to a constant variable as something like
ticksPerDegree. From here, you can say, “I want to turn 45 degrees”, therefore, “I want my encoders to move 45*ticksPerDegree ticks each”.
You can do this same method again with driving straight as well. Drive forwards 3m and record the ticks required for that distance. Using the same maths you can calculate
ticksPerInch if you prefer).
2. Functions. Functions everywhere.
Functions are building blocks that you create for yourself. If you ever think to yourself, “Hmm, perhaps I should make a function for this”. You might as well do it, you may find it’s more useful than you first thought. As an example, I often use a function called
driveOn(int leftSpeed, int rightSpeed), which simply sets the respective motor speeds. It sounds simple but is really quite useful. It also means that re-using code on new projects is easy. I can copy and paste a ton of code, and then only change the contents of this driveOn function. It will work exactly the way I want. Similarly, what we are looking at creating now is a function which allows us to program, with little care for the real-world factors. To understand how to do this, I will quickly go over a P (Proportional) Controller.
3. P Controller:
When you turn on an oven/hot water tap, it starts cold and warms up over time. No doubt you’ve learnt over the years, that if you turn the hot water on full blast, it warms up faster, when it is at the temperature you want, you can adjust it to the warm temperature you originally wanted. What you are doing here, is being a P controller, you are taking into account how much it needs to warm up, and telling it to ‘overshoot’ your target, then as it gets closer to the target, lowering the amount you overshoot, as it reaches your desired temperature. The same goes for robots, if you want to drive forwards until your encoders reach an average of 1000 ticks, you could drive at max speed till you reach it, then cut your motors. That will cause you robot to overshoot your target, as it will still have forwards momentum when the desired distance is reached. You could drive at the minimum power needed to move your robot, but your autonomous would end before you drove a metre, so clearly, we need to do something more intelligent here.
4. Implementing a (distance) P controller on encoders
What we need to do here is the same as you would do if you were running up to a line, the further away from the line you are, the faster you move – and as you get closer to the line, you slow down so you can stop on it accurately. The equation for this is therefore logically very simple, you want to set the motors to
P*(T-E) where T is the target number of ticks you want, E is the current number of ticks, and P is the proportional constant, such as 0.2. Essentially, what this P variable states, is that for every tick the encoders are off by, increase motor power by this much. Naturally, this won’t work by itself, because the motors need a certain power in order to start moving, and as you get close to your target,
P*(T-E) will give a value lower than this value, therefore, you will need to find the lowest motor values needed to move your robot, both for turning and driving straight, and add the outcome of
P*(T-E) to it – so, as your reach the target value, you will be moving at the minimum speed needed to move – meaning you will be accurate near the end. However, there is the larger issue of driving straight that still plagues your code.
5. Implementing a (wheel difference) P controller on encoders
We have now essentially removed the real-world effect of the battery slowing our drive, as we are working with distance. Now, it’s time to remove the other real-world effect, mechanical differences between the two sides of the drive. This is actually very similar. In a perfect world, we would like the two encoders to have the same value when driving, so, logically, the solution is to fight to keep them at the same value. To do this, we simply use another P controller at the same time as the previous one. This time, we are going to take the difference between the two encoders, and use that. Let’s assume we are driving forward, and both values are going up, we can do set ‘diff’ to leftEnc – rightEnc, which will give us the amount the left wheel is ahead of the right wheel. From there, we can simply subtract
diff*P2 from the left motor, and add diff*P2 to the right motor. Currently, the line of code implementing the function that sets motor speeds could look something like:
driveOn(minSpeed + distPValue - diffPValue, minSpeed + distPValue + diffPValue)
6. Making sure the values work nicely together
If you think about it, when you are going max speed, 127 forwards because of your distance proportion, your
diffPValue may not even have a chance to do anything, therefore, it’s a good idea to ‘cap’ how much these values can actually affect your motors. You may want to limit distPValue in this case, to
120-minSpeed, so that the maximum value
minSpeed + distPValue can be, is 120. This means
diffPValue can take effect all the time.
7. Writing the overall function
So, when everything is said and done, you should now be able to write a function that allows you to negate real-world variables, and drive around easily, using encoders in this case. You may want to increase speed over time, using a timer, or, you may want to use a timer to accelerate up, over the first half-second, it’s really up to you. The beefy bit of code I wrote for the vexU programming skills champion robot used both of these and everything else mentioned here, but nothing else. No Integral and no Derivative (as are used in PID control). Just P, plain and (mostly) simple. The main trouble is using these formulae when turning and moving backwards, but I’ll leave that for you to work out ;)
8. Code smartly
People love to over-complicate code. They love their ternary operators. They love saving bytes of memory by not using variables – which could have descriptive names to make the logic, well, logical. Don’t be this person. Use comments, make simple variables which allow you to code using real-world units. Avoid ternary operations like the plague, write functions for reused code, and use constants/strings to help determine what you want to do, e.g.
autoDrive(LEFT). Encoders are, in my mind, the most reliable sensor. They don’t drift, I’ve never seen one break, they are accurate if you drive correctly and they work in any light. Use them.
Hopefully this gives a little insight into what the world champion code will have looked like, the major drive function (called
autoDrive) was about 89 lines in total, and was:
autoDrive(float dist, int dir, bool flip) (
flip in this case simply reversed left/right, to make blue/red auton easy) and could be called like:
autoDrive(100, FORWARD, false) // Drive forward 1 metre
Good luck for “Nothing But Net”! I’m planning on putting up more tutorials in the coming months, I want to see programming skills be even fiercer.
– Kerey, AURA 2015
This is the video that we entered in this year’s RECF educational video competition (the video was not eligible to win the competition because it exceeded the maximum length).
We use the term “Back Voltage” here rather than “Back EMF” because the video is aimed at an audience that understands what a voltage is but doesn’t necessarily understand the term EMF.
With the release of VEX Sack Attack, many teams have begun to talk about using transmissions on their drivetrains. This is probably the best game ever for a shifting drive; speed is needed due to the large field and race for the easy to access sacks (by the goals), and torque is needed for the inevitable push battle that will happen at the end of the game when fighting over goals. Of course, a traditional drive cannot have both speed and torque unless many motors are used, but it seems difficult to use more than four, maybe six, motors on drive this year, as the sacks are rather heavy, and a 30″ reach will be needed for most robots this year. Of course, strafe will also be useful so that you can defend your troughs easily, and quickly move sacks from you opponents troughs to yours.
What Cameron (TooMuchStategy) from AURA has built to help solve these problems is a drive that switches between traditional tank drive and X holonomic. It uses four 393 motors in the the torque configuration, but this number can be easily increased if you have motors to spare. It uses four pneumatic pistons to shift between X and tank drive. It gets about 8 shifts per tank – we have two tanks on at the moment because we have not yet added pressure regulators; you don’t exactly need 100psi to open up the wheels.
In tank mode, the drive ratio is a bit on the slow side, at 1:1. This is, with four 393’s, rather powerful however, and will usually be enough to win pushing battles. In X mode, the drive ratio is slightly over 1.4 (Squareroot 2) when traveling forwards or straight sideways, and 1:1 when going diagonally – see the “Why is X-Drive Faster” article by Oliver. This makes it highly maneuverable.
As for navigating over or around sacks, in tank mode, driving over sacks is very effective The wheels can easily climb over the sacks. In X mode, sacks can get dragged along with the robot as the wheels try to push them sideways. This system has an advantage over other holonomic systems in that it can switch to tank mode to drive over sacks, then switch back to holonomic mode.
In this article, Oliver explains why x-drives have a higher effective gear ratio than tank drives.
This seems unintuitive to a lot of people, but an X-drive robot has a higher maximum speed* than a tank drive robot with the same gear ratio.
To best understand this, it helps if we consider what happens when the robot drives diagonally.
Figure 1: These two drive bases have identical gearing and an identical number of motors, but drive #1 is X-holonomic and drive #2 is tank.
Drive #1 can move in the y direction by moving only the left and right wheels. The top and bottom wheel rollers will spin freely. In this case, it will travel at the same free speed* as drive #2 would (but with half the power, because it is only using half its motors). Similarly, it can remain stationary in the y direction and move in the x direction at the same free speed as drive #2.
When it does both of these at once, it travels in the x direction at the free speed of a tank drive while also travelling in the y direction at the free speed of a tank drive, so its total free speed is greater than that of a tank drive. The direction it travels in is halfway between the two directions, or towards the front of the robot. For the same reason, an H-drive robot (tank drive with a central strafing wheel) will travel faster if it is driving forward while strafing than if it is simply driving forward. Similarly, in some computer games it is possible to run faster by strafing while running. (http://en.wikipedia.org/wiki/Strafing_%28gaming%29#Straferunning)
The amount that an X-drive is effectively geared up by relative to a tank drive is 1.414, or sqrt(2). This is the ratio of the side length of a square to its diagonal length. The force of the drive is reduced by the same amount because the force in each direction is half that of a tank drive and 1/2 x sqrt(2) = 1/(sqrt(2)). This means that the product of the free speed and the stalling force remains the same so in the ideal case an X-drive is not less powerful than a tank drive, it is just geared differently.
However, an X-drive will usually have greater frictional losses than a tank drive because of friction between the omniwheels and the omniwheel rollers.
* In this article, “maximum speed” and “Free speed” refer to the speed that the robot would travel at if its motors were rotating at their free running speed of 100 rpm. This is sometimes called the ‘theoretical speed’ of the robot, and it depends only on the gear ratio, the size of the wheels and the motor’s rotational free speed. It is different from the actual observed speed of the robot, which will also depend on motor torque, friction and the mass of the robot.
French version / Version française: http://botfatherfr.weebly.com/x-drive.html
The chain lift acts in the same manner as a 4-bar linkage or a 6-bar linkage in that whatever is attached to it will maintain the same orientation throughout the movement of the arm.
Typically chain lifts consist of two bars affixed to driven gears and two high strength sprockets that are able to be mounted i.e. 18, 24 or 30 tooth sprockets. The sprockets are mounted on either the inside or the outside of the bar and then to the tower, a chain is then wrapped around them forming a loop. The chain and tension it puts on the sprocket as the bar moves causes the sprocket that is bolted to the intake and thus the intake, to move. The sprocket on the intake moves relative to the sprocket on the tower ultimately maintaining the orientation of the intake.
There are a few ways to build this style of lift one way, with the sprocket inside the arms is as follows:
Note: With this style you will likely want the towers to be as far apart as possible.
• Build towers and fix a bar onto a gear as you would with a 4-bar linkage (you can also use a sprocket instead of a gear).
• Attach a sprocket to the inside of the tower on the pivot point but do not insert the axle into the sprocket else damage will be done.
• At the pivot point on the intake, bolt a sprocket to the intake then run an axle through this sprocket to the pivot on the arm.
• You might want to add some more support for the axle addition to the delrin bearing block on the arm’s pivot point; how this is done will likely depend on the spacing (e.g. another delrin on stand-offs bolted to the arm, a delrin on angle/L channel, a bracket or another method)
• Space the sprocket on the intake out so that the sprockets line up with each other
• Place tensioners as close as possible to the sprocket either end of the bar.
• Orientate the intake as desired then wrap the chain around and link it together. Ensure that at the intake end the chain goes under the tensioners and that it goes over at the tower end so that maximum contact with the sprocket is maintained
Some possible tips:
Chain is prone to slipping; when this happens the entire intake will tip forward or backward. Tensioners (usually spacers and/or stand-offs or even a bolt through the arm) positioned in the right place can ensure the chain has a large contact surface with the sprocket throughout the lift and will prevent slippage.
If you find you still have slack in the chain and cannot take out anymore links, check the tension above and below the sprocket, if they are vastly different trying moving the whole chain around by one link, if they are still roughly the same after that and you are using 18 or 30 tooth sprockets, try turning one sprocket (either at the intake end or at the tower end) by 90 degrees. This method works in taking up some of the slack because these two sprockets do not have the rotational symmetry like the 24 tooth sprocket: if directly above the bolt is a tooth, turn the sprocket 90 degrees and there will be no tooth (see the red lines in the image)
The chain can often snap for various reasons. Teams have found that because only some of the chain moves around the sprocket, it is possible to cable tie links together. Another idea might be to build a guard around the chain (if doing this out of polycarbonate, be aware of the limit allowed on competition robots).
Seeing as there are different sizes of sprockets that can be bolted onto metal, one can create a lift that will cause the intake’s orientation to change throughout the lift essentially simulating the lengthening and/or movement of bars in a 4-bar linkage.
One of our robots, Matlab, used a variation on the chain lift to reach 30″ – See photos and videos at http://www.aura.org.nz/archives/955
Good luck designing and building! If you have any questions, feel free to ask us on forums or e-mail email@example.com
The four bar linkage is perhaps the most common lifting mechanism used in the VRC;
the ability to lift your intake in a very simple way without rotating it is an extremely appealing idea. For instance, in the finals of the 2010 World Champs (Clean Sweep), all three robots in the winning alliance used a four bar linkage, and for 2011 (Round Up), 5/6 of the finals robots used a four bar.
In theory, a four bar should lift to 36 inches – if your arm starts at 45 degrees to the ground,
mounted at the top of your 18” robot, and lifts to 135 degrees, a rotation on 90 degrees, in theory it could reach that high. However, there are many reasons that a four bar cannot do this; for instance it is practically impossible to get the pivot of your arm at the top corner of your 18” robot, and in many cases it is not practical to have the end of your arm in front of you intake, e.g. if you have a claw mechanism. The main problem, however, is that your top arm cannot reach the ground, and the closer you bring your bars together, the less stable your lift will be. Combined, these factors mean that it is very difficult to make your arm reach even 30”.
But wait, aren’t there 30 inch goals this year?
Luckily for all the high school teams, College teams have been playing with 30” goals for a while as there were 30” goals in College Round Up. The teams found many solutions to this problem, such as combining sliders and a four-bar on one robot, or having LOTS of linear slides. However, the solution that AURA used to much success is one we call the six-bar linkage.
A six bar linkage is basically two four bar linkages superimposed on top of each other. What it does is effectively make a four bar where the top bar can go all the way from the top corner of your robot to the ground at the bottom of your robot. This allows your arm to be several inches longer than a four bar, and allows a reach of beyond the magical 30 inch mark.
A six bar can theoretically be powered in one of three ways; either through both bars as a normal four bar, through the middle bar only, or through the bottom bar only. The bottom and top bars are mainly to keep your intake from rotating, however it is possible to have the bottom bar powered. It is beneficial in some ways that you do not power only the bottom bar, as the force will have to be transferred through several joints, which can cause greater friction in your lift. However, if you power only the bottom bar, the pivot of the middle bar on the six bar can be at 18”, as it does not need to be bolted to a gear, etc. This can give you extra height, if for some reason you need to lift higher.
The next question is how much power do you need on a six bar?
Compared to a four bar, the main difference is that the intake is being lifted at a greaterdistance, and therefore has a greater torque effect on your arm. In our case, the distance was so large that our robot actually found it easier to lift goals than its intake. An easy estimate would be to say that you would need about 15% more power on a six bar than the traditional four bar lift. Of course, this varies hugely on the weight of whatever you have on the end of your arm, more so than a four bar, as the weight is being held at a greater distance.
The last thing to consider is that there will be a greater force on all the components in the lift. We burnt out several motors and broke teeth off high strength gears. Remember to build everything in your lift system very sturdily, and use plenty of power in your lift, otherwise you will have problems as we first did.
I hope that anyone that uses a six-bar has success with it. If you have any questions about it, please do not hesitate to ask, either by email at firstname.lastname@example.org, by PM on the Vex Forums, or by posting in the thread everyone can see the answer to your question.
– Cameron aka TooMuchStrategy on Vex Forums