Hey all,
Well, I’m the new designated rookie programmer on my team, 2893, and had to learn Labview pretty much from scratch with no other programming experience, so I’d say only 75% the time I have an idea what I’m actually doing, heh. Anyways, I was wondering what were the possibilities of overloading the cRIO with a Teleop VI? We did a last minute program test in essence, a week before the robot shipped, and the double joystick program I made (with fallbacks allowing each to assume control of the robot, due to our controller failure paranoia), and it didn’t work. Error report on the Driver Station reported that the loop was executing too slowly, or something, and was starving the loop. The programmer beforehand inspected my program and came up with 3 options means of why the program failed :
1: I left a case structure blank with nothing to do to the motors in the drive portion of Teleop.
2: I put all my multipliers in the case structures, and according to him doing that loads up the VI more. Also, he’s saying that putting multipliers as outside of case structures as possible and instead having the structures feed the multipliers info is a better option (I had tons of little individual multipliers in each case structure doing the same operation, but with different constants).
3: I had wayyyy too many case structures, probably due to the fact that I was linking controllers up to control the robot independently when one fails.
What do you guys think? We haven’t tested the program yet, and I’m making changes to fix 1 and 2, but 3 we’ve no clue whether it would be easy to overload the cRIO in that way.
is what’s causing the problem, and it’s lucky the safetyconfig (“drive loop running too slow”)caught it or you’d have a runaway robot.
The robot drive vi expects to get called every 100 milliseconds. If it does not, it shuts down the drive train until it gets called again. See, the problem is that calling the robot drive vi doesn’t make the robot go forward for something like half a second and then stop, and then you call it again and it goes forward another half second. No, the vi instead just sets the speed and then has the motors run until it sets another speed.
Now, if you want to have a case structure that will have the robot keep going in the direction it was until the case structure becomes true again, what you have could work. However, it’s better to use a feedback node (which keep their value from loop to loop) to just use the last value you sent the vi. So you’d have the value that’s going to the robot drive vi go into the back of the arrow and then the output goes into a case structure that either tells the robot drive vi to do what the joystick is saying or do what it was doing last.
However, what you probably want to do is stop the motors if the case structure is true. If that is what you want, put the case structure around the values going to the drive vi, but not the actual vi, just the values. Then have it so that when the structure is false, it gives a value of zero.
The “loop executing too slowly” message can be misleading. Most of the time, it really means “not calling Tank/Arcade/Mecanum Drive often enough”. If you have a case where nothing commands the drive motors for a while, the motor safety watchpup will trigger.
As mentioned, the “loop” the message is referring to is a repetitive task and not necessarily a For or While loop. If you need to investigate further, the Getting Started window for LV contains a Troubleshooting tutorial. Midway through the tutorial, it discusses the Safety VIs and how to measure more accurately how long different loops are taking. If you follow the tutorial and place the Elapsed Time VI into your teleop and perhaps into other periodic or vision loops, it will give you a better idea of how the code on the robot is actually running.
If you post the code, I’m sure you’ll get more detailed advice.
facepalms forgot to get the code last night. Well, we’re meeting Saturday as well…gonna have to remember that time. The code managed to successfully execute on the cRIO though, after the tweak so that the motors are always getting orders; bare cRIO was hooked up though with only the sidecar and nothing else (no jags, not even a breakout board).
DIO 4 is Opened twice as “A UP” and “IR3” so those aren’t likely to work.
Can’t see why or how you modified the library code in DavidsWPIRobotDriveMotors.
Having your outputs from one case statement leave through an outer case statement, then come back in before it feeds the next case statement is not good…
That can lead to a lockup condition.
Any particular reason for not keeping it within the outer Case structure?
It looks like you are misusing feed forward nodes.
Why did you put them in there at all?
It’s traditional to have inputs come from the left rather than from the right of the block diagram.
Eheh, that program’s been tweaked over and and over again, didn’t follow standard input left - output right format because I haven’t had time to really organize it the way I’d like it to.
The motor drive program was something our head programmer modified up a bit, I’ve no real clue of what modifications was made. I think it was just made so that all 4 wheels could independently be configured, or something like that. Don’t have the VI on me at the moment though facepalms again
So, with the outputs, you’re referring to having the multipliers outside of the main drive case structure…right? Wasn’t too sure whether I should’ve done that or not either, been without some supervision lately in programming and I never asked about it now that I think of it.
Eh…what’s a feed forward node …Not too familiar with LabView quite yet, I just learned simple wire connecting basics, VI locations, constant/indicator creation, and variable creation from the head, and figured out everything myself.
The way the LabVIEW data flow works is that nothing inside a programming structure (like a Case Statement or a While loop) will get executed until All the data inputs are present and accounted for.
By having outputs leave the Case statement and immediately come back in, the Case statement will wait for those inputs before starting…
Of course, the outputs won’t occur before the Case statement executes either…
So the Case statement gets locked up waiting for itself to complete before it starts…
It’s that thingy with the big arrow.
Normally, it is used to remember what a value was the last time it was executed. That way you can compare the last value with the current value.
To check how long this takes to execute, you can use the Elapsed Times.vi located under Support Code in the Project Explorer window.
Just drag and drop a copy anywhere in your Teleop, double-click to open its’ front panel, then use Run in Robot Main.vi to try it out on the cRIO. Watch the Elapsed Times front panel to see how long Teleop is taking. You don’t want it to be longer than 100ms, in fact less than 20ms is best.
You might have an issue with your checks for x+y /= 0
Joysticks at rest don’t always equal 0. There can be a trace non-zero value, way too small to move the motors, but the cases depending on exactly zero might never be active for that reason.
Depends on the game controller though, so it might not be an issue.
Did you consider making a single button on each joystick a toggle?
Last joystick to push the button gets all control.
Stick with what makes the most sense to you though.
P.S.
I’m pretty sure that you’ll find that your Teleop is too slow.
You can isolate and identify the slowest parts by using the Diagram Disable Structure to gradually comment out groups of statements to see what causes the slow down.
Ran too slow on site, and had no time to test and remake code. Eventually I just dictated that the odds of a joystick failing are so slim that the redundancies were pointless, and I stuck in the backup non-redundancy program that i made the night before. Works the way we want it to now, I thought redundancies weren’t too worth it in the beginning anyways. Ty for the support nevertheless though, certainly another pebble in the pile of programming knowledge that I’ve been building up!
We had similar problems to team 2893. After Autonomous mode finished, Teleop mode would work only half the time. I don’t know if these are related or separate problems, but we were getting error messages about Robot drive being too slow, when Teleop did work it was sometimes sluggish, and data rate on the field was taking twice as long as the other teams. There seemed to be a pattern where we would deploy the code, it would work in Auto and Teleop. Then the next round, Teleop wouldn’t work. When the code was redeployed, the same thing happened. This was repeated ~6 times during the tournament. We raised the radio up higher for the last two rounds, but had similar issues. We never experienced this when tethered to the cRIO.
We don’t have a spare cRIO or I would try running the software using the Elapsed Times.vi to see if Teleop is running too slowly and try to isolate the problem. I’m posting the code if anyone is willing to take a look at it or possibly run it to see if the timing is reasonable or not.
I believe that deleting the compressor code will solve the problem.
The compressor code is a bit more complex than it needs to be, and it looks to me like the GetEnabledState was intended to be placed a periodic task. The timeout of 100ms means that this is slowing down your TeleOp and causing the safety VIs to kick in.