Real time control via SimplemotionV2

I have a question regarding Simplemotion V2 on the Simucube w/ IoniPro HC driving a Mige 1505.

There are no examples of real time or single parameter control using the Simplemotion Library. I’ve been using the BufferedMotion API to perform torque control, but round-trip latency is too high. Just looking for some info to get started with the single parameter and real time control techniques. In particular, how do I assign addresses to the parameters I send to the drive?

If I’m using smFastUpdateCycle, how do I initialize the controller to accept torque commands and position/velocity reads?

Thanks for any input. Would also be good to get more info on reducing RT latency between my PC and the Simucube. Current latency is around 10ms and need under 5ms.

I think the new SimuCUBE firmware has already these things implemented and solved. We are currently thinking about what parts we will release as open-source and what parts are remaining as our own code.

It would of course be mutually the best solution to use the existing code base. What is the feature/reason you are implementing that is not currently on SimuCUBE beta firmware, to be released as a public beta very soon?

Needs are pretty simple: dynamic switching between torque and position control; soft real time (i.e. can’t do the long buffering latency w/ BufferedMotion API). I’m sure that can be satisfied by SimuCUBE beta firmware…which is closed source right now. Thus digging into the SimplemotionV2 library. Is there an intention to support the real time cyclic control features of the library? Or could I get access to the beta?

Thanks much!

Currently, fast update is accomplished with setting much, much higher Smbus baudrate and using the fastupdatecycle for torque command which also reads the encoder counter value.

Are you intending to use DirectInput API or something else?

I think, given a suitable need, we could implement similar fast update cycle command also for position control to Ioni firmware, and then give you some API access to give commands you would want to give there.

I think if we’re talking about bare minimum need, I’m only looking to get a zero-order-hold type torque command and read encoder counter value. Running on Linux which (I believe) is not compatible with the DirectInput API – have been going directly through the serial bus via SimpleMotionV2.

Are there any initialization steps required to use fastupdatecycle? Does it work like the smReadXParameters where you specify an address and a value? For now, non-RT (i.e. BufferedMotion) position control may be fine, pending some experimentation with the real time API. In any case, I could implement my own position controller on top of the fastupdatecycle torque API…

There are no extra steps required. Currently SimuCUBE firmware uses the following command:
u16 encoderPos;
u16 targetTorq = // something, max/min = +/- 16384
SM_STATUS stat=smFastUpdateCycle(SMBusHandle, 1, targetTorq, 0, &encoderPos, &driveStatusBits);
if(stat!=SM_OK) //command failed
// error handling here…

I’m not 100% sure, but I believe the fastupdatecycle can only be used for torque command - as you can see, the parameter address is not used in that command at all. This was added to SimpleMotionV2 specifically for SimuCUBE use.

Let me know if you have any other questions.

Ah, awesome, thank you. Do you know what the fourth argument for that is / can it be used for anything?

Its this address:
#define SMP_STATUS 553

and you can see the different bit meanings in simplemotion_defs.h.

SimuCUBE firmware uses it to check if E-stop is pressed or not.

Have a look at hidapi:

This could be used to communicate with our SimuCUBE firmware quite easily, using USB, if you are interested.

Have looked into this but it requires some kernel patching with my particular version of linux (and using the simplemotion api isn’t that hard anyway). So frankly before worrying about kernel patching and other tricks, just trying to use what’s there :slight_smile:

Thanks again, Mika.

1 Like

Can you confirm that you are using the Simplemotion via the USB port directly from PC?

You must also remember that USB serial ports have, often by default, 16ms latency, which can be set to minimum of 1. The latest version of SimplemotionV2 (develop branch) tries to set this to 1ms, but all hardware might not be compatible with that.

Yeah, set the ftdi latency timer to 1 already.

USB minimi theoretical latency is 1ms, so in good conditions you could achieve 1kHz but that is still just “soft realtime” and you might have jitter or uncertainty there.

If you run SImpleMotion lib in hard realtime system (such as microcontroller), you can typically get stable 10 to 20kHz update rate once baud rate has been turned up to 4MBit/s.

What sort of host system you will use in the end application? PC or something else? Thanks!

Any known good PCI-e RS-485 controllers (maybe even USB 3) suggested for PC based (linux) low latency control? Probably Granite Devices has tested few already, please kindly recommend.
One I have been looking at is:

Also, simple realtime control example up on SimpleMotionV2Examples (GitHub) would be a great addition. The placeholder is there for it I see :).

Thank you!

Unfortunately we don’t have much useful data about PCI-e RS-485 adapters. Also it’s pity that none of the manufacturers seem to specify the latency of their adapters.

I believe all USB devices have minimum of 1ms latency from USB protocol specs.

BTW, just a mention: one of our customers made an ethernet to RS485 bridge and it seem to work pretty fast. Haven’t got a chance to measured the latency thou.

But you’re right! There’s a placeholder for real-time control of SMV2 Examples that I’ve almost forgotten! We’ll fill the gap some day soon.


I am willing to use the smFastUpdateCycle method for several applications, but I was wondering if you’ve made changes to it internally (for the simucube fw) without updating the SMV2 lib git. How can you deal with absolute encoders with only 16 bits for the position sent back by the Ioni ? Would it possible, if not already done, to use some of the bits of driveStatusBits to extend the encoder pos to 24 bits for example ?

The encoder 16 bit value is the difference to previous read value. Current code unwraps it to 32 bits, so at a constant read rate, it is already usable.

Yes, that’s what I’m doing (unwrapping), but that doesn’t replace an absolute position provided by absolute encoders. I guess I will have to ask at the init the ioni the 32 bit value via the standards methods, and then use the fastUpdate. Never mind, I’m not playing with absolute encoders yet :slight_smile:

You guessed it right Etienne. We also first read full 32 bit value with one command and use the change of 16 bit values with to increment/decrement the initial 32 bit value. Works nicely if change of position between two updates is less than +/-15 bits total.