I’m from a new team borrowing another team’s robot. I don’t have access to it right now, but I want to check before I get to school with the code and find that it doesn’t function. What I want/hope/expect this code to do is open the connection to the two drive motors (I’m guessing at their PWM channels, but that’s simple to change), incrementally speed them both up, and have the robot spin around in a circle. I’m not overly particular about what it does-- I just want to make sure that it will run and do what I want it to do without errors.
Can’t guarantee I’ve spotted everything, but here’s a couple of my thoughts:
It looks like the robot will drive straight, not in a circle, because you have the Jaguars set to the same speed. Unless, of course you have one of the Jaguars wired “backwards” *.
Also, as it stands right now, the cRIO will speed through the For loop in a very small fraction of a second, so all you will see is your robot take off at high speed. Unless of course your program resets the motors after autonomous completes, in which case it will just sit there, because the autonomous will start and stop in that small amount of time. Instead, put a call to the Watchdog Delay and Feed VI in the loop, and tell it to wait ~10 ms each loop. This will make your robot accelerate to full speed in one second. You may want to put some delay after the loop as well to just give it some time to spin.
Not necessary, but just good coding practice would be to set both Jaguars to 0 speed after the autonomous finishes to make the autonomous code more independent from the other parts of your program.
You should probably be careful about opening motors in the autonomous routine, because if you’re opening them in the teleop portion as well, you might get errors (haven’t tested this to be sure). Try opening them once at the very beginning of your program, then passing around the device reference using a global variable.
If you do, in fact, want to open the motors in your autonomous, you should close them after the autonomous finishes.
Nothing wrong with it, but just note that +1.0 is maximum forward speed, so the last 400 iterations of your For loop won’t have any visible effect.
That’s all I see at the moment. Good luck!
–Ryan
quotes because this would mean you actually have them wired the same. Since the motors are physically oriented opposite directions, you should have the motor leads connected to the Jaguar switched. Some people will argue that you can just open the Jaguars with one inverted, but I like to change it in wiring, because the Victors at least had an asymmetric deadzone. Not sure if the Jaguars continue this “feature.”
Thank you very much! You actually managed to answer some of the questiosn that I was trying to formulate.
I guess I should probably check on that early on-- I was under the impression that since the drive motors were oriented opposite each other, they would both be spinning in “Opposite” directions. But, it’s possible that they were wired backwards, I don’t know, and I’ll be able to (possibly) find out Tuesday.
Thanks for that bit of information-- I had realized that it would probably run very quickly, but didn’t know how to slow it down, but still maintain the functionality.
As for opening and closing the motors during autonomous, I’ll close them for now, and then do a bit of testing with it later on, just to find out. At the risk of coming off as a complete fool, I’ve had absolutely no luck getting information into a Global Variable. I can create them, but I’m then taken to a new Block Diagram, and aren’t quite sure what to do from there. The help function doesn’t seem to help me at all; is it something incredibly obvious that my brain just doesn’t want to comprehend?
It looks like you’re using the advanced framework. I’m assuming you’re starting from scratch rather than modifying a pre-existing program (please correct me if I’m wrong on either of these points).
By default, unless you’ve changed it, the advanced framework opens two motors on Slot 4/PWMs 1 and 2 in Begin.vi and feeds them into the RobotDriveDevRef device reference within the main RobotData cluster that shows up everywhere. (which you see coming back out on the left of your AutonomousIterative screen there). Opening two more motors in AutonomousIterative and assigning them to the same PWM locations is likely to result in problems. It’s generally a good idea to do all your motor and sensor opens in Begin.vi, and your closes in Finish.vi so that everything stays organized.
Also, Autonomous Iterative runs every tick (about 20ms if I remember right) during Autonomous mode rather than running exactly once. What you’re doing here will cause the motor to open and set its speed repeatedly, which is not going to go well. At a recent workshop here, our NI guy indicated they’d seen teams have a lot of problems if they tried to open a motor that was already open (such as cRIO locks up and requires a reboot of the whole robot to go again). For this, I’d recommend Autonomous Independent, which runs exactly once during Autonomous mode.
Two things you need to do to make this work that you may not know about are setting the Autonomous Style to Independent in Begin.vi (the enum dropdown is already there for you - just set appropriately), and setting the T/F toggle outside the case statement in Autonomous Independent to T (a F setting disables the Autonomous code in that file).
The cleanest way I found of moving device references around between sections of the advanced framework is to add the reference to the RobotData.ctl typedef and then use the bundle and unbundle by name cluster functions to get the appropriate references in and out of the RobotData Cluster. If you’re just wanting to deal with a basic two motor drive, the default code has the the reference built in, and an unbundle already sitting there for you for the two drive motors, and you’d use the appropriate RobotDrive (arcade, tank, or holonomic) VI from the WPI library functions to set your speeds.
If you’d like me to work with you a bit on this, please PM me.
Another thing that hasn’t been mentioned is that you are putting a long loop into the autonomous iterative callback. There are two supported ways of doing the autonomous – iterative and independent.
The independent is somewhat easier to use for things like this. You enter your loop and use the Delay & Feed VI to time the movements in the loop. If you open the autonomous independent, there is code very similar to this already present, but turned off with a case structure and a constant. The independent runs until the DS or FMS ends the auto and disables the robot.
The iterative is supposed to return within 20ms so that the next packet can cause your callback to be called again. Technically, you can do this with the iterative, you you’ll need to make some state data such as a global to keep track of the existing state and to trigger new state changes on some of the calls.
Saying this cause I didn’t see it said explicitly.
Because you’re opening the motors in the execute loop, you’ll get a error sooner or later saying (not very well, I might add) that the cRIO can’t open another PWM that is already open. You could close the motor as the end of the loop is done, but that’s bad practice (slow things down, and just more effort than is needed).
Any of the solutions mentioned in here will work, though I just wanted to point out something else that I saw.
Thanks, everyone! As basically the only programmer on our new little team, I’m running around in circles trying to figure things out on my own. Every little piece of information is helpful, and very much appreciated. Vhcook has graciously offered to help me in private, and together we’re moving closer to a nice, working code. It’s starting to look like my fail-code has been redesigned to be useful-code!