From fb4cf472edec2e51fb6771d65f01abaa92e30904 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Fri, 13 Oct 2023 06:30:13 -0700 Subject: [PATCH] Delete `testxml` code sample. PiperOrigin-RevId: 573202693 Change-Id: Ic8d284293bd5c51693415d4186bb0b72a5416dca --- doc/changelog.rst | 16 ++-- doc/programming/index.rst | 2 +- doc/programming/samples.rst | 22 ----- doc/programming/simulation.rst | 12 +-- sample/CMakeLists.txt | 9 -- sample/Makefile | 1 - sample/Makefile.macos | 1 - sample/Makefile.windows | 1 - sample/testxml.cc | 170 --------------------------------- 9 files changed, 11 insertions(+), 223 deletions(-) delete mode 100644 sample/testxml.cc diff --git a/doc/changelog.rst b/doc/changelog.rst index cc9d11ae..f9ebdcfa 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -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 `__ by `Levi Burner `__. +25. Deleted the code sample ``testxml``. The functionality provided by this utility is implemented in the + `WriteReadCompare __ test. Python bindings ^^^^^^^^^^^^^^^ -25. Fixed `#870 `__ where calling ``update_scene`` with an invalid +26. Fixed `#870 `__ where calling ``update_scene`` with an invalid camera name used the default camera. -26. Added ``user_scn`` to the :ref:`passive viewer` handle, which allows users to add custom +27. Added ``user_scn`` to the :ref:`passive viewer` handle, which allows users to add custom visualization geoms (`#1023 `__). -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` and the managed +29. Added **state history** mechanism to :ref:`simulate` and the managed :ref:`Python viewer`. 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 `__ by `Levi Burner `__. Bug fixes ^^^^^^^^^ -30. Fixed a bug that was causing :ref:`geom margin` to be ignored during the construction of +31. Fixed a bug that was causing :ref:`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) diff --git a/doc/programming/index.rst b/doc/programming/index.rst index 72af55ea..b397b80c 100644 --- a/doc/programming/index.rst +++ b/doc/programming/index.rst @@ -165,7 +165,7 @@ links below, to make this documentation self-contained. `mjxmacro.h `__ This file is optional and is not included by mujoco.h. It defines :ref:`X Macros ` 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 `. + accessing all fields of mjModel and mjData. `mjexport.h `__ Macros used for exporting public symbols from the MuJoCo library. This header should not be used directly by client code. diff --git a/doc/programming/samples.rst b/doc/programming/samples.rst index f9c3e247..fdf3ac99 100644 --- a/doc/programming/samples.rst +++ b/doc/programming/samples.rst @@ -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 ` section below. -.. _saTestXML: - -`testxml `_ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -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 ` 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 ` 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 `_ diff --git a/doc/programming/simulation.rst b/doc/programming/simulation.rst index 2782923d..82743536 100644 --- a/doc/programming/simulation.rst +++ b/doc/programming/simulation.rst @@ -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 ` 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 ` 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 diff --git a/sample/CMakeLists.txt b/sample/CMakeLists.txt index 4a44908c..8015ed81 100644 --- a/sample/CMakeLists.txt +++ b/sample/CMakeLists.txt @@ -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 diff --git a/sample/Makefile b/sample/Makefile index d51b1545..33aab005 100644 --- a/sample/Makefile +++ b/sample/Makefile @@ -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 diff --git a/sample/Makefile.macos b/sample/Makefile.macos index b9f4e594..263e688b 100644 --- a/sample/Makefile.macos +++ b/sample/Makefile.macos @@ -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 diff --git a/sample/Makefile.windows b/sample/Makefile.windows index c6ba0fae..db7719c9 100644 --- a/sample/Makefile.windows +++ b/sample/Makefile.windows @@ -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 diff --git a/sample/testxml.cc b/sample/testxml.cc deleted file mode 100644 index abdf2bbc..00000000 --- a/sample/testxml.cc +++ /dev/null @@ -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 -#include -#include -#include - -#include -#include - -#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; rnr; r++ ) \ - for( c=0; cname[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; copt.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(); -}