Replies: 4 comments 5 replies
-
A couple of notes:
Separate source sets for sim code could work for Java, but we'd need to figure out how to properly load them at runtime. This is much more difficult for C++. We would also need vendors to be similarly careful in structuring their artifacts. I'm also not sure how you would structure e.g. a command based program with simulation with separate source sets. The most natural way to structure the code would be to have sim code side-by-side with the real code in each subsystem. Separate source sets would add significantly to the complexity of structuring code in this way. Fundamentally, we want to have a low barrier to entry for simulation, and I see separate source sets, while perhaps the "right" answer from a purity perspective, as adding complexity and thus raising barriers that make it harder for teams to use simulation. |
Beta Was this translation helpful? Give feedback.
-
In RobotPy, users are directed to put all simulation related code in "physics.py", which is only loaded by the simulation software. I also don't like the simulationPeriodic mechanism and agree that mixing the sim code and non-sim code is a dangerous idea, which is why RobotPy hides simulationPeriodic from its users and still uses the physics.py mechanism instead. Your example for |
Beta Was this translation helpful? Give feedback.
-
If simulation is moved to a different source set, there's some use cases based on the existing sim/non-sim interaction that would need to be addressed. The following are from code my FRC team wrote last year. The first use case is simulation update code that needs to run at a very specific point in the normal code's execution. 3512's autonomous modes were modeled after suspendable/resumable functions (aka coroutines), and they needed to update the number and location of balls in the intake/conveyor. The intake simulation was used to simulate the flywheel slowing down when a ball went through it as well as the delay from intake to actually shooting the ball. The second use case is subsystems with controllers running more often than TimedRobot and SimulationPeriodic() that need to update the sim physics at the same time. 3512 runs TimedRobot at 20ms and subsystem controllers at 5ms, and updating the physics at a lower rate than the controller can cause oscillation for quickly accelerating systems like a flywheel (Unfortunately, I'd have to drag out a lot of control theory to prove why it oscillates†). The easiest way to update the sim physics at the same time as the controller update is to put it at the bottom of the controller callback itself. As an aside, we have an adoption issue with sim, despite how useful it would be for the target demographic: weaker programming teams that don't get working hardware until the day before competition. We should think about ways to make simulation more approachable. † Basically, when the sample frequency is below the system bandwidth, the frequency response aliases and the continuous-to-discrete pole mapping puts the discrete poles in the left half-plane, which oscillates (think xₖ₊₁ = axₖ where -1 < a < 0). |
Beta Was this translation helpful? Give feedback.
-
Necromancing time. Poking here due to this CD thread - https://www.chiefdelphi.com/t/2020-2022-wpilib-feedback/409300/93?u=gerthworm The core thesis as to why I'm here - I dislike the current wpilib architecture that shares references to code objects from the robot code into the simulation code. I also don't think it's the worst thing ever, and isn't near my top priority.... but I do think, as teams scale up their sim infrastructure, mingling the content will produce more problems than it will solve.
To clarify, I actually wouldn't go this far. The "very least" we executed this year was to keep the sim-specific code in their own classes, in a separate folder hierarchy, with a very well-defined and controlled interface between them. The only things allowed were:
In the case of 3, the focus was on communicating physical values (volts, rad/sec, meters, etc.) through the interface to the plant model. Separate build artifacts is, IMO, another level on top of this that I actually am not sure I see as necessary. Unless the sim portion needs to be swapped out quickly and frequently, or is large enough to need to be built independently, I'd prefer to keep the build as monolithic as possible. That's nothing to do with sim, just to encourage simplicity of artifact management.
Would having the ability to adjust the
At the end of the day, I agree, this is really the driving priority. And any solution that gets closer to this is good in my book. The biggest gap I think is gonna need solved in the long term is the ability to visualize and debug what the sim is describing. As a quick example.... motor inversion. There's a lot of possible places, both in robot code and in the plant model, where a missing negative sign causes a motor to run backward. The corollary is that when a sw dev sees the net system misbehave, there's a lot of possible places they could inject a -1 to make the net system behavior look better. But not all injection points are equally correct. This tends to burn folks as they scale up the system, or try to move from a sim robot to a real one. Core methods to mitigate this -
|
Beta Was this translation helpful? Give feedback.
-
Recently I started looking into using the simulation component of wpilib. However, looking at examples and the API for simulation parts, I noticed something that could cause unexpected problems to teams using it.
Let's take a look at the elevator simulation example for example.
In the
Robot
class we create a couple of simulation components, such asEncoderSim
orElevatorSim
to simulate the robot. However those objects will be created when the code runs on a real robot as well.Although it might seem harmless, this could be potentially problematic, as it could cause unexpected side-effects. We should also consider any internal wpilib simulation code which might be executed without direct user invocation.
Basically, any mixing of simulation in real robot code could have any number of unexpected consequences that could arise from bugs (i.e. simulation code bugs affecting real code), resource usage and management, and more; some of which are entirely depended on the JVM (for java) and OS.
I am aware that users may wrap parts of the code with a check for
isSimulation
which at least protects against problems caused by user usage. That still leaves internal wpilib code, and honestly is not the easiest to do. Mostly causes clattering in the code, and might not be possible in some parts of the code (no example in mind though).Suggestion
I don't have a specific design in mind, but at the very least the wpilib simulation code needs to be in a separate artifact, and deployment should be done with a different source set (although that's more for the different build plugins). Kind of similar to the separation of test and main code parts.
This might require some additional abstractions to be done in wpilib, and is likely a breaking change.
This is not really the most urgent thing, just thought I'd bring it to your attention. Perhaps I'm missing a bunch of stuff as I'm not that familiar with the internals.
What are your thoughts?
Beta Was this translation helpful? Give feedback.
All reactions