Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix-unrealistic-CANMotorMediator #112

Merged
merged 15 commits into from
Jul 15, 2024
Merged

Conversation

brettle
Copy link
Member

@brettle brettle commented Jul 13, 2024

Currently, CAN motor messages don't seem to be sent over halsim ws.

@brettle
Copy link
Member Author

brettle commented Jul 13, 2024

@CoolSpy3, do you have any idea why SimDevice messages don't appear to be being sent over halsim ws? At the moment, this branch is setup such that:

  1. It doesn't use SimHooks.stepTiming() since that was a problem in the past.
  2. MotorControllerTest.wbt has an additional flywheel controlled by SparkMax NEO and MotorControllerRobot.java is set up to run it just like the PWMMotorController driven flywheel.
  3. The robot controller for MotorControllerTest.wbt is extern to make it easier to test.

When the MotorControllerTest systemTest is run, a breakpoint at the beginning of CANMotorSim.processMessage() never gets hit. Any idea why?

@brettle
Copy link
Member Author

brettle commented Jul 13, 2024

To be clear, the CI tests are just failing because the controller is currently external.

@CoolSpy3
Copy link
Member

Alright, after some testing, I've figured out part of it. You have to add CommandScheduler.getInstance().run(); to robotPeriodic() so that the lib199 periodic methods are run (which push the new motor speeds to halsim). This triggers the breakpoint, but for some reason, I'm still not seeing the motor moving in the sim.

@CoolSpy3
Copy link
Member

I think I found the other bug. Testing now.

@CoolSpy3
Copy link
Member

CoolSpy3 commented Jul 13, 2024

Try this. For some reason, simulating the extern controller locally is taking an unreasonably long time to process callbacks (i.e. many seconds for my breakpoints to be hit after the robot code sends a message).

Edit: It looks like events are being queued faster than the controller can process them.

@brettle
Copy link
Member Author

brettle commented Jul 13, 2024

I'm still not seeing the breakpoint get hit and the second flywheel doesn't turn. Is it turning for you? I even let the test run for 30 secs instead of just 3 secs. How long is the delay before you see it hit the breakpoint?

@brettle
Copy link
Member Author

brettle commented Jul 13, 2024

Fwiw, I started down this path because I was experiencing a similar problem when trying move the time sync from NT back to hal sim to fix #101. What I saw was seeing was that if I created a SimDevice with a SimDouble property and then I called set() on that SimDouble, SimDeviceSim.processMessage() was not getting called. Since I was calling set() directly, the call to CommandScheduler.getInstance().run() should not have been needed for that to work.

@CoolSpy3
Copy link
Member

CoolSpy3 commented Jul 13, 2024

I'm still not seeing the breakpoint get hit and the second flywheel doesn't turn. Is it turning for you? I even let the test run for 30 secs instead of just 3 secs. How long is the delay before you see it hit the breakpoint?

It appears to be related to my testing methodology :/ In order to not have to run the full suite, I've been testing by running ./gradlew :tests:simulateJava with Main.java set to MotorControllerRobot, and just manually enabling. (I had to add ws_server.defaultEnabled = true to build.gradle).

With this, the breakpoint in CANMotorSim.processMessage is hit continuously from the time that the controller connects to WPILib. The breakpoint I was seeing a delay on was one I placed in the speed callback of PWMMotorMediator, which was hit ~17-18 seconds after the start of the test.

If I just run the suite, CANMotorSim.processMessage is not called. (Also for some reason, I can't get the DBSExampleTest (tests) to work. The robot moves a bit, and then the simulation just freezes. (I suspect it's probably a timing bug.) (I thought it worked earlier today though.)

@CoolSpy3
Copy link
Member

What I'm Seeing: When running the test, robotPeriodic() and Lib199Subsystem.simulationPeriodic() are both run periodically, however, CANMotor devices (and any other SimDevice variants present in this version of the code [ex. CANEncoder]) have no data transmitted. This includes the initial statuses which are sent upon device creation and not in the periodic loop. (For reference, even before my changes, these were getting transmitted when MotorControllerRobot was run manually.)

@brettle
Copy link
Member Author

brettle commented Jul 13, 2024

Thanks! Although I haven't yet had a chance to try running the robot code outside the tests (my machine is underground an os upgrade at the moment), the behavior you are seeing when running the tests is consistent with what I was seeing. At least I know I'm not crazy! 😄

@CoolSpy3
Copy link
Member

It appears to be caused by WebotsSimulator:743 (commenting that line out solves the problem). I'm not sure how though. The callbacks aren't initialized until later, and that method appears to be synchronous.

@CoolSpy3
Copy link
Member

CoolSpy3 commented Jul 14, 2024

I think I figured it out. When a ws connection is created, WSProvider_SimDevice registers a device created callback so that it can write changes to the network. This is deleted by SimDeviceSim.resetData(). Thus, even if the devices are created after the resetDeviceData() call, the provider instance is never notified, so no network data is sent. Therefore, if SimDeviceSim.resetData() is called after a ws connection is established, sim devices cannot be created on that connection.

I have to work on some other stuff now, but I can verify and open a WPILib issue later.

@brettle
Copy link
Member Author

brettle commented Jul 14, 2024

Nice work! Thanks!

- Use the WPIWebSockets associated with DeepBlueRobotics/WPIWebSockets#52.
- Only call Simulation.runPeriodicMethods() once per simulation step.
- Make CANMotorMediator.java physically realistic.
- Remove calls to SimDeviceSim.resetData() because doing so prevents HALSimWS from working with any future SimDevices.
- Make MotorController.wbt use the the DeepBlueSim controller again instead of an extern controller, since we don't need to run in the debugger right now.
- Return to using SimHooks.stepTiming() for speed.
@brettle brettle marked this pull request as ready for review July 14, 2024 06:14
@brettle brettle requested a review from a team as a code owner July 14, 2024 06:14
@brettle brettle enabled auto-merge July 14, 2024 16:35
Copy link
Member

@CoolSpy3 CoolSpy3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple minor suggestions/cleanup.

brettle and others added 5 commits July 14, 2024 18:08
…im/mediators/CANMotorMediator.java

Co-authored-by: CoolSpy3 <55305038+CoolSpy3@users.noreply.github.com>
…im/mediators/CANMotorMediator.java

Co-authored-by: CoolSpy3 <55305038+CoolSpy3@users.noreply.github.com>
… that point SimDevices are no longer needed.
@brettle
Copy link
Member Author

brettle commented Jul 15, 2024

I think I've addressed everything.

@brettle brettle mentioned this pull request Jul 15, 2024
Copy link
Member

@CoolSpy3 CoolSpy3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@brettle brettle merged commit cc0ca3f into master Jul 15, 2024
4 checks passed
@brettle brettle deleted the fix-unrealistic-CANMotorMediator branch July 15, 2024 13:28
@brettle brettle mentioned this pull request Jul 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants