Delete testxml code sample.
PiperOrigin-RevId: 573202693 Change-Id: Ic8d284293bd5c51693415d4186bb0b72a5416dca
This commit is contained in:
committed by
Copybara-Service
parent
d88675a034
commit
fb4cf472ed
+9
-7
@@ -139,15 +139,17 @@ General
|
||||
:ref:`mjDEPTH_ZERONEAR` and :ref:`mjDEPTH_ZEROFAR`, which can be used to set the new ``readDepthMap`` attribute in
|
||||
:ref:`mjrContext`` to control how the depth returned by :ref:`mjr_readPixels` is mapped from ``znear`` to ``zfar``.
|
||||
`Contribution <https://github.com/google-deepmind/mujoco/pull/978>`__ by `Levi Burner <https://github.com/aftersomemath>`__.
|
||||
25. Deleted the code sample ``testxml``. The functionality provided by this utility is implemented in the
|
||||
`WriteReadCompare <https://github.com/google-deepmind/mujoco/blob/main/test/xml/xml_native_writer_test.cc>__ test.
|
||||
|
||||
Python bindings
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
25. Fixed `#870 <https://github.com/google-deepmind/mujoco/issues/870>`__ where calling ``update_scene`` with an invalid
|
||||
26. Fixed `#870 <https://github.com/google-deepmind/mujoco/issues/870>`__ where calling ``update_scene`` with an invalid
|
||||
camera name used the default camera.
|
||||
26. Added ``user_scn`` to the :ref:`passive viewer<PyViewerPassive>` handle, which allows users to add custom
|
||||
27. Added ``user_scn`` to the :ref:`passive viewer<PyViewerPassive>` handle, which allows users to add custom
|
||||
visualization geoms (`#1023 <https://github.com/google-deepmind/mujoco/issues/870>`__).
|
||||
27. Added optional boolean keyword arguments ``show_left_ui`` and ``show_right_ui`` to the functions ``viewer.launch``
|
||||
28. Added optional boolean keyword arguments ``show_left_ui`` and ``show_right_ui`` to the functions ``viewer.launch``
|
||||
and ``viewer.launch_passive``, which allow users to launch a viewer with UI panels hidden.
|
||||
|
||||
Simulate
|
||||
@@ -157,21 +159,21 @@ Simulate
|
||||
:align: right
|
||||
:width: 240px
|
||||
|
||||
28. Added **state history** mechanism to :ref:`simulate<saSimulate>` and the managed
|
||||
29. Added **state history** mechanism to :ref:`simulate<saSimulate>` and the managed
|
||||
:ref:`Python viewer<PyViewerManaged>`. State history can be viewed by scrubbing the History slider and (more
|
||||
precisely) with the left and right arrow keys. See screen capture:
|
||||
|
||||
29. The ``LOADING...`` label is now shown correctly.
|
||||
30. The ``LOADING...`` label is now shown correctly.
|
||||
`Contribution <https://github.com/google-deepmind/mujoco/pull/1070>`__ by
|
||||
`Levi Burner <https://github.com/aftersomemath>`__.
|
||||
|
||||
Bug fixes
|
||||
^^^^^^^^^
|
||||
|
||||
30. Fixed a bug that was causing :ref:`geom margin<body-geom-margin>` to be ignored during the construction of
|
||||
31. Fixed a bug that was causing :ref:`geom margin<body-geom-margin>` to be ignored during the construction of
|
||||
midphase collision trees.
|
||||
|
||||
31. Fixed a bug that was generating incorrect values in ``efc_diagApprox`` for weld equality constraints.
|
||||
32. Fixed a bug that was generating incorrect values in ``efc_diagApprox`` for weld equality constraints.
|
||||
|
||||
|
||||
Version 2.3.7 (July 20, 2023)
|
||||
|
||||
@@ -165,7 +165,7 @@ links below, to make this documentation self-contained.
|
||||
`mjxmacro.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjxmacro.h>`__
|
||||
This file is optional and is not included by mujoco.h. It defines :ref:`X Macros <tyXMacro>` that can
|
||||
automate the mapping of mjModel and mjData into scripting languages, as well as other operations that require
|
||||
accessing all fields of mjModel and mjData. See code sample :ref:`testxml.cc <saTestXML>`.
|
||||
accessing all fields of mjModel and mjData.
|
||||
`mjexport.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjexport.h>`__
|
||||
Macros used for exporting public symbols from the MuJoCo library. This header should not be used directly by client
|
||||
code.
|
||||
|
||||
@@ -26,28 +26,6 @@ profiling. The results are then printed in the console. To simulate controlled d
|
||||
one can either install the control callback :ref:`mjcb_control`, or set control signals
|
||||
explicitly as explained in the :ref:`simulation loop <siSimulation>` section below.
|
||||
|
||||
.. _saTestXML:
|
||||
|
||||
`testxml <https://github.com/google-deepmind/mujoco/blob/main/sample/testxml.cc>`_
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This code sample tests the parser, compiler and XML writer. The testing code does the following:
|
||||
|
||||
- Parse and compile a specified XML model in MJCF or URDF. This yields an mjModel structure ready for simulation;
|
||||
- Save the model as a temporary MJCF file, using a "canonical" subset of MJCF where a number of conversions have
|
||||
already been performed by the compiler;
|
||||
- Parse and compile the temporary MJCF file. This yields a second mjModel structure ready for simulation;
|
||||
- Compare the two mjModel structures field by field, and print the field with the largest numerical difference. Since
|
||||
MJCF is a text format, the real-valued numbers saved in it have lower precision than the double precision used
|
||||
internally, thus we cannot expect the two models to be identical on the bit level. But we can expect the largest
|
||||
difference to be on the order of 1e-6. A substantially larger difference indicates a bug in the parser, compiler or
|
||||
XML writer - and should be reported.
|
||||
|
||||
The code uses the :ref:`X Macros <tyXMacro>` described in the Reference chapter. This is a convenient way
|
||||
to apply the same operation to all fields in mjModel, without explicitly typing their names. The code sample
|
||||
:ref:`simulate.cc <saSimulate>` also uses X Macros to implement a watch, where the user can type the name of any mjData
|
||||
field which is resolved at runtime.
|
||||
|
||||
.. _saCompile:
|
||||
|
||||
`compile <https://github.com/google-deepmind/mujoco/blob/main/sample/compile.cc>`_
|
||||
|
||||
@@ -676,10 +676,7 @@ correct way to do it is the hard way:
|
||||
mju_copy(myqposqvel, d->qpos, m->nq + m->nv);
|
||||
|
||||
The :ref:`X Macros <tyXMacro>` defined in the optional header file ``mjxmacro.h`` can be used to automate allocation of
|
||||
data structure that match mjModel and mjData, for example when writing a MuJoCo wrapper for a scripting language. In
|
||||
the code sample :ref:`testxml.cc <saTestXML>` we use these unusual macros to compare all data arrays from two instances
|
||||
of mjModel and find the one with the largest difference. Apparently X Macros were invented in the 1960's for assembly
|
||||
language, and remain a great idea.
|
||||
data structure that match mjModel and mjData, for example when writing a MuJoCo wrapper for a scripting language.
|
||||
|
||||
.. _siStack:
|
||||
|
||||
@@ -841,13 +838,6 @@ forces are disabled) the underlying physical system is energy-conserving. In tha
|
||||
the total energy indicate inaccuracies in numerical integration. For such systems the Runge-Kutta integrator has much
|
||||
better performance than the default semi-implicit Euler integrator.
|
||||
|
||||
Finally, the user can implement additional diagnostics as needed. Two examples were provided in the code samples
|
||||
``testxml.cc`` and ``derivative.cc``, where we computed model mismatches after save and load, and assessed the accuracy
|
||||
of the numerical derivatives respectively. Key to such diagnostics is to implement two different algorithms or
|
||||
simulation paths that compute the same quantity, and compare the results numerically. This type of sanity check is
|
||||
essential when dealing with complex dynamical systems where we do not really know what the numerical output should be;
|
||||
if we knew that, we would not be using a simulator in the first place.
|
||||
|
||||
.. _siJacobian:
|
||||
|
||||
Jacobians
|
||||
|
||||
@@ -86,15 +86,9 @@ target_compile_options(testspeed PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
target_link_libraries(testspeed Threads::Threads)
|
||||
target_link_options(testspeed PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
add_executable(testxml testxml.cc array_safety.h)
|
||||
target_compile_options(testxml PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
|
||||
target_link_libraries(testxml Threads::Threads)
|
||||
target_link_options(testxml PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
|
||||
|
||||
target_link_libraries(compile mujoco::mujoco)
|
||||
target_link_libraries(derivative mujoco::mujoco)
|
||||
target_link_libraries(testspeed mujoco::mujoco)
|
||||
target_link_libraries(testxml mujoco::mujoco)
|
||||
|
||||
# Build samples that require GLFW.
|
||||
|
||||
@@ -124,7 +118,6 @@ if(APPLE AND MUJOCO_BUILD_MACOS_FRAMEWORKS)
|
||||
embed_in_bundle(derivative simulate)
|
||||
embed_in_bundle(record simulate)
|
||||
embed_in_bundle(testspeed simulate)
|
||||
embed_in_bundle(testxml simulate)
|
||||
endif()
|
||||
|
||||
# Do not install if macOS Bundles are created as RPATH is managed manually there.
|
||||
@@ -144,7 +137,6 @@ if(_INSTALL_SAMPLES)
|
||||
derivative
|
||||
record
|
||||
testspeed
|
||||
testxml
|
||||
INSTALL_DIRECTORY
|
||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}"
|
||||
LIB_DIRS
|
||||
@@ -159,7 +151,6 @@ if(_INSTALL_SAMPLES)
|
||||
derivative
|
||||
record
|
||||
testspeed
|
||||
testxml
|
||||
EXPORT ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT samples
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT samples
|
||||
|
||||
@@ -6,7 +6,6 @@ COMMON=-O2 -I../include -L../lib -std=c++17 -pthread -Wl,-no-as-needed -Wl,-rpat
|
||||
|
||||
.PHONY: all
|
||||
all:
|
||||
$(CXX) $(COMMON) testxml.cc -lmujoco -o ../bin/testxml
|
||||
$(CXX) $(COMMON) testspeed.cc -lmujoco -o ../bin/testspeed
|
||||
$(CXX) $(COMMON) compile.cc -lmujoco -o ../bin/compile
|
||||
$(CXX) $(COMMON) derivative.cc -lmujoco -fopenmp -o ../bin/derivative
|
||||
|
||||
@@ -12,7 +12,6 @@ ALLFLAGS=$(CXXFLAGS) -L$(GLFWROOT)/lib -Wl,-rpath,$(MUJOCOPATH)
|
||||
|
||||
.PHONY: all
|
||||
all:
|
||||
clang++ $(ALLFLAGS) testxml.cc -framework mujoco -o testxml
|
||||
clang++ $(ALLFLAGS) testspeed.cc -framework mujoco -o testspeed
|
||||
clang++ $(ALLFLAGS) compile.cc -framework mujoco -o compile
|
||||
clang++ $(ALLFLAGS) derivative.cc -framework mujoco -o derivative
|
||||
|
||||
@@ -10,7 +10,6 @@ COMMON=/O2 /MT /EHsc /arch:AVX /I../include /Fe../bin/
|
||||
|
||||
.PHONY: all
|
||||
all:
|
||||
cl $(COMMON) testxml.cc ../lib/mujoco.lib
|
||||
cl $(COMMON) testspeed.cc ../lib/mujoco.lib
|
||||
cl $(COMMON) compile.cc ../lib/mujoco.lib
|
||||
cl $(COMMON) derivative.cc /openmp ../lib/mujoco.lib
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
// Copyright 2021 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include <mujoco/mjxmacro.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
#include "array_safety.h"
|
||||
namespace mju = ::mujoco::sample_util;
|
||||
|
||||
static constexpr int kFieldSize = 500;
|
||||
|
||||
// help
|
||||
const char helpstring[] = "\n Usage: testxml modelfile.xml\n";
|
||||
|
||||
|
||||
// deallocate and print message
|
||||
int finish(const char* msg = 0, mjModel* m = 0, mjData* d = 0) {
|
||||
// deallocated everything
|
||||
if (d) {
|
||||
mj_deleteData(d);
|
||||
}
|
||||
if (m) {
|
||||
mj_deleteModel(m);
|
||||
}
|
||||
|
||||
// print message
|
||||
if (msg) {
|
||||
std::printf("%s\n", msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// return absolute difference if it is below 1, relative difference otherwise
|
||||
static mjtNum _compare(mjtNum val1, mjtNum val2) {
|
||||
mjtNum magnitude = mju_max(mju_abs(val1), mju_abs(val2));
|
||||
|
||||
if (magnitude>1.0) {
|
||||
return mju_abs(val1-val2) / magnitude;
|
||||
} else {
|
||||
return mju_abs(val1-val2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// compare two models, return largest difference and field name
|
||||
mjtNum compareModel(const mjModel* m1, const mjModel* m2, char (&field)[kFieldSize]) {
|
||||
int r, c;
|
||||
mjtNum dif, maxdif = 0.0;
|
||||
|
||||
// define symbols corresponding to number of columns (needed in MJMODEL_POINTERS)
|
||||
MJMODEL_POINTERS_PREAMBLE(m1);
|
||||
|
||||
// compare ints
|
||||
#define X(name) if(m1->name!=m2->name) {mju::strcpy_arr(field, #name); return 1.0;}
|
||||
|
||||
MJMODEL_INTS
|
||||
#undef X
|
||||
|
||||
// compare arrays
|
||||
#define X(type, name, nr, nc) \
|
||||
for( r=0; r<m1->nr; r++ ) \
|
||||
for( c=0; c<nc; c++ ) { \
|
||||
dif = _compare(m1->name[r*nc+c], m2->name[r*nc+c]); \
|
||||
if(dif>maxdif) {maxdif=dif; mju::strcpy_arr(field, #name);} }
|
||||
|
||||
MJMODEL_POINTERS
|
||||
#undef X
|
||||
|
||||
// compare scalars in mjOption
|
||||
#define X(type, name) \
|
||||
dif = _compare(m1->opt.name, m2->opt.name); \
|
||||
if(dif>maxdif) {maxdif=dif; mju::strcpy_arr(field, #name);}
|
||||
|
||||
MJOPTION_SCALARS
|
||||
#undef X
|
||||
|
||||
// compare arrays in mjOption
|
||||
#define X(name, n) \
|
||||
for( c=0; c<n; c++ ) { \
|
||||
dif = _compare(m1->opt.name[c], m2->opt.name[c]); \
|
||||
if(dif>maxdif) {maxdif=dif; mju::strcpy_arr(field, #name);} }
|
||||
|
||||
MJOPTION_VECTORS
|
||||
#undef X
|
||||
|
||||
// mjVisual and mjStatistics ignored for now
|
||||
|
||||
return maxdif;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// main function
|
||||
int main(int argc, const char** argv) {
|
||||
// print help if arguments are missing
|
||||
if (argc<2) {
|
||||
return finish(helpstring);
|
||||
}
|
||||
|
||||
// get filename, check file type
|
||||
std::string filename(argv[1]);
|
||||
if (filename.find(".xml")==std::string::npos) {
|
||||
return finish("xml model file is required");
|
||||
}
|
||||
|
||||
// load model
|
||||
char error[1000];
|
||||
mjModel* m = mj_loadXML(argv[1], 0, error, 1000);
|
||||
if (!m) {
|
||||
return finish(error);
|
||||
}
|
||||
|
||||
// make data
|
||||
mjData* d = mj_makeData(m);
|
||||
if (!d) {
|
||||
return finish("Could not allocate mjData", m);
|
||||
}
|
||||
|
||||
// prepare temp filename in the same directory as original (for asset loading)
|
||||
std::string tempfile;
|
||||
std::size_t lastpath = filename.find_last_of("/\\");
|
||||
if (lastpath==std::string::npos) {
|
||||
tempfile = "_tempfile_.xml";
|
||||
} else {
|
||||
tempfile = filename.substr(0, lastpath+1) + "_tempfile_.xml";
|
||||
}
|
||||
|
||||
// save
|
||||
if (!mj_saveLastXML(tempfile.c_str(), m, error, 1000)) {
|
||||
return finish(error, m, d);
|
||||
}
|
||||
|
||||
// load back
|
||||
mjModel* mtemp = mj_loadXML(tempfile.c_str(), 0, error, 100);
|
||||
if (!mtemp) {
|
||||
return finish(error, m, d);
|
||||
}
|
||||
|
||||
// compare
|
||||
char field[kFieldSize] = "";
|
||||
mjtNum result = compareModel(m, mtemp, field);
|
||||
std::printf("\nComparison of original and saved model\n");
|
||||
std::printf(" Max difference : %.3g\n", result);
|
||||
std::printf(" Field name : %s\n", field);
|
||||
|
||||
// delete temp model and file
|
||||
mj_deleteModel(mtemp);
|
||||
remove(tempfile.c_str());
|
||||
|
||||
// finalize
|
||||
return finish();
|
||||
}
|
||||
Reference in New Issue
Block a user