Dynamic Obstacles

DYNAMIC OBSTACLES:

https://www.youtube.com/watch?v=8BZ_3gua5Bs


In PandAI, use it via:

addDynamicObstacle(NodePath obstacle);

The code for this tutorial:

  1# This tutorial provides an example of creating a character and having it walk
  2# around using PandAI and dynamic obstacle pathfinding
  3
  4from direct.showbase.ShowBase import ShowBase
  5from panda3d.core import *
  6from direct.showbase.DirectObject import DirectObject
  7from direct.interval.IntervalGlobal import *
  8from direct.task import Task
  9from direct.actor.Actor import Actor
 10import random
 11import sys
 12import os
 13from direct.gui.DirectGui import *
 14from direct.gui.OnscreenText import OnscreenText
 15
 16from panda3d.ai import *
 17
 18base = ShowBase()
 19
 20speed = 0.2
 21turnspeed = 3.5
 22
 23# Figure out what directory this program is in.
 24MYDIR = os.path.abspath(sys.path[0])
 25MYDIR = Filename.fromOsSpecific(MYDIR).getFullpath()
 26
 27font = loader.loadFont("cmss12")
 28
 29
 30# Function to put instructions on the screen.
 31def addInstructions(pos, msg):
 32    return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), font=font,
 33                        pos=(-1.3, pos), align=TextNode.ALeft, scale=.05)
 34
 35
 36# Function to put title on the screen.
 37def addTitle(text):
 38    return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), font=font,
 39                        pos=(1.3, -0.95), align=TextNode.ARight, scale=.07)
 40
 41
 42class World(DirectObject):
 43
 44    def __init__(self):
 45
 46        self.keyMap = {"left": 0, "right": 0, "forward": 0}
 47
 48        #base.disableMouse()
 49        base.cam.setPosHpr(0, -210, 135, 0, 327, 0)
 50        self.done = []
 51        for i in range(4):
 52            self.done.append(False)
 53        self.toggle = False
 54        self.firstTime = False
 55
 56        addTitle("Pandai Tutorial: Dynamic Avoidance of Moving Obstacles")
 57        addInstructions(0.95, "[ESC]: Quit")
 58        addInstructions(0.90, "[Arrow Keys]: Move the blue Ralph")
 59        addInstructions(0.85, "Try and move the blue Ralph in the path of the "
 60                              "other Ralphs")
 61
 62        self.loadModels()
 63        self.setAI()
 64
 65    def loadModels(self):
 66
 67        self.environ1 = loader.loadModel("models/skydome")
 68        self.environ1.reparentTo(render)
 69        self.environ1.setPos(0, 0, 0)
 70        self.environ1.setScale(1)
 71
 72        self.environ2 = loader.loadModel("models/skydome")
 73        self.environ2.reparentTo(render)
 74        self.environ2.setP(180)
 75        self.environ2.setH(270)
 76        self.environ2.setScale(1)
 77
 78        self.environ = loader.loadModel("models/plane_demo1")
 79        self.environ.reparentTo(render)
 80        self.environ.setPos(0, 0, 0)
 81
 82        self.Target = Actor("models/ralph",
 83                            {"run": "models/ralph-run",
 84                             "walk": "models/ralph-walk"})
 85        self.Target.setColor(0, 0, 1)
 86        self.Target.setPos(60, -60, 0)
 87        self.Target.setScale(2)
 88        self.Target.reparentTo(render)
 89        self.Target.loop("run")
 90        self.Targetforward = NodePath("Targetforward")
 91        self.Targetforward.setPos(0, -1, 0)
 92        self.Targetforward.reparentTo(self.Target)
 93
 94        # Create the main character, Ralph
 95        self.ralph = []
 96        self.positions = []
 97        self.positions_new = []
 98        for i in range(4):
 99            self.ralph.append(Actor("models/ralph",
100                                    {"run": "models/ralph-run",
101                                     "walk": "models/ralph-walk"}))
102            self.ralph[i].reparentTo(render)
103            self.ralph[i].setScale(2)
104
105            self.positions.append(NodePath(str(i)))
106            self.positions_new.append(NodePath(str(i)))
107            if i < 2:
108                self.ralph[i].setPos(Point3(-61, -34 + (i * 40), 0))
109            else:
110                self.ralph[i].setPos(Point3(61, -34 + ((i - 2) * 40), 0))
111
112            self.positions.append(NodePath(str(i)))
113            self.positions_new.append(NodePath(str(i)))
114
115        self.positions[0].setPos(Point3(-61, -34 + ((0) * 40), 0))
116        self.positions[1].setPos(Point3(-53, -34 + ((1) * 40), 0))
117        self.positions[2].setPos(Point3(53, -44 + ((0) * 40), 0))
118        self.positions[3].setPos(Point3(61, -24 + ((1) * 40), 0))
119
120        self.positions_new[0].setPos(Point3(61, -44 + ((0) * 40), 0))
121        self.positions_new[1].setPos(Point3(53, -44 + ((1) * 40), 0))
122        self.positions_new[2].setPos(Point3(-53, -24 + ((0) * 40), 0))
123        self.positions_new[3].setPos(Point3(-61, -24 + ((1) * 40), 0))
124
125    def setAI(self):
126        # Creating AI World
127        self.AIworld = AIWorld(render)
128
129        #self.accept("enter", self.setMove)
130        # Movement
131        self.accept("arrow_left", self.setKey, ["left", 1])
132        self.accept("arrow_right", self.setKey, ["right", 1])
133        self.accept("arrow_up", self.setKey, ["forward", 1])
134        self.accept("arrow_left-up", self.setKey, ["left", 0])
135        self.accept("arrow_right-up", self.setKey, ["right", 0])
136        self.accept("arrow_up-up", self.setKey, ["forward", 0])
137
138        self.AIchar = []
139        self.AIbehaviors = []
140        for i in range(4):
141            maxForce = 25 - (5 * random.random())
142            char = AICharacter("ralph", self.ralph[i], 60, 0.05, maxForce)
143            self.AIchar.append(char)
144            self.AIworld.addAiChar(char)
145            self.AIbehaviors.append(char.getAiBehaviors())
146            self.AIbehaviors[i].initPathFind("models/navmesh.csv")
147
148        # AI World update
149        taskMgr.add(self.AIUpdate, "AIUpdate")
150
151        taskMgr.add(self.Mover, "mover")
152
153        self.setMove(1)
154
155    def setMove(self, type):
156        if type == 1:
157            for i in range(4):
158                if i == 0:
159                    self.AIbehaviors[i].pathFindTo(self.positions_new[0], "addPath")
160                    self.AIbehaviors[i].addDynamicObstacle(self.ralph[2])
161                if i == 1:
162                    self.AIbehaviors[i].pathFindTo(self.positions_new[1], "addPath")
163                    self.AIbehaviors[i].addDynamicObstacle(self.ralph[3])
164                if i == 2:
165                    self.AIbehaviors[i].pathFindTo(self.positions_new[2], "addPath")
166                if i == 3:
167                    self.AIbehaviors[i].pathFindTo(self.positions_new[3], "addPath")
168                if self.firstTime is False:
169                    self.AIbehaviors[i].addDynamicObstacle(self.Target)
170                self.ralph[i].loop("run")
171
172            self.firstTime = True
173
174        if type == 2:
175            for i in range(4):
176                if i == 0:
177                    self.AIbehaviors[i].pathFindTo(self.positions[0], "addPath")
178                if i == 1:
179                    self.AIbehaviors[i].pathFindTo(self.positions[1], "addPath")
180                if i == 2:
181                    self.AIbehaviors[i].pathFindTo(self.positions[2], "addPath")
182                if i == 3:
183                    self.AIbehaviors[i].pathFindTo(self.positions[3], "addPath")
184
185                self.ralph[i].loop("run")
186
187    # To update the AIWorld
188    def AIUpdate(self, task):
189        self.AIworld.update()
190        for i in range(4):
191            status = self.AIbehaviors[i].behaviorStatus("pursue")
192            if status == "done" or status == "paused":
193                self.done[i] = True
194
195        j = 0
196        for i in range(4):
197            if self.done[i] is True:
198                j += 1
199
200        if j == 4:
201            self.toggle = not self.toggle
202            if self.toggle is True:
203                self.setMove(2)
204            else:
205                self.setMove(1)
206            for i in range(4):
207                self.done[i] = False
208
209        return Task.cont
210
211    def setKey(self, key, value):
212        self.keyMap[key] = value
213
214    def Mover(self, task):
215        startPos = self.Target.getPos()
216
217        if self.keyMap["left"] != 0:
218            self.Target.setH(self.Target.getH() + turnspeed)
219        if self.keyMap["right"] != 0:
220            self.Target.setH(self.Target.getH() - turnspeed)
221        if self.keyMap["forward"] != 0:
222            forwardvector = self.Targetforward.getPos(render) - startPos
223            self.Target.setPos(startPos + forwardvector * speed)
224
225        return Task.cont
226
227
228w = World()
229base.run()

The full working demo can be downloaded at:

https://sites.google.com/site/etcpandai/documentation/pathfinding/DynamicObstacleDemo.zip?attredirects=0&d=1