Your repository name suggests that you’re following a tutorial. Could you also provide a link to that tutorial? If you’re not following a tutorial, I don’t see any commands in your code. What are you trying to accomplish?
I’m not super familiar with C++ wpilib, but according to the WPILIbC examples (Hatchbot inlined), the button binding seems to accept a CmdPtr, rather than the Command.
Not sure if that matters or not. Just an interesting difference. I don’t quite understand why you’re instantiating a long list of commands in your toggle commands structure of Manipulator so some explanation of what you’re trying to do may help as well.
CreateClawToggleStateCommand() is wrong. You move openLeftCommand into openClaw, and then return an empty openLeftCommand CommandPtr. Thats why it doesn’t show up on the dashboard.
As for the composition error, its the same issue, but also maybe shows a bug on our end. You’re taking openLeftCommand out of CreateClawToggleStateCommand(), which has been composed into openClaw(), and binding it to a trigger.
Beta 4 has some fixes to make these bugs clearer and throw errors earlier.
Sorry about that. I was doing some debugging and just wanted to test that part. I didn’t reset it all the way. It’s back the way it should be on the repo, but I’m still getting the same behavior
I put another layer between Robot Container and the subsystems just so that Robot Container doesn’t get too messy. I call it Manipulator. The commands are there
So am I right in thinking that, unlike Java, C++ needs to have commands stored somewhere in the header file if I’m to use them the way I’m using them in this little project.
I can just make the command in a method in Java and bind it to a trigger no problem.
You do not need to store temporaries as fields. If you’ve used std::move properly (or else just composed with rvalues directly from constructors), nothing will go out of scope.
The safest thing to do is compose inline. If you find it getting verbose, add an intermediate factory.
It looks like you mostly have the idea of it; you use it whenever you are transferring ownership to the other side of the call contract. When I compose commands, the component command’s ownership should transfer to the parent command, so we have to std::move it when it is passed.
When you bind the command to a trigger, you need to give ownership to the trigger for the same reason. As your code is written, the command goes out of scope immediately after binding.
I implore you to just inline constructors/factory calls wherever feasible instead of doing all this stuff out-of-line and then using std::move. It’s something of a code smell.
You do not need to use std::move when getting a Trigger from the CommandXboxController; the returned Trigger is already owned by the controller.
You do not need to call .get on the CommandPtr instance, either; you can/should move the entire command.