I am currently working on a medical simulation scenario in Unity3D (version 2021.3.21) that incorporates haptic feedback using the Touch Haptic Device (Phantom Omni). I am utilizing the OpenHaptics plugin for Unity to achieve this functionality. Although I have successfully connected the haptic device to Unity and can manipulate it within the scene, I have encountered an issue where the feedback does not feel smooth and instead feels jerky when I apply forces to the haptic device.
Currently, the haptic device is represented as a rigid body, and forces are applied using the RigidBody.AddForce() function that runs within the FixedUpdate() method.
I am interested in exploring options to potentially run the haptic code in a separate thread to ensure that it runs at a consistent rate of 1000Hz, thereby providing real-time feedback.
I would greatly appreciate any suggestions or guidance on how to achieve this smoother haptic feedback experience.
Reading input at 1000hz won’t improve anything if physics is running at its default of 50Hz and trying to run physics at higher rates massively increases the load on your CPU.
If there’s support for reading devices off the main-thread in this “OpenHaptics” plug-in then I’d just refer you to its documentation (if any).
You should ensure this is really your issue too before you go down that rabbit hole. I would say emulate some input first and drive physics that way to verify the source of the issue.
I’ve come across recommendations in various sources stating that haptics updates should ideally occur at 1000Hz for real-time feedback, which is a much higher rate compared to the typical visual update rate of around 30Hz in Unity. However, I’m a bit unsure about how to implement this specifically within Unity. While the OpenHaptics documentation offers solutions for running haptics threads separately, these solutions are geared towards C++ implementations and don’t directly address the Unity plug-in.
My main aim is to use Unity primarily as a visual interface, with the actual force calculations happening externally to Unity’s physics engine. Given this setup, I’m wondering if there are ways to ensure that the haptic code runs at a higher frequency, like 1000Hz, to achieve smoother feedback. Any advice or pointers on how to approach this would be greatly appreciated.
Well again I’d have to point you back to their documentation/support site. If they don’t offer the ability to run input off the main thread in C# in the plug-in then no advice in the world will help you. Do they allow this?
Unity offers you the C# job-system but you can also use System.Threading and do all the synchronisation yourself.
There’s a forum dedicated to the job system too if you need to ask specific things about it here: Unity Engine - Unity Discussions
I’ll give the Threading functionality a try as you suggested. Meanwhile, I’ll explore further to see if the OpenHaptics plug-in has any suitable workarounds! Thanks for pointing out the dedicated forum!!
I seriously doubt that 1000 Hz has any meaningful application for human interfaces. Hardcore gamers are at the forefront of input processing so to speak, and they top off at 250 Hz with most users not even being able to notice any difference beyond 120 Hz.
The world’s fastest monitor updates at 500 Hz and when I read that, I jump to conclusions and call this marketing bollocks. Even if its true 500 Hz it will not matter to a human being’s perception. The difference between 250 and 500 Hz is simply not perceivable.
If you want to have realtime feedback visualized on a screen, then it would have to be the world’s fastest monitor and “only” 500Hz. But realistically, 250 Hz is far more than enough if the end result is to be displayed on a monitor. And then you’ll likely want to use ECS with the DOTS physics system to be able to multithread that.
About the only thing I can think of is using it to create a certain feel to the vibrations. I can’t find any actual info on the device to suggest it’s even capable of properly handling that 1kHz though. It’s likely the extreme upper limit as opposed to the recommended usage.
Are you saying that input must result in updated output in 1ms or less? Or are you saying that output must support a frequency of at least 1000Hz? These are subtly but fundamentally different requirements.
For example, for video game input to feel responsive it needs to run the full update loop (get input, create a new image based on that input, send the image to the screen) consistently in ~30ms or less. If the loop gets slower than that, input feels sluggish or sloppy.
As another example, audio needs to support a frequency of at least 44,100hz to make all of the sounds a human can hear. However, the loop does not need to run at 44,100hz. Instead, the loop runs at a lower rate (typically around 30hz just because it’s convenient) to batch process the output, which it puts in a buffer. That buffer is then converted in real time by separate, dedicated hardware, as it’s sent to your speakers. Of course, just like with rendering, if the loop which prepares the batches is too slow the users will notice a latency between doing a thing, and the associated sound making it to the speakers.
The key point there is that a 1000hz output frequency can be achieved with a much lower frequency update loop. The frequency of your update loop depends not on the output signal frequency, but on how much latency is acceptable between input and output.
So, do you need output in a millisecond, or do you need to support a 1000hz signal?
Hi,
I am a bit confused after reading your post. I am relatively new to unity programming and haptics. I have been reading literature to understand how haptic feedback could be implemented using the unity platform incorporating the Phantom Device. The research articles often quote that for real-time visual feedback, the update rate requirement is 30Hz, while for haptic interface, it needs to be higher at 1000Hz. Based on my understanding, I believe the update loop for the haptic part will need to run at a higher frequency rate, which includes accepting the input, computing the new forces, and sending those to the device. If anyone has got a better understanding, please correct me if that’s not the case. Looking forward to any suggestions that might help.