Go to Post Warning: this reply is just an approximation of what I meant to convey - engineers cannot possibly use just written words to express what they are thinking. Raul - Raul [more]
Home
Go Back   Chief Delphi > Technical > Programming > C/C++
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 07-03-2015, 16:20
Sparkyshires Sparkyshires is offline
Registered User
AKA: Michael Shires
FRC #0384 (Sparky)
Team Role: Programmer
 
Join Date: Jan 2012
Rookie Year: 2006
Location: Virginia
Posts: 226
Sparkyshires is an unknown quantity at this point
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
__________________
"Measure with a micrometer, mark with chalk, cut with an axe."
Reply With Quote
  #2   Spotlight this post!  
Unread 07-03-2015, 16:50
TFleig78's Avatar
TFleig78 TFleig78 is offline
Registered User
AKA: Tyler
FRC #0078 (Air Strike)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Rhode Island
Posts: 58
TFleig78 will become famous soon enoughTFleig78 will become famous soon enough
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
Reply With Quote
  #3   Spotlight this post!  
Unread 07-03-2015, 21:09
Sparkyshires Sparkyshires is offline
Registered User
AKA: Michael Shires
FRC #0384 (Sparky)
Team Role: Programmer
 
Join Date: Jan 2012
Rookie Year: 2006
Location: Virginia
Posts: 226
Sparkyshires is an unknown quantity at this point
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.
__________________
"Measure with a micrometer, mark with chalk, cut with an axe."
Reply With Quote
  #4   Spotlight this post!  
Unread 07-03-2015, 21:32
TFleig78's Avatar
TFleig78 TFleig78 is offline
Registered User
AKA: Tyler
FRC #0078 (Air Strike)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Rhode Island
Posts: 58
TFleig78 will become famous soon enoughTFleig78 will become famous soon enough
Re: COmmand based software Interrupts

Quote:
Ok thank you so much, that was exactly what I wanted! Also, if you know, how do you make a command non-interruptible?
You can use the Command::setInterruptible(bool interruptible) function.
Reply With Quote
  #5   Spotlight this post!  
Unread 09-03-2015, 18:04
Sparkyshires Sparkyshires is offline
Registered User
AKA: Michael Shires
FRC #0384 (Sparky)
Team Role: Programmer
 
Join Date: Jan 2012
Rookie Year: 2006
Location: Virginia
Posts: 226
Sparkyshires is an unknown quantity at this point
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?
__________________
"Measure with a micrometer, mark with chalk, cut with an axe."
Reply With Quote
  #6   Spotlight this post!  
Unread 09-03-2015, 18:19
RufflesRidge RufflesRidge is offline
Registered User
no team
 
Join Date: Jan 2012
Location: USA
Posts: 987
RufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant future
Re: COmmand based software Interrupts

Quote:
Originally Posted by Sparkyshires View Post
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?
If Interrupted() is being called, the command is already being canceled.

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.
Reply With Quote
  #7   Spotlight this post!  
Unread 09-03-2015, 19:13
Sparkyshires Sparkyshires is offline
Registered User
AKA: Michael Shires
FRC #0384 (Sparky)
Team Role: Programmer
 
Join Date: Jan 2012
Rookie Year: 2006
Location: Virginia
Posts: 226
Sparkyshires is an unknown quantity at this point
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
__________________
"Measure with a micrometer, mark with chalk, cut with an axe."
Reply With Quote
  #8   Spotlight this post!  
Unread 10-03-2015, 09:10
Sparkyshires Sparkyshires is offline
Registered User
AKA: Michael Shires
FRC #0384 (Sparky)
Team Role: Programmer
 
Join Date: Jan 2012
Rookie Year: 2006
Location: Virginia
Posts: 226
Sparkyshires is an unknown quantity at this point
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
__________________
"Measure with a micrometer, mark with chalk, cut with an axe."
Reply With Quote
  #9   Spotlight this post!  
Unread 10-03-2015, 17:18
Sparkyshires Sparkyshires is offline
Registered User
AKA: Michael Shires
FRC #0384 (Sparky)
Team Role: Programmer
 
Join Date: Jan 2012
Rookie Year: 2006
Location: Virginia
Posts: 226
Sparkyshires is an unknown quantity at this point
Re: COmmand based software Interrupts

Our code is at https://github.com/Sparky384/Team384...ree/master/src if anyone wants to take a look.
__________________
"Measure with a micrometer, mark with chalk, cut with an axe."
Reply With Quote
  #10   Spotlight this post!  
Unread 10-03-2015, 17:34
otherguy's Avatar
otherguy otherguy is offline
sparkE
AKA: James
FRC #2168 (The Aluminum Falcons)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: CT
Posts: 429
otherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to behold
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)?
__________________
http://team2168.org
Reply With Quote
  #11   Spotlight this post!  
Unread 10-03-2015, 23:01
TFleig78's Avatar
TFleig78 TFleig78 is offline
Registered User
AKA: Tyler
FRC #0078 (Air Strike)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Rhode Island
Posts: 58
TFleig78 will become famous soon enoughTFleig78 will become famous soon enough
Re: COmmand based software Interrupts

Quote:
Originally Posted by otherguy View Post
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)?
Also, what is in interrupted()?

Quote:
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?
You should very rarely (if ever) have to explicitly cancel a command. The command will end(the scheduler will stop it) if it is interrupted by another command using the same subsystem or if isFinished() returns true. From what's going on, it seems as though your two commands A and B don't require the same subsystem.
Also, how are you starting the commands? It's possible they both keep trying to start, and are therefore interrupting each other repeatedly.
Reply With Quote
  #12   Spotlight this post!  
Unread 11-03-2015, 10:17
Sparkyshires Sparkyshires is offline
Registered User
AKA: Michael Shires
FRC #0384 (Sparky)
Team Role: Programmer
 
Join Date: Jan 2012
Rookie Year: 2006
Location: Virginia
Posts: 226
Sparkyshires is an unknown quantity at this point
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());
joy1button3->WhenPressed(new MoveElevatorOneTote());
(Carry and OneTote are names for positions on the elevator)

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);
in both the commands, is that wrong?

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!!!!
__________________
"Measure with a micrometer, mark with chalk, cut with an axe."

Last edited by Sparkyshires : 11-03-2015 at 10:19. Reason: Added thank you
Reply With Quote
  #13   Spotlight this post!  
Unread 12-03-2015, 14:45
otherguy's Avatar
otherguy otherguy is offline
sparkE
AKA: James
FRC #2168 (The Aluminum Falcons)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: CT
Posts: 429
otherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to behold
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.
__________________
http://team2168.org

Last edited by otherguy : 12-03-2015 at 16:22. Reason: fix typo that got flagged as profanity?
Reply With Quote
  #14   Spotlight this post!  
Unread 12-03-2015, 15:16
Sparkyshires Sparkyshires is offline
Registered User
AKA: Michael Shires
FRC #0384 (Sparky)
Team Role: Programmer
 
Join Date: Jan 2012
Rookie Year: 2006
Location: Virginia
Posts: 226
Sparkyshires is an unknown quantity at this point
Re: COmmand based software Interrupts

Quote:
Originally Posted by otherguy View Post
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... $@#$@#$@# 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.
Nah, I know they're wired properly, as I said the code works amazingly well, and I've tested both emergency situation and it works exactly as expected. We specifically wired it this way so if an issue arises, such as a wire coming loose, it'll act like it's hit(?) so it will stop the elevator. At least that's what the electrical guys told me. All I know is that logic is correct for our electrical set-up. The only issue that this code is giving us is that it will run two commands concurrently.

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.
__________________
"Measure with a micrometer, mark with chalk, cut with an axe."

Last edited by Sparkyshires : 12-03-2015 at 15:24.
Reply With Quote
  #15   Spotlight this post!  
Unread 12-03-2015, 17:13
otherguy's Avatar
otherguy otherguy is offline
sparkE
AKA: James
FRC #2168 (The Aluminum Falcons)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: CT
Posts: 429
otherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to beholdotherguy is a splendid one to behold
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:
  1. Joy 1 Button 4 is pressed.
  2. A new command is created and added into the scheduler (DropElevator)
  3. The active command on the subsystem (elevator) is ElevatorIdle() and it's going to be canceled. Since a new
  4. When the scheduler come around to execute the active command, it runs the execute() function, assume that you're not at end of travel on the elevator, so you're going to run the DropElevatorArm() function, which presumably commands a motor to move the arm.
  5. assume isFinished on this command returns false.
  6. the next time around (assuming the button is still pressed) a new instance of the DropElevator() command is created. It requires the Elevator subsystem, so all active commands on that subsystem are canceled.
  7. The scheduler calls the end method on the first instance of the on the DropElevator command. This in turn calls the StopElevatorArm() function, presumably commanding the elevator motors to zero.
  8. now it's time for the new instance of the DropElevator() command to run: the scheduler runs the execute() function, assume that you're not at end of travel on the elevator, so you're going to run the DropElevatorArm() function, which presumably commands a motor to move the arm.
  9. and the cycle of starting and stopping this command repeats forever until you let go of the button.

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()); 
joy1button4->WhileHeld(new DropElevator()); 
joy2button3->WhileHeld(new LiftElevator());
becomes
Code:
joy1button3->WhenPressed(new LiftElevator()); 
joy1button3->WhenReleased(new ElevatorIdle()); 
joy1button4->WhenPressed(new DropElevator()); 
joy1button4->WhenReleased(new ElevatorIdle()); 
joy2button3->WhenPressed(new LiftElevator()); 
joy2button3->WhenReleased(new ElevatorIdle());
__________________
http://team2168.org
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 03:01.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi