Merge pull request #1479 from jmargeta:fix-record-command-docs
PiperOrigin-RevId: 613927858 Change-Id: I8fe30db8677811c98ed4f881b51a0f430d93dd3b
This commit is contained in:
@@ -150,21 +150,60 @@ This code sample simulates the passive dynamics of a given model, renders it off
|
|||||||
values, and saves them into a raw data file that can then be converted into a movie file with tools such as ffmpeg. The
|
values, and saves them into a raw data file that can then be converted into a movie file with tools such as ffmpeg. The
|
||||||
rendering is simplified compared to :ref:`simulate.cc <saSimulate>` because there is no user interaction, visualization
|
rendering is simplified compared to :ref:`simulate.cc <saSimulate>` because there is no user interaction, visualization
|
||||||
options or timing; instead we simply render with the default settings as fast as possible. The dimensions and number of
|
options or timing; instead we simply render with the default settings as fast as possible. The dimensions and number of
|
||||||
multi-samples for the offscreen buffer are specified in the MuJoCo model, while the simulation duration, frames-per-
|
multi-samples for the offscreen buffer are specified in the MuJoCo model with the visual/global/{`offwidth
|
||||||
second to be rendered (usually much less than the physics simulation rate), and output file name are specified as
|
<https://mujoco.readthedocs.io/en/stable/XMLreference.html#visual-global-offwidth>`__, `offheight
|
||||||
command-line arguments. For example, a 5 second animation at 60 frames per second is created with:
|
<https://mujoco.readthedocs.io/en/stable/XMLreference.html#visual-global-offheight>`__} and visual/quality/`offsamples
|
||||||
|
<https://mujoco.readthedocs.io/en/stable/XMLreference.html#visual-quality-offsamples>`_ attributes, while the simulation
|
||||||
|
duration, frames-per-second to be rendered (usually much less than the physics simulation rate), and output file name
|
||||||
|
are specified as command-line arguments.
|
||||||
|
|
||||||
.. code-block:: Shell
|
.. code-block:: Shell
|
||||||
|
|
||||||
render humanoid.xml 5 60 rgb.out
|
record modelfile duration fps rgbfile [adddepth]
|
||||||
|
|
||||||
The default humanoid.xml model specifies offscreen rendering with 800x800 resolution. With this information in hand, we
|
Where the command line arguments are
|
||||||
can compress the (large) raw date file into a playable movie file:
|
|
||||||
|
.. list-table::
|
||||||
|
:width: 95%
|
||||||
|
:align: left
|
||||||
|
:widths: 1 1 5
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Argument
|
||||||
|
- Default
|
||||||
|
- Meaning
|
||||||
|
* - ``modelfile``
|
||||||
|
- (required)
|
||||||
|
- path to model
|
||||||
|
* - ``duration``
|
||||||
|
- (required)
|
||||||
|
- duration of the recording in seconds
|
||||||
|
* - ``fps``
|
||||||
|
- (required)
|
||||||
|
- number of frames per second
|
||||||
|
* - ``rgbfile``
|
||||||
|
- (required)
|
||||||
|
- path to raw recording file
|
||||||
|
* - ``adddepth``
|
||||||
|
- 1
|
||||||
|
- overlay depth image in the lower left corner (0: none)
|
||||||
|
|
||||||
|
For example, a 5 second animation at 60 frames per second is created with:
|
||||||
|
|
||||||
.. code-block:: Shell
|
.. code-block:: Shell
|
||||||
|
|
||||||
ffmpeg -f rawvideo -pixel_format rgb24 -video_size 800x800
|
record humanoid.xml 5 60 rgb.out
|
||||||
-framerate 60 -i rgb.out -vf "vflip" video.mp4
|
|
||||||
|
The default `humanoid.xml <https://github.com/google-deepmind/mujoco/blob/main/model/humanoid/humanoid.xml>`__ model
|
||||||
|
specifies offscreen rendering with 2560x1440 resolution. With this information in hand, we can compress the (large) raw
|
||||||
|
data file into a playable movie file:
|
||||||
|
|
||||||
|
.. code-block:: Shell
|
||||||
|
|
||||||
|
ffmpeg -f rawvideo -pixel_format rgb24 -video_size 2560x1440
|
||||||
|
-framerate 60 -i rgb.out -vf "vflip,format=yuv420p" video.mp4
|
||||||
|
|
||||||
|
Note that the offscreen rendering resolution of the model and ffmpeg's video_size must be the identical.
|
||||||
|
|
||||||
This sample can be compiled in three ways which differ in how the OpenGL context is created: using GLFW with an
|
This sample can be compiled in three ways which differ in how the OpenGL context is created: using GLFW with an
|
||||||
invisible window, using OSMesa, or using EGL. The latter two options are only available on Linux and are envoked by
|
invisible window, using OSMesa, or using EGL. The latter two options are only available on Linux and are envoked by
|
||||||
|
|||||||
+15
-7
@@ -217,8 +217,8 @@ void closeOpenGL(void) {
|
|||||||
|
|
||||||
int main(int argc, const char** argv) {
|
int main(int argc, const char** argv) {
|
||||||
// check command-line arguments
|
// check command-line arguments
|
||||||
if (argc!=5) {
|
if (argc < 5 || argc > 6) {
|
||||||
std::printf(" USAGE: record modelfile duration fps rgbfile\n");
|
std::printf(" USAGE: record modelfile duration fps rgbfile [adddepth]\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +255,11 @@ int main(int argc, const char** argv) {
|
|||||||
mju_error("Could not open rgbfile for writing");
|
mju_error("Could not open rgbfile for writing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int adddepth = 1;
|
||||||
|
if (argc > 5 && std::sscanf(argv[5], "%d", &adddepth) != 1) {
|
||||||
|
mju_error("Invalid adddepth argument");
|
||||||
|
}
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
double frametime = 0;
|
double frametime = 0;
|
||||||
int framecount = 0;
|
int framecount = 0;
|
||||||
@@ -276,12 +281,15 @@ int main(int argc, const char** argv) {
|
|||||||
mjr_readPixels(rgb, depth, viewport, &con);
|
mjr_readPixels(rgb, depth, viewport, &con);
|
||||||
|
|
||||||
// insert subsampled depth image in lower-left corner of rgb image
|
// insert subsampled depth image in lower-left corner of rgb image
|
||||||
const int NS = 3; // depth image sub-sampling
|
if (adddepth) {
|
||||||
for (int r=0; r<H; r+=NS)
|
const int NS = 3; // depth image sub-sampling
|
||||||
for (int c=0; c<W; c+=NS) {
|
for (int r=0; r<H; r+=NS) {
|
||||||
int adr = (r/NS)*W + c/NS;
|
for (int c=0; c<W; c+=NS) {
|
||||||
rgb[3*adr] = rgb[3*adr+1] = rgb[3*adr+2] = (unsigned char)((1.0f-depth[r*W+c])*255.0f);
|
int adr = (r/NS)*W + c/NS;
|
||||||
|
rgb[3*adr] = rgb[3*adr+1] = rgb[3*adr+2] = (unsigned char)((1.0f-depth[r*W+c])*255.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// write rgb image to file
|
// write rgb image to file
|
||||||
std::fwrite(rgb, 3, W*H, fp);
|
std::fwrite(rgb, 3, W*H, fp);
|
||||||
|
|||||||
Reference in New Issue
Block a user