![]() |
COmmand based software Interrupts
Hello again! I'm back with another (possibly) stupid question. Does anyone have any documentation on how command interrupts are handled in command based code? I'm having issues where effectively command 1 which requires subsystem A gets called initially, then before it finishes command 2 gets called which also requires subsystem A, but then they both keep getting called in parallel (I am not using command groups)? I would love to know what exactly goes on inside the code and what order functions are run in, etc., etc., for when situations like these happen.
My google-fu and delphi-fu isn't doing much |
Re: COmmand based software Interrupts
Do you have anything in the interrupted function of the first command? The command itself may be ending but whatever it's doing may continue unless you explicitly tell it to stop in the interrupted function. How do you know they both keep getting called in parallel?
Here's some general command based documentation, but it has some specific detail about interrupting and requires(): http://wpilib.screenstepslive.com/s/...uling-commands http://wpilib.screenstepslive.com/s/...ed-programming |
Re: COmmand based software Interrupts
Ok thank you so much, that was exactly what I wanted! Also, if you know, how do you make a command non-interruptible? It said that in the flow chart about halfway down the page on the second link you gave me.
|
Re: COmmand based software Interrupts
Quote:
|
Re: COmmand based software Interrupts
Ok, thank you. I tried using the cancel command in the Interrupted function, but it still did not work :/ do you know how you can force a command to stop once it is interrupted?
|
Re: COmmand based software Interrupts
Quote:
You didn't answer the question about how you know they are running in parallel. It shouldn't be possible for two commands that Require the same subsystem to run at the same time. |
Re: COmmand based software Interrupts
I'm adding some diagnostics and should be able to test it soon, but I'm assuming that's whats happening because when we call command A that goes to, say, 1000 encoder counts, and then command B (which should go to -1000) before it reaches, it will kinda stutter like it's being repeatedly told to go positive and then zero, going forwards until it hits 1000 and then run in reverse at normal speed until it hits -1000 then stop.
Btw those were arbitrary numbers |
Re: COmmand based software Interrupts
Yeah, that's exactly what happened. When we did the printf's, it showed:
CommandA execute CommandB execute CommandA execute CommandB execute CommandA execute CommandB execute CommandA execute CommandB execute CommandA execute CommandB execute CommandA execute CommandB execute |
Re: COmmand based software Interrupts
Our code is at https://github.com/Sparky384/Team384...ree/master/src if anyone wants to take a look.
|
Re: COmmand based software Interrupts
Is your repository private? Link doesn't work.
For the commands that are running "in parallel". * Do they both require the same subsystem? * What does their isFinished() code look like? * What command is set as the default command for the subsystem? * What does the code in OI look like that associates the commands with buttons (or where is new CommandXYZ() called for each command in question)? |
Re: COmmand based software Interrupts
Quote:
Quote:
Also, how are you starting the commands? It's possible they both keep trying to start, and are therefore interrupting each other repeatedly. |
Re: COmmand based software Interrupts
Oh crap, my apologies! The repository is private. My school blocks github :/ so I can't make it public until this afternoon at about 430 EST. I will as soon as I get to our shop.
Yes, they require the same subsystem. There are two checks in the is finished command, one is if they hit either the upper or lower limit, in which case return true and end the command immediately so you don't break anything, and the other is just to check if you've hit the encoder count you want, in which case return true and end the command. I would like to note that these parts of the command work exemplary and exactly as I want them, and have never given me any issues, except for this "parallel" problem. The default command is called ElevatorIdle which turns the motors off in the Initialize function, then repeatedly prints out diagnostics in the execute, doesn't have anything in the isFinished except for return false, and turns off the elevator motor in the End and IsInterrupted functions. The code in the OI is just: Code:
joy1button2->WhenPressed(new MoveElevatorCarry());In Interrupted is a printf which is only seen once when the new command is begun, and a function call to turn off the elevator motor. As I said above, I'm just calling the commands in the OI file. Is there another place where we need to write some code so it knows what to expect? I have the line: Code:
Requires(CommandBase::Elevator);P.S. also all of the above is from memory, as I said my school blocks github so I can't access the code :/ so if anything small in the syntax looks like it might be the issue, there's a high probability it's just me remembering it slightly wrong. As I said, the code works beautifully, I'm in love with commandBased as it's my first year using it, but I think I'm just missing some small nuance that has to happen with it. P.P.S. Thank you guys so much for your help!!! We're a week four, so we have just about a week until competition, so I'm getting really nervous with this. You guys are lifesavers!!!! :D |
Re: COmmand based software Interrupts
In the Elevator subsystem:
How are the upperLimit() and lowerLimit() switches wired up? If they are just limit switches that pull the channel low when the switch is closed (ground on the NC pin, signal on the C pin), then I would expect your GetLowerLimit() and GetUpperLimit() to return true when the switches are not pressed, and false when they are pressed. This is because there are pull-ups on the discrete input channels. This would cause your MoveElevatorXXX commands to immediately end. If you haven't already tested in your subsystem do what you think they should... add some print statements that call elevator.GetLowerLimit() and elevator.GetUpperLimit() from within Robot.TeleopPeriodic(). Without running any commands, press your switches and verify that the functions are retuning True/False when you think they should. If that's not the problem, can you provide a real log of the output that you're seeing in the console when you run. I suspect that what was provided earlier wasn't real output from the robot. There's a lot more print statements in your code that I would expect to see that aren't in the log you provided. Having a real copy of the log will help us see how the commands are executing and potentially help narrow down where to look. |
Re: COmmand based software Interrupts
Quote:
I'll get a proper log later, but yeah that was pretty much it :/ the only thing I changed was adding a printf to the isFinished command. When the new button was pressed it ran the: old command interrupt new command init new command execute new command isFinished old command execute old command isfinished new command execute new command isFinished old command execute old command isfinished and et cetera. |
Re: COmmand based software Interrupts
Your switches may be wired correctly... but that doesn't mean that your code is reading their states correctly. Hence my suggestion to check that it's doing what you expect. If you're confident that's not the problem, good. I can't make you check it. You're the one that's saying it's not working correctly, so It may be prudent to verify your assumptions.
Other things that could be wrong: Which commands in particular are you referring to as "new" command and "old" command? The reason I ask is in OI all the MoveElevatorXXX commands are started when you press a button. These are the command I thought you were talking about previously wrt your logs. They will only execute once unless you're repeatedly pressing the button in question. This is not consistent with the logs you've provided. On the other hand, if the one of the commands that's running happens to be the DropElevator() or LiftElevator() commands, then there's a different explanation for what may be going on. I have yet to come up with a case where WhileHeld() actually does what you want it to (if someone has a use case, please let me know). If I understand your code correctly, the way you're attempting to use this command is to have your Lift/DropElevator() commands run until you let go of the button. But what's actually going to happen is each loop iteration, you're going to start a new copy of the Lift/DropElevator() command. Since you have a call to stop the elevator as part of the command, you're going to be in this endless loop of driving the elevator, stopping it, driving it, stopping it, until you let go of the button. Here's why using the joy1button4->WhileHeld(new DropElevator()); as an example:
What you probably want to do is instead execute the command WhenPressed, then call a command that stops the elevator (ElevatorIdle) When the same button is released. Code:
joy1button3->WhileHeld(new LiftElevator()); Code:
joy1button3->WhenPressed(new LiftElevator()); |
Re: COmmand based software Interrupts
Quote:
The fact there is only one object created at Robot init (vs. one created every time the button is held) is only important if your command has member variables that might make a difference to you how many objects there are. |
| All times are GMT -5. The time now is 14:02. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi