I am using the Command & Control framework and I am noticing that when I create new subsystems i.e. Arm, Grabber subsystem. The Arm Controller, Grabber Controller VIs are running the reserve case all the time while the Drive Controller.vi that is generated automatically when you first create a project does not run the reserve case all the time. Maybe I am missing something, but I checked and I don't see what is causing this.
I am enclosing the code. Any help will be greatly appreciated.
Solved! Go to Solution.
Is there any reason you attached a project that doesn't include the subsystems you're worried about? I see they're dependencies. But, they should really be a part of the project itself. How did you add your controllers?
Reserve is the "default" (not in the case structure, but as defined off to the left) case. In your teleop, you currently have everything related to the Arm and Grabber disabled. When nothing else is running, the case you selected off to the left runs. With nothing calling into the grabber (because it's all disabled), you'll continuously call into Reserve.
Do you see the same behavior if you right-click the edge of the Diagram Disable Structure and choose to remove it?
Thank you for the quick reply.
I think there is a bug on the Command & Control framework. When I first created the subsystems, they show up in the directory structure but after a few runs, I no longer see them in the project explorer, but they are still there in their folders. To open the Arm Controller.vi, I end up going to the Subsystem.vi or Windows Explorer. If you look in Windows Explorer the code is there for all the subsystems.
I am creating the Subsystems the proper way, just like in the tutorials. Right click on Target and select New Subsystem, give it a name, select a color and add some actions. Then add code to the Controller VI, and add the new commands from the templates. It works, I can run the new commands, but I have the reserve case running all the time.
I tried it both ways with the code in Teleop with and without the Disable diagram and I see the same behavior.
If you're following those steps, the problem is likely the project needs to be saved after they're added. Otherwise, it wouldn't be surprising to me to hear the project no longer shows the folders after closing and re-opening.
As a project just links to files, they'd still exist on disk. The magic of Command and Control here is the folders will automatically sync with what's on your drive if you maintain them in the project. That way, you can use source code control to get things back and forth.
I'd probe the wire going into one of the Arm commands in your teleop. Those booleans may, or may not, be the correct location for the buttons. Without having been there when you set these up, I'm not entirely sure how you got to those button selections. The team I mentor often makes mistakes in choosing the correct button. With a probe, we can quickly see if the True value comes across that wire when you're holding down the button you expect to work. Start with Teleop Lift Arm. That should be the button at Index 2 on your joystick. If that value is True, I'd expect you to see something other than Reserve being called. If it's not, I wouldn't be surprised to see Reserve called again.
The few practice projects I've done sometimes crash, so I am in the habit of saving frequently to avoid losing any code.
As far as the buttons, I used the Driver Station, selected the USB tab and checked each button on the joystick when I pressed on it. I can see the Arm Lift command get executed on the code and displayed on the Trace VI.
I am including a picture of the Joystick that I am using.
Thank you for taking the time to look into this.
Saving the VI and saving the Project are different saves. You'd have to select Save from the Project to get the Project, itself, to save.
Good! That's definitely the easiest way to make sure all of the buttons match with what you'd expect.
When you press it, you see the Arm Lift command get executed. Then, it goes back to a series of Reserve calls instead?
That's what I'd expect you to see because you've set Reserve as the default option in the lower left side of the Arm Controller VI. Am I misunderstanding something here?
I do both, I save the VIs and then when I close the Project, I save it. In the future, I will select Save from the Project instead of just closing it and saving.
Yes, when I press on it, the Arm Lift command gets executed and then is infinite Reserves, but I don't see the same behavior with the Drive Controller. The Drive Controller only executes the commands sent and it doesn't do the infinite Reserve commands. The code for the Drive Controller and the Arm Controller looks exactly the same except for the specific command cases. That is the strange part.
Ok. I see what you're getting at.
Let's take a look at your teleop and either controller to understand this:
And the (drive) controller:
The second image shows a step to take when creating a controller. When you don't call any other command, this will run. This is the behavior we're seeing in the Arm Controller and it makes sense. We're only calling a command when you specifically hit the button to take an action in the Arm Controller. Every other iteration needs to do something. That something is defined by the second bit of code shown.
Why don't we see this in the Drive Controller's behavior? Take a look at the teleop code. In every iteration, you're calling something. Teleop Imm calls the Immediate command. If you have a button pressed, you'll potentially call either Wait method. Any of those calls will make the Drive Controller run a case that isn't Reserve. As a result, you're seeing this command called each time instead of Reserve.
If you want to see both have similar behavior, place a case structure around the Teleop Imm call and press a button to see how it behaves then. ((I wouldn't do this for your actual robot or it won't drive unless you're both moving the joystick AND pressing the button. But, it might help you see how the controllers are behaving for troubleshooting purposes.))
I just spend some time with NI support and they saw the same behavior on their end. We found the reason for this issue with the subsystems I created and why the Driver Controller does not do it.
In the Arm Controller.vi or any Subsystem Controller you create, in the top loop, in the False case there is a Read Arm Operation.vi ("Arm" is the name of the subsystem, so for the Grabber it would be Grabber Read Operation.vi) the default case for the cluster is ....."Reserve" that is why I keep seeing so many Reserve states being executed.
For the Drive Controller, in the Drive Read Operation.vi the default case is "Read Current". We changed "Reserve" to "Read Current" in the Arm Read Operation.vi and it works, I am looking to see if this change affects anything else. NI is going to come up with a write up on this issue.
Thank you for taking the time to look into this.
Looking through that, I'd be careful about doing any of that.
What you were seeing wasn't bad. When nothing is happening, you're going to the reserve case. When something is happening, it goes to the method you call.
You're making changes that cause it to constantly read values, even in the absence of input to do so. If that's how you want things to behave, that'll make sense. If you don't want it operating until you tell it to do things, similar to how you've coded it in Teleop, you're looking to introduce bugs to your code for the sake of not seeing Reserve in the trace.
Each time that controller executes, it has to do SOMETHING. The something in this case has been the "Do nothing here" Reserve case. It meets the requirement to do something but also doesn't make the robot do anything. Did you want to see different behavior?