Jump to content

Programs that use the OpenVR SDK to display some image on the VIVE Pro may terminated abnormally


Recommended Posts

Hello,

We are using the OpenVR SDK to develop a program that displays video on the VIVE Pro.
If we run our program immediately after launching SteamVR, it can be displayed without any problem.
However, when ROOM SETUP is performed after starting SteamVR and then our program is executed, the following error occurs and the app terminated abnormally.
Does anyone know the cause of this error and the countermeasures?

[Error message]
Thread 9 "sample_openvr" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffbc4a8700 (LWP 6169)]
0x00007ffff42c1ad8 in LfMutexUnlockRobust(LfMutex*) ()
    from /home/XXX/.steam/steam/steamapps/common/SteamVR/bin/linux64/vrclient.so

[Supplementary information]
・If we comment out "vr::VRCompositor()->Submit()", the app will not terminated abnormally.
・It seems that the app terminated abnormally when the waitGetPoses of OpenVR is called twice or three times.

The minimum sample code to cause a similar error is listed at the end.
・Below is a snapshot of the backtrace when running the sample code. There is a Mute error from vrclient.so.

[BackTrace snapshot]
sample_opencv_backtrace.png.d968239a0dcb88898f51f394e61167df.png

 

[Reproduction environment]
OS: Ubuntu 18.04.2 LTS
GPU: NVIDIA GeForce GTX 1070 Ti
SteamVR: 1.16.10 (currently latest)
OpenVR: 1.14.15

[Reproducibility procedure]
1. Launch Steam from the console.
2. Launch SteamVR from Steam.
3. Run ROOM SETUP. (run "Set up for Standing Only")
4. Run sample code.

[Sample code]
 

#include <openvr.h>

#include <iostream>
#include <unistd.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <GL/glew.h>

//! Texture of left eye
GLuint left_id;

//! Texture of right eye
GLuint right_id;

void TerminateVIVEStereoCameraPanel()
{
  std::cerr << "[ERROR] terminate error" << std::endl;
  exit(-1);
}

int generateTextureFromImage(const cv::Mat& image, GLuint& id)
{
  // Send an exception if the image is empty
  if (image.empty())
  {
    std::cerr << "[ERROR]image empty" << std::endl;
    return -1;
  }

  // Generate textures
  glGenTextures(1, &id);
  glBindTexture(GL_TEXTURE_2D, id);

  // Processing when displaying textures scaled up or down
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  // Processing when drawing an area that extends beyond the original texture image
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

  // Assign a 2D image to a texture
  cv::Mat image_bgr;
  cv::cvtColor(image, image_bgr, cv::COLOR_RGB2BGR);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image_bgr.cols, image_bgr.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, image_bgr.ptr());

  return 0;
}

int main()
{
  std::set_terminate(TerminateVIVEStereoCameraPanel);

  // vr initialization
  vr::EVRInitError vr_error = vr::VRInitError_None;
  vr::IVRSystem* vr_system_ = vr::VR_Init(&vr_error, vr::VRApplication_Scene);
  if (vr_error != vr::VRInitError_None)
  {
    std::cerr << "[ERROR] vr init" << std::endl;
    return -1;
  }

  // create green image
  cv::Mat green_img(cv::Size(1440, 1600), CV_8UC3, cv::Scalar(0, 255, 0));

  // generate texture from image
  std::cout << "generate textrue from image" << std::endl;
  if (generateTextureFromImage(green_img, left_id) == -1)
  {
    return -1;
  }
  if (generateTextureFromImage(green_img, right_id) == -1)
  {
    return -1;
  }

  std::cout << "while start" << std::endl;
  int no = 0;
  while(true)
  {
    std::cout << "no : " << no << std::endl;

    // The application as the focus of the Compositor
    vr::EVRCompositorError evr_compositor_error;
    vr::TrackedDevicePose_t all_poses_wait[vr::k_unMaxTrackedDeviceCount];
    std::cout << "call WaitGetPoses" << std::endl;
    evr_compositor_error = vr::VRCompositor()->WaitGetPoses(all_poses_wait, vr::k_unMaxTrackedDeviceCount, NULL, 0);
    std::cout << "called WaitGetPoses" << std::endl;
    if (evr_compositor_error != vr::EVRCompositorError::VRCompositorError_None)
    {
      std::cout << "[ERROR] WaitGetPoses EVRCompositorError message: " << static_cast<int>(evr_compositor_error) << std::endl;
    }

    // Submit to the left eye
    vr::Texture_t leftEyeTexture = { (void*)(&left_id), vr::TextureType_OpenGL,
                                    vr::ColorSpace_Gamma };
    std::cout << "call left Submit" << std::endl;
    evr_compositor_error = vr::VRCompositor()->Submit(vr::Eye_Left, &leftEyeTexture);
    std::cout << "called left Submit" << std::endl;
    if (evr_compositor_error != vr::EVRCompositorError::VRCompositorError_None)
    {
      std::cout << "[ERROR] left Submit EVRCompositorError : " << static_cast<int>(evr_compositor_error) << std::endl;
    }

    // Submit to the right eye
    vr::Texture_t rightEyeTexture = { (void*)(&right_id), vr::TextureType_OpenGL,
                                      vr::ColorSpace_Gamma };
    std::cout << "call right Submit" << std::endl;
    evr_compositor_error = vr::VRCompositor()->Submit(vr::Eye_Right, &rightEyeTexture);
    std::cout << "called right Submit" << std::endl;
    if (evr_compositor_error != vr::EVRCompositorError::VRCompositorError_None)
    {
      std::cout << "[ERROR] right Submit EVRCompositorError : " << static_cast<int>(evr_compositor_error) << std::endl;
    }

    no++;

    // 30FPS
    usleep(33333);
  }

  return 0;
}

 

Link to post
Share on other sites

Is this happeneing on other headsets other than Vive Pro? Have you checked the SteamVR OpenXR forums? The Vive Pro would use SteamVR's OpenXR runtime, on this site, the OpenXR forum focuses on the Vive OpenXR runtime (for Cosmos).

Link to post
Share on other sites

Please sign in to comment

You need to be a member in order to leave a comment

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...