create planete

i have updated my code with GeoMipTerrain, but i can not apply the node to ODE physic Engine (in line 97)

from __future__ import print_function

import os
import sys
from panda3d.core import Vec3, load_prc_file_data, ShaderTerrainMesh
from direct.showbase.ShowBase import ShowBase
from panda3d.ode import OdeWorld, OdeSimpleSpace, OdeJointGroup
from panda3d.ode import OdeWorld, OdeBody, OdeMass, OdeBoxGeom, OdePlaneGeom
from panda3d.core import Quat


from panda3d.core import *

import threading
from threading import Thread
import procedural
from random import randint, random


class Application(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        
        #Init sphere
        sphere = procedural.IcoSphere(radius=1, subdivisions=3)
        sphere.reparentTo(self.render)
        
        #Init Terrain
        self.terrain_np = render.attach_new_node("terrain")
        terrain = GeoMipTerrain("myDynamicTerrain")
        terrain.setHeightfield("resources/heightfield.png")
        
        # Set terrain properties
        terrain.setBlockSize(32)
        terrain.setNear(40)
        terrain.setFar(100)
        terrain.setFocalPoint(base.camera)
         
        # Store the root NodePath for convenience
        root = terrain.getRoot()
        root.reparentTo(render)
        root.setSz(100)
        
        # Attach Sphere to terrain node
        sphere.reparentTo(root)
        
        #Init Physic
        world = OdeWorld()
        world.setGravity(0, 0, -9.81)
        world.initSurfaceTable(1)
        world.setSurfaceEntry(0, 0, 150, 0.0, 9.1, 0.9, 0.00001, 0.0, 0.002)
        
        # Create a space and add a contactgroup to it to add the contact joints
        space = OdeSimpleSpace()
        space.setAutoCollideWorld(world)
        contactgroup = OdeJointGroup()
        space.setAutoCollideJointGroup(contactgroup)
        
        # Add a random amount of boxes
        box = loader.loadModel("box")
        # Make sure its center is at 0, 0, 0 like OdeBoxGeom
        box.setPos(-.5, -.5, -.5)
        box.flattenLight() # Apply transform
        box.setTextureOff
        
        boxes = []
        for i in range(0, 15):
          # Setup the geometry
          boxNP = box.copyTo(render)
          boxNP.setPos(randint(-10, 10), randint(-10, 10), 10 + random())
          boxNP.setColor(random(), random(), random(), 1)
          boxNP.setHpr(randint(-45, 45), randint(-45, 45), randint(-45, 45))
          # Create the body and set the mass
          boxBody = OdeBody(world)
          M = OdeMass()
          M.setBox(50, 1, 1, 1)
          boxBody.setMass(M)
          boxBody.setPosition(boxNP.getPos(render))
          boxBody.setQuaternion(boxNP.getQuat(render))
          # Create a BoxGeom
          boxGeom = OdeBoxGeom(space, 1, 1, 1)
          boxGeom.setCollideBits(BitMask32(0x00000002))
          boxGeom.setCategoryBits(BitMask32(0x00000001))
          boxGeom.setBody(boxBody)
          boxes.append((boxNP, boxBody))
          
          
        # Generate it.

        cNode = CollisionNode("sphere")
        ground = render.attachNewNode(cNode)

        cm = CardMaker("ground")
        cm.setFrame(-20, 20, -20, 20)
        
        # Why terrain.generate() not work ?
        ground = render.attachNewNode(cm.generate())
        terrain.generate()

        ground.setPos(0, 0, 0); ground.lookAt(0, 0, -1)
        groundGeom = OdePlaneGeom(space, Vec4(0, 0, 1, 0))
        groundGeom.setCollideBits(BitMask32(0x00000001))
        groundGeom.setCategoryBits(BitMask32(0x00000002))

        # Add a task to keep updating the terrain
        def updateTask(task):
          terrain.update()
          return task.cont
        taskMgr.add(updateTask, "update")
        
        # The task for our simulation
        def simulationTask(task):
          space.autoCollide() # Setup the contact joints
          # Step the simulation and set the new positions
          world.quickStep(globalClock.getDt())
          for np, body in boxes:
            np.setPosQuat(render, body.getPosition(), Quat(body.getQuaternion()))
          contactgroup.empty() # Clear the contact joints
          return task.cont
         
        # Wait a split second, then start the simulation  
        taskMgr.doMethodLater(0.5, simulationTask, "Physics Simulation")
        
Application().run()