import direct.directbase.DirectStart
from panda3d.core import *
from direct.showbase.DirectObject import DirectObject
from direct.task import Task
#for Pandai
from panda3d.ai import *
class World(DirectObject):
def __init__(self):
base.cam.setPosHpr(0,0,55,0,-90,0)
self.loadModels()
self.setAI()
def loadModels(self):
# smiley
self.smiley = loader.loadModel('smiley')
self.smiley.reparentTo(render)
self.smiley.setPos(0, 0, 0)
# Obstacle 1
self.obstacle1 = loader.loadModel('frowney')
self.obstacle1.setPos(0,0,0)
self.obstacle1.reparentTo(render)
# Obstacle 2
self.obstacle2 = loader.loadModel('frowney')
self.obstacle2.setPos(5,0,0)
self.obstacle2.reparentTo(render)
def AIUpdate(self,task):
self.AIworld.update()
return Task.cont
def setAI(self):
self.AIworld = AIWorld(render)
self.smileyAIchar = AICharacter("smiley",self.smiley, 100, 0.05, 5)
self.AIworld.addAiChar(self.smileyAIchar)
self.smileyAIbehaviors = self.smileyAIchar.getAiBehaviors()
self.smileyAIbehaviors.obstacleAvoidance(1.0)
taskMgr.add(self.AIUpdate,"AIUpdate")
# comment both addObstacles to induce the AssertionError
# comment only the last addObstacle to induce an AssertionError
self.AIworld.addObstacle(self.obstacle1)
self.AIworld.addObstacle(self.obstacle2)
w = World()
run()
Iâve struggling to get panda3d.ai 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 panda3d.ai 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:
wglGraphicsPipe
(all display modules loaded.)
:ShowBase(warning): run() is deprecated, use base.run() instead
Assertion failed: !is_empty() at line 1041 of panda/src/pgraph/nodePath.cxx
Traceback (most recent call last):
File âE:.âŚ\narrowedDown.pyâ, line 30, in AIUpdate
self.AIworld.update()
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:.âŚ\narrowedDown.pyâ, line 47, in
run()
File âC:\Users.âŚ\AppData\Roaming\Python\Python37\site-packages\direct\showbase\ShowBaseGlobal.pyâ, line 67, in run
base.run()
File âC:.âŚ\AppData\Roaming\Python\Python37\site-packages\direct\showbase\ShowBase.pyâ, line 3325, in run
self.taskMgr.run()
File âC:\Users.âŚ\AppData\Roaming\Python\Python37\site-packages\direct\task\Task.pyâ, line 546, in run
self.step()
File âC:\Users.âŚ\AppData\Roaming\Python\Python37\site-packages\direct\task\Task.pyâ, line 500, in step
self.mgr.poll()
File âE:.âŚ\narrowedDown.pyâ, line 30, in AIUpdate
self.AIworld.update()
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.
https://docs.panda3d.org/1.10/python/programming/pandai/steering-behaviors/obstacle-avoidance
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 panda3d.ai import AIWorld, AICharacter
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.smiley = loader.load_model('smiley')
self.smiley.reparent_to(render)
#self.smiley.set_pos(5, 0, 0)
self.obstacle1 = loader.load_model('frowney')
self.obstacle1.reparent_to(render)
#self.obstacle1.set_pos(0, 0, 0)
self.AIworld = AIWorld(render)
self.smileyAIchar = AICharacter("smiley", self.smiley, 100, 0.05, 5)
self.AIworld.add_ai_char(self.smileyAIchar)
self.smileyAIbehaviors = self.smileyAIchar.get_ai_behaviors()
self.smileyAIbehaviors.obstacle_avoidance(1.0)
self.AIworld.add_obstacle(self.obstacle1)
self.AIworld.update()
app = MyApp()
app.run()
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