So, our team is trying to run a command as a background process with multithreading. How is the best way to assign certain methods to specific threads? Our robot is command-based and we are really struggling to make this work.
Call the methods from the thread you want them to run in.
A thread is declared like an object though. How do you connect that object to anything?
I don’t think you understand how to make a thread.
You have to pass a class implementing Runnable to the constructor. The run() method of that class will execute inside the Thread.
I strongly recommend not using threads if you can avoid it. It’s too easy to create resource-eating zombie threads that never die. If you do use them, ensure they are always stopped appropriately, even in the event of an error. Just because FRCUserProgram stopped does not mean your thread has. Also be aware that some WPILib objects may not be thread safe. So try not to use any WPILib objects in your thread.
Just curious: What does the command do and why do you need to run it on a different thread?
The wpilib Scheduler, the core of the Command-Based Robot implements a simple form of multitasking. The intent is for users to write Commands and to start those commands through…some means. See the docs for more details on starting commands.
Of the list of commands that are running, each one periodically gets its execute() method called. This is the lower-level action when the Schedule.getInstance.run() method is called (teleopPeriodic, etc…). If you are curious as to the implementation, the source code to Scheduler is available for viewing.*
While this is not Java Thread concurrency, it is a simple way to have several actions occur “at once”. In reality, it means every running Command has its execute() method called about once every 20 milliseconds. This approximates “continuously” enough for most tasks.
The effect is similar to building your code out of sequential blocks of conditional statements in the teleopPeriodic() method. The first block might be to manage your drivetrain for the cycle, the next for one of your end-effectors, etc… Command-based is a different way to organize this, but functions in largely the same way.
Wpilib commands are not intended to be called from different threads, as might occur in other types of programs. This would violate the model that the library developers worked within, and may cause your program to behave unpredictably.
My understanding is that the wpilib developers took this approach of creating their own scheduler and pseudo-concurrency because traditional concurrency (i.e., Thread/Runnable/ExecutorService based) is particularly complex and likely to cause large problems from small coding errors. This would make the architecture inaccessible to teams without experienced CS mentors and push students out of the process.
If you still find the need to invoke Java multithreading, I recommend checking out the Concurrency chapter in Effective Java by Joshua Bloch.
*At one point, I forked some of wpilib and, although the project didn’t pan out, I did end up refactoring Scheduler extensively to increase readability and clarify intent. The wpilib version was written before the Java Collections Framework was available on FRC 'bots, and implemented its own version of the LinkedHashSet, cluttering the Scheduler code with data structure management.