MuJoCo学习
前情提要
本人仅有C语言基础,具体内容仍在学习中,欢迎各位交流和批评指正
1.下载和安装
Navigate to https://github.com/deepmind/mujoco/
releases and download the windows installation,mujoco-windows-x86_64.zip
解压缩该文件并将其放在合适的位置(路径中不要有中文)
检查是否安装成功
打开bin目录下的simulate.exe
在 D:\07_MuJoCo\mujoco-3.0.1-windows-x86_64\model\hammock 下找到 hammock.xml 将其拖入其中
可以出现如下结果:
则证明安装成功
2.使用xml语言进行简单建模
创建以下xml文件:
<mujoco>
<worldbody>
<light diffuse=".5 .5 .5" pos="0 0 3" dir="0 0 -1"/>
<geom type="plane" size="1 1 0.1" rgba=".9 0 0 1"/>
<body pos="0 0 1">
<joint type="free"/>
<geom type="box" size=".1 .2 .3" rgba="0 .9 0 1"/>
</body>
</worldbody>
</mujoco>
拖入在Mujico中生成模型:
左侧工具栏中"Reload"键可以在每次改变xml文件后进行重新生成模型
3.尝试体验一下流程
3.1xml:为其建模:
<mujoco>
<worldbody>
<light diffuse=".5 .5 .5" pos="0 0 3" dir="0 0 -1"/>
<geom type="plane" size="1 1 0.1" rgba=".9 0 0 1"/>
<body pos="0 0 1">
<joint type="free"/>
<geom type="box" size=".1 .2 .3" rgba="0 .9 0 1"/>
</body>
</worldbody>
</mujoco>
效果:
3.2运功控制代码:为其添加动力和阻力
(本次实验仅做初次尝试使用,未理解其具体代码实现原理)
(1)打开 D:\07_MuJoCo\mujoco-2.2.1\sample下的“Makefile”
根据文件中顶部的注释进行相关文件的下载和移动
# A copy of the GLFW library is required to build some sample programs.
# If this is not already installed on your system, download the WIN64 archive
# from https://github.com/glfw/glfw/releases, and copy files as follows:
# - Copy the entire `include/GLFW` subdirectory to `mujoco/include/GLFW`.
# - Copy glfw3dll.lib from the subdirectory corresponding into your compiler
# choice to `mujoco/lib/glfw3dll.lib`.
# - Copy glfw3.dll from the same subdirectory into `mujoco/bin/glfw3.dll`.
(2)创建一个“myproject”的文件夹,存放项目文件
创建一个小球的模型文件.xml(上一步已完成)
为其添加动力和阻力
在该文件中,要注意其中对xml文件的存放位置
特别注意,为防止编译软件找不到mujoco相关头文件以及方便相关头文件的应用,对其相关头文件进行修改
第一步:打开以下文件路径:C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt
第二步:打开 \mujoco-3.0.1\include
打开每个文件,将其中的 <mujoco/mjdata.h> 改为<mjdata.h>,即将 mujoco/ 全部去掉
前:
后:
并将修改后的12个文件全部移到 C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt 路径下
第三步:将下载的
这两个文件一同移动到C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt
创建以下c文件:
#include<stdbool.h> //for bool
//#include<unistd.h> //for usleep
//#include <math.h>
#include "mujoco.h"
#include "glfw3.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
char filename[] = "D:/07_MuJoCo/mujoco-3.0.1/myproject/hello/hello.xml";
// MuJoCo data structures
mjModel* m = NULL; // MuJoCo model
mjData* d = NULL; // MuJoCo data
mjvCamera cam; // abstract camera
mjvOption opt; // visualization options
mjvScene scn; // abstract scene
mjrContext con; // custom GPU context
// mouse interaction
bool button_left = false;
bool button_middle = false;
bool button_right = false;
double lastx = 0;
double lasty = 0;
// holders of one step history of time and position to calculate dertivatives
mjtNum position_history = 0;
mjtNum previous_time = 0;
// controller related variables
float_t ctrl_update_freq = 100;
mjtNum last_update = 0.0;
mjtNum ctrl;
// keyboard callback
void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods)
{
// backspace: reset simulation
if( act==GLFW_PRESS && key==GLFW_KEY_BACKSPACE )
{
mj_resetData(m, d);
mj_forward(m, d);
}
}
// mouse button callback
void mouse_button(GLFWwindow* window, int button, int act, int mods)
{
// update button state
button_left = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
button_middle = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
button_right = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
// update mouse position
glfwGetCursorPos(window, &lastx, &lasty);
}
// mouse move callback
void mouse_move(GLFWwindow* window, double xpos, double ypos)
{
// no buttons down: nothing to do
if( !button_left && !button_middle && !button_right )
return;
// compute mouse displacement, save
double dx = xpos - lastx;
double dy = ypos - lasty;
lastx = xpos;
lasty = ypos;
// get current window size
int width, height;
glfwGetWindowSize(window, &width, &height);
// get shift key state
bool mod_shift = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
// determine action based on mouse button
mjtMouse action;
if( button_right )
action = mod_shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V;
else if( button_left )
action = mod_shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V;
else
action = mjMOUSE_ZOOM;
// move camera
mjv_moveCamera(m, action, dx/height, dy/height, &scn, &cam);
}
// scroll callback
void scroll(GLFWwindow* window, double xoffset, double yoffset)
{
// emulate vertical mouse motion = 5% of window height
mjv_moveCamera(m, mjMOUSE_ZOOM, 0, -0.05*yoffset, &scn, &cam);
}
// main function
int main(int argc, const char** argv)
{
// load and compile model
char error[1000] = "Could not load binary model";
// check command-line arguments
if( argc<2 )
m = mj_loadXML(filename, 0, error, 1000);
else
if( strlen(argv[1])>4 && !strcmp(argv[1]+strlen(argv[1])-4, ".mjb") )
m = mj_loadModel(argv[1], 0);
else
m = mj_loadXML(argv[1], 0, error, 1000);
if( !m )
mju_error_s("Load model error: %s", error);
// make data
d = mj_makeData(m);
// init GLFW
if( !glfwInit() )
mju_error("Could not initialize GLFW");
// create window, make OpenGL context current, request v-sync
GLFWwindow* window = glfwCreateWindow(1244, 700, "Demo", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// initialize visualization data structures
mjv_defaultCamera(&cam);
mjv_defaultOption(&opt);
mjv_defaultScene(&scn);
mjr_defaultContext(&con);
mjv_makeScene(m, &scn, 2000); // space for 2000 objects
mjr_makeContext(m, &con, mjFONTSCALE_150); // model-specific context
// install GLFW mouse and keyboard callbacks
glfwSetKeyCallback(window, keyboard);
glfwSetCursorPosCallback(window, mouse_move);
glfwSetMouseButtonCallback(window, mouse_button);
glfwSetScrollCallback(window, scroll);
while( !glfwWindowShouldClose(window))
{
mjtNum simstart = d->time;
while( d->time - simstart < 1.0/60.0 )
{
mj_step(m, d);
}
// get framebuffer viewport
mjrRect viewport = {0, 0, 0, 0};
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
// update scene and render
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
mjr_render(viewport, &scn, &con);
// swap OpenGL buffers (blocking call due to v-sync)
glfwSwapBuffers(window);
// process pending GUI events, call GLFW callbacks
glfwPollEvents();
}
// free visualization storage
mjv_freeScene(&scn);
mjr_freeContext(&con);
// free MuJoCo model and data, deactivate
mj_deleteData(d);
mj_deleteModel(m);
// terminate GLFW (crashes with Linux NVidia drivers)
#if defined(__APPLE__) || defined(_WIN32)
glfwTerminate();
#endif
return 1;
}
注意!!!
若出现:
则证明第12行的.xml文件路径指定错误;
若出现:
则证明在c文件中出现了mj_activate,删除即可;
3.3修改makefile文件
COMMON=/O2 /MT /EHsc /arch:AVX /I../../include /Fe../../bin/
LIBS = ../../lib/glfw3dll.lib ../../lib/mujoco.lib
CC = cl
ROOT = hello
all:
$(CC) $(COMMON) hello.c $(LIBS) -o ../../bin/$(ROOT)
main.o:
$(CC) $(COMMON) -c hello.c
clean:
rm *.o ../../bin/$(ROOT)
注意!!!
“ROOT = hello”中,hello指的是makefile文件所在的文件目录
两处“hello.c ”均是所建立的C文件名称!
这样在该目录下有以下三个文件
运行
打开vs studio下的该程序
来到该目录下
输入“nmake”运行
输入“hello”或者在 “bin”下找到“main.exe”,点击运行
运行效果: