From 3a4b6e6c5bbf14963e77ebb9ca1fa80f74416b27 Mon Sep 17 00:00:00 2001 From: Tom Power Date: Wed, 28 May 2025 06:12:22 -0700 Subject: [PATCH] Added terrain generation to mjspec tutorial PiperOrigin-RevId: 764229337 Change-Id: Ic541eefc4b561d3c39c5ee99c7d38466d7e75903 --- doc/changelog.rst | 9 + .../procedural_terrain_generation.png | Bin 0 -> 85112 bytes python/mjspec.ipynb | 844 +++++++++++++++++- 3 files changed, 848 insertions(+), 5 deletions(-) create mode 100644 doc/images/changelog/procedural_terrain_generation.png diff --git a/doc/changelog.rst b/doc/changelog.rst index 8f5135b6..b425416f 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -24,6 +24,15 @@ Simulate ``mjData`` when the Python viewer is used in passive mode. This functionality is now provided by :ref:`mjv_copyModel` and :ref:`mjv_copyData`, which don't copy arrays which are not required for visualization. +.. image:: images/changelog/procedural_terrain_generation.png + :width: 25% + :align: right + +Python bindings +^^^^^^^^^^^^^^^ + +- Added examples of procedural terrain generation to the Model Editing tutorial: |mjspec_colab| + Version 3.3.2 (April 28, 2025) ------------------------------ diff --git a/doc/images/changelog/procedural_terrain_generation.png b/doc/images/changelog/procedural_terrain_generation.png new file mode 100644 index 0000000000000000000000000000000000000000..7c083dff7513baa769fa2e357b825a13acfae0e8 GIT binary patch literal 85112 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

UyjZpXqs%K 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

`vaj`q7MGH+B5Z+TyuB%sljU90;w(-vD}5rB zL!k^%{KIMsjZxlA4KEK{h8kCSROC@0JqsOF&`S@`Ry)c#o zL!ftFzlaG4d!^0$2Q*dc8#SlZc>%!YqNdcfZtIAyCYD_}z=0!z#VtyZ5P}GV0wG8U zZ};((_N5Q0CY24LI`2^g>xC zj%WEmj2Y*GY@FzEWzKi2!b>Rn%7 zwrEb>f<+A-2l^j;^pogdV%qd7Gh_Yg{`dAA9H^}bG&h$H^~8e#cgU^&?r-m}{pe72 zx&N%wCZ{vz&W%TtNn_^J%9Tqeop$nsk&)D))}bkr%cFhqiBl^lw$ucCs+~5H8MCY| z^5lO$dw0$5x~gEfCcJBV=bD$duU~iIOV=#?+RZ1wv1ZS@clRGTJhcgDVCvK=g+$|B8F>z&NU_Z}^s(+1}KsSOF&NvS z6M7GX7D^xqgkF-+LNB5BZm_XwHa56dxyhE*yR_2wopSGa|Crg`S>Yt`ywCT3OVO4) z{ho5q`JLa9GOUOtTJiuYo?NMov+inYFFC)`X1C~g32G7LVsWrq#LM$t^K)}YX6XTQ z1c-{%k>fy`-qJbIWioLjPSLI{&Hm3@n|l3`$@bi_IR+>iA*^sqiK~81L+rCQ+wnP~ zT{NnxFd`UrL_>o$l5}pdb554qYa<4^5{OPq#;E*~8AU~>7KbWDyU!}xM5BQNHpy)= zo(zf4fJ}U|W{SLoh^9EL%<-C}q2`9~ZIbeIz=#p?oi=sYUH7k=I=&<;$Ias!A$nb* z`FtQ9Mv|1_B)&4GXarq1$SR*VKIgMd-FBO>?QmdrO~znE&2)%4U~AL%y&YxM1z4b(#t6YkB44cBW3`Fzy?h}H$x3gyd{~y`vE6;|%B&pc z1CO170x|zU^vS2!g~IZjS;NQ9s?-Lfh{M5y-6f@&h~VNPFCs+g331K|C3!`@J=

rH8*iMi_oTC0#n;~5wt0Kg^Zz(= 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 T-\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \"\"\"\n", + "\n", + " spec = mj.MjSpec.from_string(arena_xml)\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + "\n", + " name = 'base_tile'\n", + "\n", + " spec.worldbody.add_body(pos=[-3, 0, 0], name=name)\n", + " if direction:\n", + " tile_func(spec, direction=direction)\n", + " else:\n", + " tile_func(spec)\n", + "\n", + " model = spec.compile()\n", + " data = mj.MjData(model)\n", + "\n", + " cam = mj.MjvCamera()\n", + " mj.mjv_defaultCamera(cam)\n", + " cam.lookat = [0, 0, 0]\n", + " cam.distance = cam_distance\n", + " cam.elevation = cam_elevation\n", + "\n", + " height = 300\n", + "\n", + " with mj.Renderer(model, 480, 640) as renderer:\n", + " mj.mj_forward(model, data)\n", + " renderer.update_scene(data,cam)\n", + " media.show_image(renderer.render(), height=height)\n", + "\n", + "\n", + "def interpolant(t):\n", + " return t*t*t*(t*(t*6 - 15) + 10)\n", + "\n", + "def perlin(shape, res, tileable=(False, False), interpolant=interpolant):\n", + " \"\"\"Generate a 2D numpy array of perlin noise.\n", + "\n", + " Args:\n", + " shape: The shape of the generated array (tuple of two ints).\n", + " This must be a multiple of res.\n", + " res: The number of periods of noise to generate along each\n", + " axis (tuple of two ints). Note shape must be a multiple of\n", + " res.\n", + " tileable: If the noise should be tileable along each axis\n", + " (tuple of two bools). Defaults to (False, False).\n", + " interpolant: The interpolation function, defaults to\n", + " t*t*t*(t*(t*6 - 15) + 10).\n", + "\n", + " Returns:\n", + " A numpy array of shape shape with the generated noise.\n", + "\n", + " Raises:\n", + " ValueError: If shape is not a multiple of res.\n", + " \"\"\"\n", + " delta = (res[0] / shape[0], res[1] / shape[1])\n", + " d = (shape[0] // res[0], shape[1] // res[1])\n", + " grid = np.mgrid[0:res[0]:delta[0], 0:res[1]:delta[1]]\\\n", + " .transpose(1, 2, 0) % 1\n", + " # Gradients\n", + " angles = 2*np.pi*np.random.rand(res[0]+1, res[1]+1)\n", + " gradients = np.dstack((np.cos(angles), np.sin(angles)))\n", + " if tileable[0]:\n", + " gradients[-1,:] = gradients[0,:]\n", + " if tileable[1]:\n", + " gradients[:,-1] = gradients[:,0]\n", + " gradients = gradients.repeat(d[0], 0).repeat(d[1], 1)\n", + " g00 = gradients[ :-d[0], :-d[1]]\n", + " g10 = gradients[d[0]: , :-d[1]]\n", + " g01 = gradients[ :-d[0],d[1]: ]\n", + " g11 = gradients[d[0]: ,d[1]: ]\n", + " # Ramps\n", + " n00 = np.sum(np.dstack((grid[:,:,0] , grid[:,:,1] )) * g00, 2)\n", + " n10 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1] )) * g10, 2)\n", + " n01 = np.sum(np.dstack((grid[:,:,0] , grid[:,:,1]-1)) * g01, 2)\n", + " n11 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1]-1)) * g11, 2)\n", + " # Interpolation\n", + " t = interpolant(grid)\n", + " n0 = n00*(1-t[:,:,0]) + t[:,:,0]*n10\n", + " n1 = n01*(1-t[:,:,0]) + t[:,:,0]*n11\n", + " return np.sqrt(2)*((1-t[:,:,1])*n0 + t[:,:,1]*n1)\n", + "\n", + "def edge_slope(size, border_width=5, blur_iterations=20):\n", + " \"\"\"Creates a grayscale image with a white center and fading black edges using convolution.\"\"\"\n", + " img = np.ones((size, size), dtype=np.float32)\n", + " img[:border_width, :] = 0\n", + " img[-border_width:, :] = 0\n", + " img[:, :border_width] = 0\n", + " img[:, -border_width:] = 0\n", + "\n", + " kernel = np.array([[1, 1, 1],\n", + " [1, 1, 1],\n", + " [1, 1, 1]]) / 9.0\n", + "\n", + " for _ in range(blur_iterations):\n", + " img = convolve2d(img, kernel, mode='same', boundary='symm')\n", + "\n", + " return img" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "dtFWSSwWSgeD" + }, + "outputs": [], + "source": [ + "# @title Stairs\n", + "def stairs(spec=None, grid_loc=[0, 0] , num_stairs=4, direction=1, name='stair'):\n", + " SQUARE_LENGTH = 2\n", + " V_SIZE = 0.076\n", + " H_SIZE = 0.12\n", + " H_STEP = H_SIZE * 2\n", + " V_STEP = V_SIZE * 2\n", + " BROWN = [0.460, 0.362, 0.216, 1.0]\n", + "\n", + " if spec == None:\n", + " spec = mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + "\n", + " body = spec.worldbody.add_body(pos=grid_loc + [0], name=name)\n", + " # Offset\n", + " x_beginning, y_end = [-SQUARE_LENGTH + H_SIZE] * 2\n", + " x_end, y_beginning = [SQUARE_LENGTH - H_SIZE] * 2\n", + " # Dimension\n", + " size_one = [H_SIZE, SQUARE_LENGTH, V_SIZE]\n", + " size_two = [SQUARE_LENGTH, H_SIZE, V_SIZE]\n", + " # Geoms positions\n", + " x_pos_l = [x_beginning, 0, direction * V_SIZE]\n", + " x_pos_r = [x_end, 0, direction * V_SIZE]\n", + " y_pos_up = [0, y_beginning, direction * V_SIZE]\n", + " y_pos_down = [0, y_end, direction * V_SIZE]\n", + "\n", + " for i in range(num_stairs):\n", + " size_one[1] = SQUARE_LENGTH - H_STEP * i\n", + " size_two[0] = SQUARE_LENGTH - H_STEP * i\n", + "\n", + " x_pos_l[2], x_pos_r[2], y_pos_up[2], y_pos_down[2] = [\n", + " direction * ( V_SIZE + V_STEP * i)] * 4\n", + "\n", + " # Left side\n", + " x_pos_l[0] = x_beginning + H_STEP * i\n", + " body.add_geom(pos=x_pos_l, size=size_one, rgba=BROWN)\n", + " # Right side\n", + " x_pos_r[0] = x_end - H_STEP * i\n", + " body.add_geom(pos=x_pos_r, size=size_one, rgba=BROWN)\n", + " # Top\n", + " y_pos_up[1] = y_beginning - H_STEP * i\n", + " body.add_geom(pos=y_pos_up, size=size_two, rgba=BROWN)\n", + " # Bottom\n", + " y_pos_down[1] = y_end + H_STEP * i\n", + " body.add_geom(pos=y_pos_down, size=size_two, rgba=BROWN)\n", + "\n", + " # Closing\n", + " size = [SQUARE_LENGTH - H_STEP * num_stairs,\n", + " SQUARE_LENGTH - H_STEP * num_stairs,\n", + " V_SIZE]\n", + " pos = [0, 0,\n", + " direction * (V_SIZE + V_STEP * num_stairs)]\n", + " body.add_geom(pos=pos, size=size, rgba=BROWN)\n", + "\n", + "render_tile(stairs, direction=random.choice([-1, 1]))" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "YwX50AtzSmnT" + }, + "outputs": [], + "source": [ + "# @title Debris (Geoms)\n", + "def debris_with_simple_geoms(spec=None, grid_loc=[0, 0], name='plane'):\n", + " SQUARE_LENGTH = 2\n", + " THICKNESS = 0.05\n", + " BROWN = [0.460, 0.362, 0.216, 1.0]\n", + " RED = [0.6, 0.12, 0.15, 1.0]\n", + "\n", + " if spec == None:\n", + " spec = mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + "\n", + " # Create tile\n", + " body = spec.worldbody.add_body(pos=grid_loc + [0], name=name)\n", + " body.add_geom(size=[SQUARE_LENGTH, SQUARE_LENGTH, THICKNESS], rgba=BROWN )\n", + "\n", + " # Simple Geoms\n", + " x_beginning, y_end = [-SQUARE_LENGTH + THICKNESS] * 2\n", + " x_end, y_beginning = [SQUARE_LENGTH - THICKNESS] * 2\n", + "\n", + " x_grid = np.linspace(x_beginning, x_end, 10)\n", + " y_grid = np.linspace(y_beginning, y_end, 10)\n", + "\n", + " for i in range(10):\n", + " x = np.random.choice(x_grid)\n", + " y = np.random.choice(y_grid)\n", + "\n", + " pos=[grid_loc[0] + x, grid_loc[1] + y, 0.2]\n", + "\n", + " g_type = None\n", + " size = None\n", + " if random.randint(0, 1):\n", + " g_type = mj.mjtGeom.mjGEOM_BOX\n", + " size = [0.1, 0.1, 0.02]\n", + " else:\n", + " g_type = mj.mjtGeom.mjGEOM_CYLINDER\n", + " size = [0.1, 0.02, 0]\n", + "\n", + " body = spec.worldbody.add_body(pos=pos, name=f'g{i}_{name}', mass=1)\n", + " body.add_geom(type=g_type, size=size, rgba=RED)\n", + " body.add_freejoint()\n", + "\n", + "render_tile(debris_with_simple_geoms)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "Wm_0DHK8S2kQ" + }, + "outputs": [], + "source": [ + "# @title Debris (Mesh)\n", + "def debris(spec=None, grid_loc=[0, 0] , name='debris'):\n", + " SQUARE_LENGTH = 2\n", + " THICKNESS = 0.05\n", + " STEP = THICKNESS * 8\n", + " SCALE = 0.1\n", + " BROWN = [0.460, 0.362, 0.216, 1.0]\n", + " RED = [0.6, 0.12, 0.15, 1.0]\n", + "\n", + " if spec == None:\n", + " spec = mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + " main.mesh.scale = np.array([SCALE]*3, dtype=np.float64)\n", + "\n", + " x_beginning = -SQUARE_LENGTH + THICKNESS\n", + " y_beginning = SQUARE_LENGTH - THICKNESS\n", + "\n", + " # Create tile\n", + " body = spec.worldbody.add_body(pos=grid_loc + [0], name=name)\n", + " body.add_geom(size=[SQUARE_LENGTH, SQUARE_LENGTH, THICKNESS], rgba=BROWN)\n", + "\n", + " # Place debris on the tile\n", + " for i in range(10):\n", + " for j in range(10):\n", + " # draw on xy plane\n", + " drawing = np.random.normal(size=(4, 2))\n", + " drawing /= np.linalg.norm(drawing, axis=1, keepdims=True)\n", + " z = np.zeros((drawing.shape[0], 1))\n", + " # Add z value to drawing\n", + " base = np.concatenate((drawing, z), axis=1)\n", + " # Extrude drawing\n", + " z_extrusion = np.full((drawing.shape[0], 1), THICKNESS * 4)\n", + " top = np.concatenate((drawing, z_extrusion), axis=1)\n", + " # Combine to get a mesh\n", + " mesh = np.vstack((base, top))\n", + "\n", + " # Create body and add the mesh to the geom of the body\n", + " spec.add_mesh(name=f'd{i}_{j}_{name}', uservert=mesh.flatten())\n", + " pos=[grid_loc[0] + x_beginning + i * STEP,\n", + " grid_loc[1] + y_beginning - j * STEP,\n", + " 0.2]\n", + "\n", + " body = spec.worldbody.add_body(pos=pos, name=f'd{i}_{j}_{name}', mass=1)\n", + " body.add_geom(type=mj.mjtGeom.mjGEOM_MESH, meshname=f'd{i}_{j}_{name}',\n", + " rgba=RED)\n", + " body.add_freejoint()\n", + "\n", + "render_tile(debris)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "BqTG_K8uS3v_" + }, + "outputs": [], + "source": [ + "# @title Boxy Terrain\n", + "def boxy_terrain(spec=None, grid_loc=[0, 0], name='boxy_terrain'):\n", + " SQUARE_LENGTH = 2\n", + " CUBE_LENGTH = 0.05\n", + " GRID_SIZE = int(SQUARE_LENGTH / CUBE_LENGTH)\n", + " STEP = CUBE_LENGTH * 2\n", + " BROWN = [0.460, 0.362, 0.216, 1.0]\n", + "\n", + " if spec == None:\n", + " spec=mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + "\n", + " # Create tile\n", + " body = spec.worldbody.add_body(pos=grid_loc + [0], name=name)\n", + "\n", + " x_beginning = -SQUARE_LENGTH + CUBE_LENGTH\n", + " y_beginning = SQUARE_LENGTH - CUBE_LENGTH\n", + " for i in range(GRID_SIZE):\n", + " for j in range(GRID_SIZE):\n", + " body.add_geom(\n", + " pos=[x_beginning + i * STEP ,\n", + " y_beginning - j * STEP ,\n", + " random.randint(-1, 1) * CUBE_LENGTH\n", + " ],\n", + " size=[CUBE_LENGTH] * 3,\n", + " rgba=BROWN\n", + " )\n", + "\n", + "render_tile(boxy_terrain)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "gfQ1CafnS7hs" + }, + "outputs": [], + "source": [ + "# @title Box (Extrusion | Cut)\n", + "def box_extrusions(spec=None, grid_loc=[0, 0], complex=False,\n", + " name='box_extrusions'):\n", + " # Warning! complex sometimes leads to creation of holes\n", + " SQUARE_LENGTH = 2\n", + " CUBE_LENGTH = 0.05\n", + " GRID_SIZE = int(SQUARE_LENGTH / CUBE_LENGTH)\n", + " STEP = CUBE_LENGTH * 2\n", + " BROWN = [0.460, 0.362, 0.216, 1.0]\n", + "\n", + " if spec == None:\n", + " spec = mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + "\n", + " # Create tile\n", + " body = spec.worldbody.add_body(pos=grid_loc + [0], name=name)\n", + "\n", + " x_beginning = -SQUARE_LENGTH + CUBE_LENGTH\n", + " y_beginning = SQUARE_LENGTH - CUBE_LENGTH\n", + "\n", + " # Create initial grid and store geoms ref\n", + " grid = [[ 0 for _ in range(GRID_SIZE)] for _ in range(GRID_SIZE)]\n", + " for i in range(GRID_SIZE):\n", + " for j in range(GRID_SIZE):\n", + " ref = body.add_geom(\n", + " pos=[x_beginning + i * STEP, y_beginning - j * STEP, 0],\n", + " size=[CUBE_LENGTH] * 3,\n", + " rgba = BROWN\n", + " )\n", + " grid[i][j] = ref\n", + "\n", + " # Extrude or Cut operation using the boxes\n", + " for _ in range(random.randint(4, 50)):\n", + " box = None\n", + " while box == None:\n", + " # Create a box\n", + " start = (random.randint(0, GRID_SIZE - 2), random.randint(0, GRID_SIZE - 2))\n", + " dim = (random.randint(0, GRID_SIZE - 2), random.randint(0, GRID_SIZE-2))\n", + " # Make suer box is valid\n", + " if start[0] + dim [0] < len(grid) and start[1] + dim [1] < len(grid):\n", + " box = {\"start\":start, \"dim\":dim}\n", + "\n", + " # Use the box to Cut or Extrude\n", + " operation = random.choice([1, -1])\n", + " start = box[\"start\"]\n", + " dim = box[\"dim\"]\n", + " for i in range(start[0], dim[0]):\n", + " for j in range(start[1], dim[1]):\n", + " tile = grid[i][j]\n", + " if complex:\n", + " tile.pos[2] += operation * CUBE_LENGTH\n", + " else:\n", + " tile.pos[2] = operation * CUBE_LENGTH\n", + "\n", + "render_tile(box_extrusions)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "e1PEGQ37S_ee" + }, + "outputs": [], + "source": [ + "# @title Heightfield\n", + "def h_field(spec=None, grid_loc=[0, 0], name='h_field'):\n", + " SQUARE_LENGTH = 2\n", + " HEIGHT = 0.1\n", + " BROWN_RGBA = [0.460, 0.362, 0.216, 1.0]\n", + "\n", + " if spec is None:\n", + " spec = mj.MjSpec()\n", + "\n", + " size = 128\n", + " noise = perlin((size, size), (8, 8))\n", + "\n", + " # Remap noise to 0 to 1\n", + " noise = (noise + 1)/2\n", + " noise -= np.min(noise)\n", + " noise /= np.max(noise)\n", + "\n", + " # Makes the edges slope down to avoid sharp boundary\n", + " noise *= edge_slope(size)\n", + "\n", + " # Create height field\n", + " hfield = spec.add_hfield(name=name,\n", + " size=[SQUARE_LENGTH, SQUARE_LENGTH,\n", + " HEIGHT, HEIGHT/10],\n", + " nrow=noise.shape[0],\n", + " ncol=noise.shape[1],\n", + " userdata=noise.flatten())\n", + "\n", + " body = spec.worldbody.add_body(pos=grid_loc + [0], name=name)\n", + " body.add_geom(type=mj.mjtGeom.mjGEOM_HFIELD, hfieldname=name,\n", + " rgba=BROWN_RGBA)\n", + "\n", + "render_tile(h_field)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "UwDVd6aUTRKF" + }, + "outputs": [], + "source": [ + "# @title Floating platform\n", + "def floating_platform(spec=None, gird_loc=[0, 0, 0], name='platform'):\n", + " PLATFORM_LENGTH = 0.5\n", + " WIDTH = 0.12\n", + " INWARD_OFFSET = 0.008\n", + " THICKNESS = 0.005\n", + " SIZE = [PLATFORM_LENGTH, WIDTH, THICKNESS]\n", + " TENDON_LENGTH = 0.5\n", + " Z_OFFSET = 0.1\n", + "\n", + " GOLD = [0.850, 0.838, 0.119, 1]\n", + "\n", + " if spec == None:\n", + " spec = mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + "\n", + " # Platform with sites\n", + " gird_loc[2] += Z_OFFSET\n", + " platform = spec.worldbody.add_body(pos=gird_loc, name=name)\n", + " platform.add_geom(size=SIZE, rgba=GOLD)\n", + " platform.add_freejoint()\n", + "\n", + " for x_dir in [-1, 1]:\n", + " for y_dir in [-1, 1]:\n", + " # Add site to world\n", + " vector = np.array([x_dir * PLATFORM_LENGTH,\n", + " y_dir * (WIDTH - INWARD_OFFSET)])\n", + " x_w = gird_loc[0] + vector[0]\n", + " y_w = gird_loc[1] + vector[1]\n", + " z_w = gird_loc[2] + TENDON_LENGTH\n", + " # Rotate sites by theta\n", + " spec.worldbody.add_site(name=f'{name}_hook_{x_dir}_{y_dir}',\n", + " pos=[ x_w, y_w, z_w],\n", + " size=[0.01, 0, 0])\n", + " # Add site to platform\n", + " x_p = x_dir * PLATFORM_LENGTH\n", + " y_p = y_dir * (WIDTH - INWARD_OFFSET)\n", + " platform.add_site(name=f'{name}_anchor_{x_dir}_{y_dir}',\n", + " pos=[ x_p, y_p, THICKNESS * 2],\n", + " size=[0.01, 0, 0])\n", + "\n", + " # Connect tendon to sites\n", + " thread = spec.add_tendon(name=f'{name}_thread_{x_dir}_{y_dir}',\n", + " limited=True,\n", + " range=[0, TENDON_LENGTH], width=0.01 )\n", + " thread.wrap_site(f'{name}_hook_{x_dir}_{y_dir}')\n", + " thread.wrap_site(f'{name}_anchor_{x_dir}_{y_dir}')\n", + "\n", + "render_tile(floating_platform, cam_distance=2, cam_elevation=-20)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "Wb4GmZewTSVI" + }, + "outputs": [], + "source": [ + "# @title Simple stairs\n", + "def simple_suspended_stair(spec=None, grid_loc=[0, 0], num_stair=20,\n", + " name=\"simple_suspended_stair\"):\n", + " BROWN= [0.460, 0.362, 0.216, 1.0]\n", + " SQUARE_LENGTH = 2\n", + " THICKNESS = 0.05\n", + " OFFSET_Y = -4/5 * SQUARE_LENGTH\n", + "\n", + " V_STEP = 0.076\n", + " H_STEP = 0.12\n", + "\n", + " if spec == None:\n", + " spec = mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + "\n", + " # Create tile\n", + " body = spec.worldbody.add_body(pos=grid_loc + [0], name=name)\n", + " body.add_geom(size=[SQUARE_LENGTH, SQUARE_LENGTH, THICKNESS], rgba=BROWN)\n", + "\n", + " # Create Stairs\n", + " for i in range(num_stair):\n", + " floating_platform(spec,[grid_loc[0],\n", + " OFFSET_Y + grid_loc[1] + i * 2 * H_STEP,\n", + " i * V_STEP],\n", + " name =f'{name}_p_{i}')\n", + "\n", + "render_tile(simple_suspended_stair,cam_distance=7, cam_elevation=-30)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "AaoLjrKeTXu-" + }, + "outputs": [], + "source": [ + "# @title Sinusoidal stairs\n", + "def sin_suspended_stair(spec, grid_loc=[0, 0], num_stair=40,\n", + " name=\"sin_suspended_stair\"):\n", + " BROWN = [0.460, 0.362, 0.216, 1.0]\n", + " SQUARE_LENGTH = 2\n", + " THICKNESS = 0.05\n", + " OFFSET_Y = -4/5 * SQUARE_LENGTH\n", + "\n", + " V_STEP = 0.076\n", + " H_STEP = 0.12\n", + " AMPLITUDE = 0.2\n", + " FREQUENCY = 0.5\n", + "\n", + " if spec == None:\n", + " spec = mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + "\n", + " # Plane\n", + " body = spec.worldbody.add_body(pos=grid_loc + [0], name=name)\n", + " body.add_geom(size=[SQUARE_LENGTH, SQUARE_LENGTH, THICKNESS], rgba=BROWN)\n", + "\n", + " for i in range(num_stair):\n", + " x_step = AMPLITUDE * np.sin(2 * np.pi * FREQUENCY * (i * H_STEP))\n", + " floating_platform(spec, [grid_loc[0] + x_step,\n", + " OFFSET_Y + grid_loc[1] + i * 2 * H_STEP,\n", + " i * V_STEP],\n", + " name=f'{name}_p_{i}')\n", + "\n", + "render_tile(sin_suspended_stair,cam_distance=7, cam_elevation=-30)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "2_Ux8h-PTqbW" + }, + "outputs": [], + "source": [ + "# @title Floating platform for circular stair\n", + "def floating_platform_for_circular_stair(spec=None, gird_loc=[0, 0, 0] ,theta=0,\n", + " name='platform'):\n", + " PLATFORM_LENGTH = 0.5\n", + " TENDON_LENGTH = 0.5\n", + " WIDTH = 0.12/4 # Platform (body) is made of 4 separate geoms\n", + " THICKNESS = 0.005\n", + " SIZE = [PLATFORM_LENGTH, WIDTH, THICKNESS]\n", + " Z_OFFSET = 0.1\n", + "\n", + " GOLD = [0.850, 0.838, 0.119, 1]\n", + "\n", + " if spec == None:\n", + " spec = mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + " spec.compiler.degree = False\n", + "\n", + " # Platform with sites\n", + " gird_loc[2] += Z_OFFSET\n", + " platform = spec.worldbody.add_body(pos=gird_loc, name=name, euler=[0, 0, theta])\n", + " platform.add_geom(pos=[0, 0, 0] , size=SIZE, euler=[0, 0, 0],rgba=GOLD)\n", + " platform.add_geom(pos=[0, 0.02, 0], size=SIZE, euler=[0, 0, 0.05],rgba=GOLD)\n", + " platform.add_geom(pos=[0, 0.05, 0], size=SIZE, euler=[0, 0, 0.1],rgba=GOLD)\n", + " platform.add_geom(pos=[0, 0.08, 0], size=SIZE, euler=[0, 0, 0.15],rgba=GOLD)\n", + " platform.add_freejoint()\n", + "\n", + " for i, x_dir in enumerate([-1, 1]):\n", + " for j, y_dir in enumerate([-1, 1]):\n", + " # Rotate sites by theta\n", + " rotation_matrix = np.array([[np.cos(-theta), -np.sin(-theta)],\n", + " [np.sin(-theta), np.cos(-theta)]])\n", + " vector = np.array([x_dir * PLATFORM_LENGTH, y_dir * WIDTH ])\n", + " if i + j == 2:\n", + " vector = np.array([x_dir * PLATFORM_LENGTH, y_dir * 6 * WIDTH ])\n", + " vector = np.dot(vector , rotation_matrix)\n", + " x_w = gird_loc[0] + vector[0]\n", + " y_w = gird_loc[1] + vector[1]\n", + " z_w = gird_loc[2] + TENDON_LENGTH\n", + "\n", + " # Add site to world\n", + " spec.worldbody.add_site(name=f'{name}_hook_{x_dir}_{y_dir}',\n", + " pos=[ x_w, y_w, z_w],\n", + " size=[0.01, 0, 0])\n", + " # Add site to platform\n", + " x_p = x_dir * PLATFORM_LENGTH\n", + " y_p = y_dir * WIDTH\n", + " if i + j == 2:\n", + " y_p = y_dir * 6 * WIDTH\n", + " platform.add_site(name=f'{name}_anchor_{x_dir}_{y_dir}',\n", + " pos=[x_p, y_p, THICKNESS * 2],\n", + " size=[0.01, 0, 0])\n", + "\n", + " # Connect tendon to sites\n", + " thread = spec.add_tendon(name=f'{name}_thread_{x_dir}_{y_dir}', limited=True,\n", + " range=[0, TENDON_LENGTH], width=0.01 )\n", + " thread.wrap_site(f'{name}_hook_{x_dir}_{y_dir}')\n", + " thread.wrap_site(f'{name}_anchor_{x_dir}_{y_dir}')\n", + "\n", + "render_tile(floating_platform_for_circular_stair,cam_distance=2, cam_elevation=-40)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "UXSDdVF8TwmQ" + }, + "outputs": [], + "source": [ + "# @title Circular stairs\n", + "def circular_stairs(spec, grid_loc=[0, 0], num_stair=60, name=\"circular_stairs\"):\n", + " BROWN_RGBA = [0.460, 0.362, 0.216, 1.0]\n", + " SQUARE_LENGTH = 2\n", + " THICKNESS = 0.05\n", + "\n", + " RADIUS = 1.5\n", + " V_STEP = 0.076\n", + "\n", + " if spec == None:\n", + " spec = mj.MjSpec()\n", + "\n", + " # Defaults\n", + " main = spec.default\n", + " main.geom.type = mj.mjtGeom.mjGEOM_BOX\n", + " spec.compiler.degree = False\n", + "\n", + " # Plane\n", + " body = spec.worldbody.add_body(pos=grid_loc + [0], name=name)\n", + " body.add_geom(size = [SQUARE_LENGTH, SQUARE_LENGTH, THICKNESS], rgba = BROWN_RGBA )\n", + "\n", + " theta_step = 2 * np.pi / num_stair\n", + " for i in range(num_stair):\n", + " theta = i * theta_step\n", + " x = grid_loc[0] + RADIUS * np.cos(theta)\n", + " y = grid_loc[1] + RADIUS * np.sin(theta)\n", + " z = i * V_STEP\n", + "\n", + " floating_platform_for_circular_stair(spec, [x, y, z], theta=theta, name=f'{name}_p_{i}')\n", + "\n", + "render_tile(circular_stairs,cam_distance=12, cam_elevation=-30)" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "lsDky1KjT30W" + }, + "outputs": [], + "source": [ + "# @title Tile Generator\n", + "def add_tile(spec=None, grid_loc=[0, 0]):\n", + " if spec is None:\n", + " spec = mj.MjSpec()\n", + "\n", + " tile_type = random.randint(0, 9)\n", + "\n", + " if tile_type == 0:\n", + " debris_with_simple_geoms(spec, grid_loc, name=f\"plane_{grid_loc[0]}_{grid_loc[1]}\")\n", + " elif tile_type == 1:\n", + " stairs(spec, grid_loc, name=f\"stairs_up_{grid_loc[0]}_{grid_loc[1]}\",direction=1)\n", + " elif tile_type == 2:\n", + " stairs(spec, grid_loc, name=f\"stairs_down_{grid_loc[0]}_{grid_loc[1]}\",direction=-1)\n", + " elif tile_type == 3:\n", + " debris(spec, grid_loc, name=f\"debris_{grid_loc[0]}_{grid_loc[1]}\")\n", + " elif tile_type == 4:\n", + " box_extrusions(spec, grid_loc, name=f\"box_extrusions_{grid_loc[0]}_{grid_loc[1]}\")\n", + " elif tile_type == 5:\n", + " boxy_terrain(spec, grid_loc, name=f\"boxy_terrain_{grid_loc[0]}_{grid_loc[1]}\")\n", + " elif tile_type == 6:\n", + " h_field(spec, grid_loc, name=f\"h_field_{grid_loc[0]}_{grid_loc[1]}\")\n", + " elif tile_type == 7:\n", + " simple_suspended_stair(spec, grid_loc, name=f\"sss_{grid_loc[0]}_{grid_loc[1]}\")\n", + " elif tile_type == 8:\n", + " sin_suspended_stair(spec, grid_loc, name=f\"sinss_{grid_loc[0]}_{grid_loc[1]}\")\n", + " elif tile_type == 9:\n", + " circular_stairs(spec, grid_loc, name=f\"circular_s_{grid_loc[0]}_{grid_loc[1]}\")\n", + " return spec" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "id": "P2F0ObC2T8w8" + }, + "outputs": [], + "source": [ + "# @title Generate Terrain\n", + "arena_xml = \"\"\"\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + "\n", + "\"\"\"\n", + "\n", + "spec = mj.MjSpec.from_string(arena_xml)\n", + "\n", + "spec.option.enableflags |= mj.mjtEnableBit.mjENBL_OVERRIDE\n", + "spec.option.enableflags |= mj.mjtEnableBit.mjENBL_MULTICCD\n", + "spec.option.timestep = 0.0001\n", + "spec.compiler.degree = False\n", + "\n", + "main = spec.default\n", + "main.geom.solref = [0.001, 1]\n", + "\n", + "# Add lights\n", + "for x in [-1, 1]:\n", + " for y in [-1, 1]:\n", + " spec.worldbody.add_light(pos=[x, y, 40], dir=[-x, -y, -15])\n", + "\n", + "SQUARE_LENGTH = 2\n", + "for i in range(-2, 2):\n", + " for j in range(-2, 2):\n", + " add_tile(spec=spec, grid_loc=[i * 2 * SQUARE_LENGTH, j * 2 * SQUARE_LENGTH])\n", + "\n", + "model = spec.compile()\n", + "data = mj.MjData(model)\n", + "\n", + "cam = mj.MjvCamera()\n", + "mj.mjv_defaultCamera(cam)\n", + "cam.lookat = [-2, 0, -2]\n", + "cam.distance = 18\n", + "cam.elevation = -30\n", + "\n", + "with mj.Renderer(model, 720, 1280) as renderer:\n", + " mj.mj_forward(model, data)\n", + " renderer.update_scene(data,cam)\n", + " media.show_image(renderer.render())" + ] + }, { "cell_type": "markdown", "metadata": { @@ -864,6 +1697,7 @@ "cell_type": "code", "execution_count": 0, "metadata": { + "cellView": "form", "id": "223KzKAzLdEJ" }, "outputs": [], @@ -1263,7 +2097,7 @@ "id": "RYbaTPNmLdEK" }, "source": [ - "We can scale the size of a model by traversing the kinematic tree and applying the the scale to the relevant geoms. Above we can see humanoids of three different sizes." + "We can scale the size of a model by traversing the kinematic tree and applying the scale to the relevant geoms. Above we can see humanoids of three different sizes." ] }, { @@ -1605,7 +2439,7 @@ "Note that:\n", "\n", "- MJCF attributes correspond directly to arguments of the `add_()` methods.\n", - "- When referencing elements, e.g when specifying the joint to which an actuator is attached, the name string of the MJCF elements is used." + "- When referencing elements, e.g. when specifying the joint to which an actuator is attached, the name string of the MJCF elements is used." ] }, { @@ -1792,7 +2626,7 @@ "accelerator": "GPU", "colab": { "collapsed_sections": [ - "yXY7HGfVsVlo" + "sJFuNetilv4m" ], "gpuClass": "premium", "private_outputs": true,