allwpilib icon indicating copy to clipboard operation
allwpilib copied to clipboard

Allow sim device creation to be disabled

Open Gold856 opened this issue 1 year ago • 10 comments
trafficstars

The use case for this is to allow the use and creation of simulation extensions that interact with real hardware. When using the simulation HAL, hardware objects will use SimDevice to control various values, like motor speeds. However, some teams may want to write a simulation extension that interacts with real IO, like SPI, CAN, or I2C. Instead of having to use the callbacks for each device they want to use, and possibly reimplementing the data processing for each device (read: parsing SPI/CAN/I2C packets) they can use HAL_DisableSimDeviceCreation to allow the devices to use their non-simulation SPI/CAN/I2C code, and simply implement the IO layer.

Basically, if I want to implement a simulation extension that uses simulation callbacks and something like Linux's open to allow communication with a SPI bus, I want the devices to use their non-sim SPI code so I don't have to parse SPI packets and use individiual device callbacks.

Gold856 avatar Dec 02 '23 21:12 Gold856

Does this actually do what you think it does? I'd like to see a concrete example, I don't think the API actually works this way unless you're implementing your own custom HAL.

Specifically:

Basically, if I want to implement a simulation extension that connects to an SPI bus, I want the devices to use their non-sim SPI code so I don't have to parse SPI packets and use individiual device callbacks.

If you aren't using a custom HAL, I don't think it will actually connect to any SPI bus unless you're linked to a HAL that allows that (and the simulation HAL doesn't).

virtuald avatar Dec 02 '23 23:12 virtuald

It won't connect to a physical bus, but you can write a plugin that does so for most of the low-level bus calls, as the HALSIM layer does have mock hooks for most of them (but not all, e.g. auto-SPI is not shimmable). My worry with this though is having multiple plugins conflict (especially e.g. vendors trying to hook CAN layer calls will almost certainly step on each other). We would need to implement better bus sim hooks to really make this clean.

PeterJohnson avatar Dec 02 '23 23:12 PeterJohnson

Would vendors implement the bus sim hooks, or would we? I have a SocketCAN extension, and I was kind of thinking about PRing that here.

Gold856 avatar Dec 02 '23 23:12 Gold856

If you aren't using a custom HAL, I don't think it will actually connect to any SPI bus unless you're linked to a HAL that allows that (and the simulation HAL doesn't).

I worded that badly. When I said connect, I meant using the simulation callbacks, like calling open to access a SPI port on Linux, and adding a registering a callback for writing SPI packets that uses write to send data over SPI.

Gold856 avatar Dec 02 '23 23:12 Gold856

I worded that badly. When I said connect, I meant using the simulation callbacks, like calling open to access a SPI port on Linux, and adding a registering a callback for writing SPI packets that uses write to send data over SPI.

Edit: I now realize what you're saying. I'm not sure this is the right approach for this, though.

rzblue avatar Dec 03 '23 01:12 rzblue

Maybe not, but nearly every device, both in WPILib and in vendordeps, have a condition where if a valid sim device is created (HAL_CreateSimDevice doesn't return 0), it won't use real hardware, even if it's provided through HALSIM plugins and simulation callbacks. Doing another way would require a HUGE refactor. This is simpler and it works. I've tested this impl on a Raspberry Pi with a CAN bus and have sucessfully spun CAN motors.

Gold856 avatar Dec 03 '23 02:12 Gold856

This is implemented as a global disable. I think it would be more useful as a (set of) prefix disable(s) so it can be selectively applied to just specific devices.

PeterJohnson avatar Dec 03 '23 05:12 PeterJohnson

This is implemented as a global disable. I think it would be more useful as a (set of) prefix disable(s) so it can be selectively applied to just specific devices.

As Raymond Chen would say, don't use global state to manage a local problem

virtuald avatar Dec 03 '23 06:12 virtuald

How would vendordeps be handled? I'm using this to force REVLib to use its real code path for CANSparkMaxes. Also, what would level would the disables be on? Device-level? IO-level? IO-level (SPI, CAN, I2C) seems reasonable.

Gold856 avatar Dec 03 '23 06:12 Gold856

The only thing that makes sense is the name of the device. We don’t know what a SimDevice is mocking, only the name of it.

PeterJohnson avatar Dec 03 '23 08:12 PeterJohnson