MuJoCo Pro socket connection

Discussion in 'Simulation' started by Anton Sobinov, Jun 2, 2017.

  1. Hi,

    I am trying to connect Matlab to a MuJoCo Pro simulation running in the background on a Windows machine, kind of what you did for MuJoCo HAPTIX. I created a Winsock server that accepts tcp/ip package with a data package, runs mj_inverse and responds with qfrc_applied. I am trying to use if for a real time experiment, but I am experiencing some delays:
    First, time from accepting the data package to sending it out (basically, spent within the mj_inverse) is either 0, 0.5 or 1 ms. I was wondering if mj_inverse also runs on the clock (as mj_step), and whether that could be bypassed or sped up.
    Second, on Matlab side I am currently using standard tcp/ip interface, which is relatively slow (write+read to a socket takes around 4-5 ms). I know you implemented some cpp-compiled solutions for fast access of MuJoCo HAPTIX, and I was wondering if you could share some of them, or the concept behind them.

    Side-note: I tried to use the asynchronous access to the socket on Matlab side, but it did not improve the time much - it still spends a lot of time in fwrite and fread (tcp/ip library in Matlab profiler).

    PS: I am using std::chrono::high_resolution_clock for counting time, if that might influence anything.

    Thank you!

    Best wishes,
    Anton
     
  2. Emo Todorov

    Emo Todorov Administrator Staff Member

    The sockets available in MATLAB are slow indeed, and have stability issues.

    It would make sense to open-source my socket code properly, but it will take some work to disentangle it from the rest of the HAPTIX project and clean it up, and I don't know when I will get around to it. In the meantime, attached is a ZIP with the relevant files -- if you can figure out how to use them, great. socket.cpp is a cross-platform socket library that I wrote. It is used by mjhx.cpp and haptix.cpp (on the MATLAB and C++ side respectively) to open a connection and send data back and forth.

    As for mj_inverse, I am not sure what you mean by "run on the clock". It is just a C function that you call. There is no internal synchronization. It is usually very fast: around 30 microseconds on the orange humanoid with 10 contacts.
     

    Attached Files:

  3. Thank you! I will try to implement it and maybe separate into a library. If I do, I will post a result here.

    On mj_inverse, I try this:
    Code:
     
            std::chrono::duration<double, std::micro> diff;
            < in 'for' loop >
            start = std::chrono::high_resolution_clock::now();
            mj_inverse(m, d);
            diff = std::chrono::high_resolution_clock::now() - start;
    
    When I look on the vector of diffs, I get 95% approximately 0 microsec, 2% around 500 microsec and 3% around 1000 microsec.
    They are distributed around these points, +- 30 microsec. I am using 18-DOF hand model. I was wondering if this grouping is a result of some clock on the background.
     
  4. Emo Todorov

    Emo Todorov Administrator Staff Member

    This looks like your clock has limited resolution for some reason. The behavior of std:chrono is compiler-dependent in my experience. Maybe try the high-resolution timer in the code I posted? Or, you can try the function I use with std::chrono:

    #include <chrono>
    double get_time(void)
    {
    static std::chrono::system_clock::time_point _start = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed = std::chrono::system_clock::now() - _start;
    return elapsed.count();
    }
     
  5. I tried the get_time function, got the same result as before, I will try the code in the mj_socket and maybe on another machine, or compiled with Visual Studio. Although strange, precision of the clock should be
    Code:
    std::cout<<(double) std::chrono::high_resolution_clock::period::num / std::chrono::high_resolution_clock::period::den << std::endl;
    
    Which returns 1e-9 when compiled with gcc.
     
  6. I recompiled MuJoCo Pro part of the socket with Microsoft Visual Studio v14, now I the execution of mj_inverse is 47 microsec +- 9 microsec, which is more reasonable. The problem was probably with time library for gcc.
     
  7. Could you by any chance also share a Makefile for compiling the libraries for cpp-access and function for Matlab mex-compilation?

    UPD: I've figured those out, but if you could share them, I would still be grateful.
     
    Last edited: Jun 9, 2017