AssertionError: !is_empty() at line 1041 of panda/src/pgraph/nodePath.cxx

import direct.directbase.DirectStart
from panda3d.core import *
from direct.showbase.DirectObject import DirectObject
from direct.task import Task
#for Pandai
from import *

class World(DirectObject):

    def __init__(self):,0,55,0,-90,0)

    def loadModels(self):
        # smiley
        self.smiley = loader.loadModel('smiley')
        self.smiley.setPos(0, 0, 0)
        # Obstacle 1
        self.obstacle1 = loader.loadModel('frowney')
        # Obstacle 2
        self.obstacle2 = loader.loadModel('frowney')

    def AIUpdate(self,task):
        return Task.cont
    def setAI(self):
        self.AIworld = AIWorld(render)
        self.smileyAIchar = AICharacter("smiley",self.smiley, 100, 0.05, 5)
        self.smileyAIbehaviors = self.smileyAIchar.getAiBehaviors()        
        # comment both addObstacles to induce the AssertionError
        # comment only the last addObstacle to induce an AssertionError

w = World()

I’ve struggling to get working. The example works fine, but every time I try using it in a game prototype it doesnt work anymore. The above code snippet is the best narrowing down that I could do for AssertionError: !is_empty() at line 1041 of panda/src/pgraph/nodePath.cxx Commenting or uncommenting the addObstacle near the end induces the AssertionError.

Based on what is required to induce the error, my guess is that the system ignores obstacles that have the exact same position as the aiChar and throws the AssertionError when the list of obstacles is empty.

Is my assumption of what’s going on correct?

All in all, if my assumption is correct, that’s easy to fix, could just put an obstacle somewhere outside of the walkable area so the list cant be empty or do a check every frame and do a small nudge so it’s off by 0.1 instead of exactly overlapping.

That assertionError is quite an abstract thing to get, took me some trial and error to figure out what it might mean. It would be nice if it could throw a more explainatory message.

Based on the error, I don’t think that you’re correct.

At a glance, this looks to be a not-uncommon error produced when a NodePath is “empty”–i.e. it holds no node.

Quite what’s causing it I don’t know–could you show the full error, please, so that we can get an idea of where in the code it’s happening?

Just run the snippet and see for yourself. Commenting or uncommenting the obstacles is what induces the AssertionError

full error:

Using deprecated DirectStart interface.
Known pipe types:
(all display modules loaded.)
:ShowBase(warning): run() is deprecated, use instead
Assertion failed: !is_empty() at line 1041 of panda/src/pgraph/nodePath.cxx
Traceback (most recent call last):
File “E:…\”, line 30, in AIUpdate
AssertionError: !is_empty() at line 1041 of panda/src/pgraph/nodePath.cxx
:task(error): Exception occurred in PythonTask AIUpdate
Traceback (most recent call last):
File “E:…\”, line 47, in
File “C:\Users…\AppData\Roaming\Python\Python37\site-packages\direct\showbase\”, line 67, in run
File “C:…\AppData\Roaming\Python\Python37\site-packages\direct\showbase\”, line 3325, in run
File “C:\Users…\AppData\Roaming\Python\Python37\site-packages\direct\task\”, line 546, in run
File “C:\Users…\AppData\Roaming\Python\Python37\site-packages\direct\task\”, line 500, in step
File “E:…\”, line 30, in AIUpdate
AssertionError: !is_empty() at line 1041 of panda/src/pgraph/nodePath.cxx

Hmm, it does indeed seem to be that some NodePath is ending up “empty”–and it looks like it’s a NodePath that’s handled by the AI system.

Since it appears to happen in AIWorld’s “update” method, and since that method updates AI-characters, I’m guessing that the problem lies with one of those.

You set the length of the feeler to 1, but did not let it work to find the obstacle, so you initialize the obstacle and the character in the same place. Accordingly, AIworld began an iteration of searching from an empty list of nodes.

In bullet, if you place all the objects at one point, an explosion will occur, and there is no mistake about it.

Just don’t create two conditions.

I think in the source code only need to add a condition to check if the node is empty.

I just tried the code given in the first post above, and… it works without crash.

So, my next question is this: What version of Panda3D are you using? If it’s not the latest, then perhaps you’re bumping into a bug that has been fixed. If it’s a development version, perhaps a regression has been introduce.

Either way, it might be worth trying your code with the latest stable version of Panda.

You haven’t read the post carefully. Here is a minimal example.

from direct.showbase.ShowBase import ShowBase
from import AIWorld, AICharacter

class MyApp(ShowBase):
    def __init__(self):

        self.smiley = loader.load_model('smiley')
        #self.smiley.set_pos(5, 0, 0)

        self.obstacle1 = loader.load_model('frowney')
        #self.obstacle1.set_pos(0, 0, 0)

        self.AIworld = AIWorld(render)
        self.smileyAIchar = AICharacter("smiley", self.smiley, 100, 0.05, 5)

        self.smileyAIbehaviors = self.smileyAIchar.get_ai_behaviors()


app = MyApp()

Ah, you’re right–I missed the bit about the commenting. (In my defence, I was pretty tired. ^^; )

And trying that new version, it does seem that it has something to do with having the obstacle in the same place as the AI-character, as you previously suggested–which seems like a bug in the AI system, to me.

I should have pasted down the error having version and not the ‘comment this to create the error’. My bad.

1 Like