Help with Error message

My script was working perfectly until I put a collision mesh.
When I press escape, the game is supposed to return to the menu.
Instead I keep getting this error:

[i]Assertion failed: !is_empty() at line 944 of panda/src/pgraph/nodePath.cxx
Traceback (most recent call last):
File “help1.py”, line 428, in ?
run()
File “C:\Panda3D-1.4.2\direct\src\showbase\ShowBase.py”, line 2176, in run
self.taskMgr.run()
File “C:\Panda3D-1.4.2\direct\src\task\Task.py”, line 930, in run
self.step()
File “C:\Panda3D-1.4.2\direct\src\task\Task.py”, line 862, in step
self.__stepThroughList(taskPriList)
File “C:\Panda3D-1.4.2\direct\src\task\Task.py”, line 764, in __stepThroughList
ret = self.__executeTask(task)
File “C:\Panda3D-1.4.2\direct\src\task\Task.py”, line 684, in __executeTask
ret = task(*task.extraArgs)
File “help1.py”, line 276, in move
startpos = self.Mod1.getPos()
AssertionError: !is_empty() at line 944 of panda/src/pgraph/nodePath.cxx

**** End of process output ****[/i]

Could you please look at the code, and tell me what might be wrong?
You just have to replace the terrain model, and change it’s name.
Appreciate any help I can get. Thanks

import direct.directbase.DirectStart
from direct.showbase.ShowBaseGlobal import *
from direct.gui.DirectGui import *
from direct.showbase import *
from direct.task import Task
from pandac.PandaModules import *
from direct.actor import Actor 
from direct.interval.SoundInterval import SoundInterval
from direct.interval.MetaInterval import Sequence,Parallel
from direct.interval.LerpInterval import LerpFunc
from direct.interval.IntervalGlobal import *
from direct.showbase.InputStateGlobal import inputState 
import random, sys, os, math
from math import pi, sin


#Define font to use
font = loader.loadFont('cmr12.egg') #Using an .egg has advantages

#**************************************#
""" Creates a Title Screen Menu      """
#**************************************#

class StartMenu(DirectObject.DirectObject):
    def __init__(self):
 
        # View Framerate
        base.setFrameRateMeter(1) 
	# Make Background Black for Splash Screen
	base.setBackgroundColor(0, 0, 0)
        # Variables
        self.page = 0
        self.sceneOne = 0
        self.windowOver = 0
        self.fontQuit = loader.loadFont('cmr12.egg') #Using an .egg
        # Control the speed of the camera's rotation and zoom
        self.camera1Speed = .10 
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
        self.zoomIn = 0
        self.zoomOut = 0

	#**************************************#
	""" Loads up Title Screen Menu       """
	#**************************************#

	self.menuLabel = DirectLabel(text = "MAIN MENU", scale = (0.4, 0.4, 0.4), text_fg=(1, 1, 1, 1), relief = None)
	self.menuLabel.setTransparency(1)	
	self.menuLabel.setPos(0, 0, 0.6)

	self.playButton = DirectButton(text = "PLAY", scale = (0.4, 0.4, 0.1), text_fg=(1, 1, 1, 1), relief = None, clickSound = None, command = self.activate)
	self.playButton.setTransparency(1)
	self.playButton.setPos(0, 0, -0.15)

	self.exitButton = DirectButton(text = "EXIT", scale = (0.4, 0.4, 0.1), text_fg=(1, 1, 1, 1), relief = None, clickSound = None, command = sys.exit)
	self.exitButton.setTransparency(1)
	self.exitButton.setPos(0, 0, -0.4)

    #**************************************#
    """ Main Menu Functions                
        Running The Game  - Scene 1      """
    #**************************************#

    # This Function Starts the Game
    def activate(self):
        self.page = 1
        self.sceneOne = 1
        self.windowOver = 1
        self.hideMainMenu()
        
        # Create a floater object.  We use the "floater" as a temporary
        # variable in a variety of calculations.
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        """KEYS"""
        self.accept('escape', self.returnOptions)
        self.accept("wheel_up", self.cameraZoom,[-1]) 
        self.accept("wheel_down", self.cameraZoom,[1]) 
        self.accept("t",self.jumpMod2)
        self.accept("f",self.turnMod2,[-1])
        self.accept("g",self.turnMod2,[1])
        # key down
        self.accept("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        # Key up
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])
        # zoom
        self.accept("v", self.zoomCameraIn, [-1])
        self.accept("b", self.zoomCameraOut, [1])
        self.accept("v-up", self.zoomStop, [0])
        self.accept("b-up", self.zoomStop, [0])
        
        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.prevtime = 0
        self.isMoving = False

        self.environ1 = loader.loadModel("models/terrain001") 
        self.environ1.reparentTo(render)
        self.environ1.setScale(0.15,0.15,0.15) 
        self.environ1.setPos(0,0,147.7) 
        self.environ1.setHpr(0,0,0)
        #self.environ1.setColor(0.3, 0.4, 1)

        self.Mod1StartPos = self.environ1.find("**/start_point").getPos()
        self.Mod1 = Actor.Actor("models/ralph",{"run":"models/ralph-run","walk":"models/ralph-walk"})
        self.Mod1.reparentTo(render) 
        self.Mod1.setScale(0.2,0.2,0.2) 
        #self.Mod1.setPos(0,-10,150) 
        self.Mod1.setHpr(90,0,0) 
        self.Mod1.setPos(self.Mod1StartPos) 

        # Camera 3
        self.my_cam1 = Camera("cam1") 
        self.my_camera1 = render.attachNewNode(self.my_cam1) 
        self.my_camera1.setName("camera1")
        self.my_camera1.setPos(self.Mod1.getX()-10, self.Mod1.getY()-10, 155) 
        #self.my_camera1.setPos(0,-20,155)
        #self.my_camera1.setHpr(0,0,0)
        self.my_camera1.lookAt(self.Mod1)
        self.my_camera1.node().getLens().setAspectRatio(4.0/2.0)
        
        # Disable the default DisplayRegion, which covers the whole screen. 
        self.dr = base.camNode.getDisplayRegion(0) 
        self.dr.setActive(1) # Don't disable
            
        self.window = self.dr.getWindow() 
        self.dr1 = self.window.makeDisplayRegion(0.026, 0.975, 0.35, 0.94) 
        self.dr1.setSort(self.dr.getSort())
        
        self.dr1.setCamera(self.my_camera1) 


        ## # Set up the camera
        
        ## base.disableMouse()
        ## self.my_camera1.setPos(self.Mod1.getX(), self.Mod1.getY()+10, 1.5)
        

        """COLLISIONS"""
        """************************************************************"""
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  One ray will
        # start above mod's head, and the other will start above the camera.
        # A ray may hit the terrain, or it may hit a rock or a tree.  If it
        # hits the terrain, we can detect the height.  If it hits anything
        # else, we rule that the move is illegal.

        self.cTrav = CollisionTraverser()

        self.Mod1GroundRay = CollisionRay()
        self.Mod1GroundRay.setOrigin(0,0,1000)
        self.Mod1GroundRay.setDirection(0,0,-1)
        self.Mod1GroundCol = CollisionNode('modRay')
        self.Mod1GroundCol.addSolid(self.Mod1GroundRay)
        self.Mod1GroundCol.setFromCollideMask(BitMask32.bit(0))
        self.Mod1GroundCol.setIntoCollideMask(BitMask32.allOff())
        self.Mod1GroundColNp = self.Mod1.attachNewNode(self.Mod1GroundCol)
        self.Mod1GroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.Mod1GroundColNp, self.Mod1GroundHandler)

        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,1000)
        self.camGroundRay.setDirection(0,0,-1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = self.my_camera1.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        # Uncomment this line to see the collision rays
        #self.modGroundColNp.show()
        #self.camGroundColNp.show()
       
        #Uncomment this line to show a visual representation of the 
        #collisions occuring
        #self.cTrav.showCollisions(render)
        """**********************************************************"""

        """CAMERA"""    
        #Task to move the camera 
        def SpinCameraTask(task): 
            #rotate camera 6 degrees every second
            angledegrees = task.time * 0.0 
            #compute desired orientation of camera (degrees, radians)
            angleradians = angledegrees * (math.pi / 180.0) 
            #setPos = set position of the camera
            base.camera.setPos(20*math.sin(angleradians),-20.0*math.cos(angleradians),3) 
            #setHpr = set orientation
            base.camera.setHpr(angledegrees, 0, 0) 
            return Task.cont 
        
        taskMgr.add(SpinCameraTask, "SpinCameraTask") 
        #taskMgr.add = call the subroutine SpinCameraTask every frame
    
    """Key Movements"""
    # Camera zoom in function. 
    def zoomCameraIn(self, dir):
        self.zoomOut = 0 
        self.zoomIn = 1
    
    # Camera zoom out function. 
    def zoomCameraOut(self, dir): 
        self.zoomIn = 0
        self.zoomOut = 1
    
    # Stop zooming camera. 
    def zoomStop(self, dir): 
        self.zoomIn = 2
        self.zoomOut = 2
    
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.zoomIn = 0
        self.zoomOut = 0
        self.keyMap[key] = value

    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.zoomIn = 0
        self.zoomOut = 0
        self.keyMap[key] = value
    
    # Turn model2. 
    def turnMod2(self,dir): 
        modelTurn = self.Mod1.hprInterval(.2,Vec3(self.Mod1.getH()-(10*dir),0,0))
        ## posInterval and hprInterval contain (speed, x, y, z)
        modelTurn.start()
    
    def jumpMod2(self):
        ## Using math
        dist = 5.0      # jump forward 5 feet in facing direction
        angle = self.Mod1.getH()*math.pi/180.0
        dx = dist*math.sin(angle)
        dy = dist*-math.cos(angle)
        
        modelWalk = Parallel(
            self.Mod1.posInterval(0.8,Vec3(self.Mod1.getX()+dx,self.Mod1.getY()+dy,0)),
            self.Mod1.actorInterval("jump",loop=1,duration=0.8)
            )
        modelWalk.start()

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):

        elapsed = task.time - self.prevtime

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        camright = self.my_camera1.getNetTransform().getMat().getRow3(0)
        camright.normalize()
        if (self.keyMap["cam-left"]!=0):
            self.my_camera1.setPos(self.my_camera1.getPos() - camright*(elapsed*10))
        if (self.keyMap["cam-right"]!=0):
            self.my_camera1.setPos(self.my_camera1.getPos() + camright*(elapsed*10))
        if self.zoomIn > 0:
            self.my_camera1.setPos(Point3(self.my_camera1.getX(), self.my_camera1.getY()-5*(elapsed*.5), self.my_camera1.getZ()))
        if self.zoomOut > 0:
            self.my_camera1.setPos(Point3(self.my_camera1.getX(), self.my_camera1.getY()+5*(elapsed*.5), self.my_camera1.getZ()))

        # save mod's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        startpos = self.Mod1.getPos()
        self.my_camera1.lookAt(self.Mod1)

        # If a move-key is pressed, move mod in the specified direction.

        if (self.keyMap["left"]!=0):
            self.Mod1.setH(self.Mod1.getH() + elapsed*300)
        if (self.keyMap["right"]!=0):
            self.Mod1.setH(self.Mod1.getH() - elapsed*300)
        if (self.keyMap["forward"]!=0):
            backward = self.Mod1.getNetTransform().getMat().getRow3(1)
            backward.setZ(0)
            backward.normalize()
            self.Mod1.setPos(self.Mod1.getPos() - backward*(elapsed*5))

        # If a move-key is pressed, move camera in the specified direction.

        ## if (self.keyMap["cam-in"]!=0):
            ## self.my_camera1.setPos(self.my_camera1.getPos() + elapsed*300)
        ## if (self.keyMap["cam-out"]!=0):
            ## self.my_camera1.setPos(self.my_camera1.getPos() - elapsed*300)

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
            if self.isMoving is False:
                self.Mod1.loop("run")
                self.isMoving = True
        else:
            if self.isMoving:
                self.Mod1.stop()
                self.Mod1.pose("walk",5)
                self.isMoving = False

        # If the camera is too far from mod, move it closer.
        # If the camera is too close to mod, move it farther.

        self.camvec = self.Mod1.getPos() - self.my_camera1.getPos()
        self.camvec.setZ(0)
        self.camdist = self.camvec.length()
        self.camvec.normalize()
        if (self.camdist > 10.0) and self.zoomIn < 1 and self.zoomOut < 1:
            self.my_camera1.setPos(self.my_camera1.getPos() + self.camvec*(self.camdist-10))
            self.camdist = 10.0
        if (self.camdist < 5.0) and self.zoomIn < 1 and self.zoomOut < 1:
            self.my_camera1.setPos(self.my_camera1.getPos() - self.camvec*(5-self.camdist))
            self.camdist = 5.0

        # Now check for collisions.

        self.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z. If it hit anything else, or didn't hit anything, put
        # him back where he was last frame.

        entries = []
        for i in range(self.Mod1GroundHandler.getNumEntries()):
            entry = self.Mod1GroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        """I had to change <Dart> { 1 } to <Dart> { 0 } in my egg file to move ralph.
        This apparently is the models z coordinates. The 0 places him on the ground.
        medTerrain01 is the name of the mesh (group) found in the egg file."""
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "medTerrain01"):
            self.Mod1.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.Mod1.setPos(startpos)

        # Keep the camera at one foot above the terrain,
        # or two feet above mod, whichever is greater.
        
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "medTerrain01"):
            self.my_camera1.setZ(entries[0].getSurfacePoint(render).getZ()+1.5)
        if (self.my_camera1.getZ() < self.Mod1.getZ() + 1.5):
            self.my_camera1.setZ(self.Mod1.getZ() + 1.5)
            
        # The camera should look in mod's direction,
        # but it should also try to stay horizontal, so look at
        # a floater which hovers above mod's head.
        
        self.floater.setPos(self.Mod1.getPos())
        self.floater.setZ(self.Mod1.getZ() + 1.5)
        self.my_camera1.lookAt(self.floater)

        # Store the task time and continue.
        self.prevtime = task.time
        return Task.cont
    
    # Define the cameraZoom function. 
    def cameraZoom(self,dir): 
        self.camZoom = LerpPosInterval(self.my_camera1, self.camera1Speed, Point3(self.my_camera1.getX(), self.my_camera1.getY()-(2*dir), self.my_camera1.getZ()+(.8*dir))) 
        self.camZoom.start() 

    #**************************************#
    """ Setup Menu Functions             """
    #**************************************#

    # This Function Loads the Setup Screen
    def loadSetup(self):
        self.windowOver = 0
        if self.windowOver < 1:
            self.hideMainMenu()

    # This Function Ends the Setup Screen
    def returnOptions(self):
        self.page = 0
        self.showMainMenu()
        # Cleanup scene 1
        if self.sceneOne > 0:
            self.dr1.setActive(0)
            self.sceneOne = 0
            self.Mod1.removeNode()
            #self.Mod1.delete()

    #**************************************#
    """ Functions to Swap Out the Menus  """
    #**************************************#

    # Hides the Main Menu
    def hideMainMenu(self):
        self.menuLabel.hide()
        self.playButton.hide()
        self.exitButton.hide()

    # Shows the Main Menu
    def showMainMenu(self):
        self.menuLabel.show()
        self.playButton.show()
        self.exitButton.show()

    #**************************************#
    """ Functions to Swap Out the Scenes """
    #**************************************#

    # Cleanup scene 1
    def hideScene1(self):
        if self.page < 1:
            self.Mod1.removeNode()
            self.Mod1.delete()
            self.dr1.setActive(0)


menu = StartMenu() # Start Menu class
run()

It means Mod1 is an empty NodePath. Are you sure it contains something? That models/ralph exists?
Are you also sure you called activate() before move() ?

EDIT: It seems like you are removing the node somewhere… maybe that is the issue?

    def returnOptions(self):
        self.page = 0
        self.showMainMenu()
        # Cleanup scene 1
        if self.sceneOne > 0:
            self.dr1.setActive(0)
            self.sceneOne = 0
            self.Mod1.removeNode()
            #self.Mod1.delete() 

When you press ESCAPE the above method gets called. This removes the Mod1 NodePath from the scene. Like pro-rsoft siad. This means self.Mod1 is from now on an empty node.

BUT: The task “move” still runs. It is called every frame an tries to move an empty node now. Not good.

So stop the task too before returning to the options menu.

enn0x

Sorry I didn’t reply earlier. I was not able to connect this weekend.
Thanks very much for your assistance. It sound logical, and I will check it out right away.
Thanks much. :smiley:

EDIT:
Just wanted to let you know I got it working.
I had to do like you said - find a way to stop the task before returning to the Menu. It’s working great now. :smiley: :smiley: :smiley:
Thanks guys.