Ejemplo n.º 1
0
    def __init__(self, row_id, values, parser):
        """Create a new row.

        :param row_id: an identifier for the row
        :param values: the values from the specification
        :param list inheriting_from: a list of specifications to inherit values
          from, see :class:`knittingpattern.Prototype.Prototype`

        .. note:: Seldomly, you need to create this row on your own. You can
          load it with the :mod:`knittingpattern` or the
          :class:`knittingpattern.Parser.Parser`.
        """
        super().__init__(values)
        self._id = row_id
        self._instructions = ObservableList()
        self._instructions.register_observer(self._instructions_changed)
        self._parser = parser
Ejemplo n.º 2
0
    def __init__(self, row_id, values, parser):
        """Create a new row.

        :param row_id: an identifier for the row
        :param values: the values from the specification
        :param list inheriting_from: a list of specifications to inherit values
          from, see :class:`knittingpattern.Prototype.Prototype`

        .. note:: Seldomly, you need to create this row on your own. You can
          load it with the :mod:`knittingpattern` or the
          :class:`knittingpattern.Parser.Parser`.
        """
        super().__init__(values)
        self._id = row_id
        self._instructions = ObservableList()
        self._instructions.register_observer(self._instructions_changed)
        self._parser = parser
    def __init__(self, appTitle="Simbicon Application", 
                 fps = 30.0,
                 dt = 1/2000.0,
                 glCanvasSize=wx.DefaultSize,
                 size=wx.DefaultSize, redirect=False, filename=None,
                 useBestVisual=False, clearSigInt=True, showConsole=True):
        """
        appTitle is the window title
        fps is the desired number of frames per seconds
        dt is the desired simulation timestep
        :see: wx.BasicApp.__init__`
        """
        
        wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)

        # No annoying error logging window
        wx.Log.SetActiveTarget(wx.LogStderr())

        import UI

        # Setup the main window style
        style = wx.DEFAULT_FRAME_STYLE
        if size == wx.DefaultSize :
            size = wx.GetDisplaySize()
            size.height *= 0.75        
            size.width *= 0.75
            if glCanvasSize == wx.DefaultSize :
                style |= wx.MAXIMIZE
       
        # Setup the environment for the python interactive console
        consoleEnvironment = {
            "wx" : wx,
            "Physics" : Physics,
            "Utils" : Utils }
        exec "from MathLib import *\n" + \
             "app = wx.GetApp()\n" + \
             "from PyUtils import load" in consoleEnvironment, consoleEnvironment
       
        # Create the main window
        self._frame = UI.MainWindow(None, -1, appTitle, size = size, style = style, 
                                    fps = fps, glCanvasSize = glCanvasSize,
                                    showConsole = showConsole,
                                    consoleEnvironment = consoleEnvironment)
        
        # Define GL callbacks
        self._glCanvas = self._frame.getGLCanvas()
        self._glCanvas.addDrawCallback( self.draw )
        self._glCanvas.addPostDrawCallback( self.postDraw )
        self._glCanvas.addOncePerFrameCallback( self.advanceAnimation )
        self._glCanvas.setDrawAxes(False)
        self._glCanvas.setPrintLoad(True)
        self._glCanvas.setCameraTargetFunction( self.cameraTargetFunction )
        
        # Get the tool panel
        self._toolPanel = self._frame.getToolPanel()
        
        # Show the application
        self._frame.Show()
        
        # Set-up starting state
        self._dt = dt      
        self._drawShadows = True
        self._simulationSecondsPerSecond = 1   # 1 = real time, 2 = twice real time, 1/2 = half real time
        self._animationRunning = False
        self._cameraFollowCharacter = False
        self._drawCollisionVolumes = False
        self._followedCharacter = None # Pointer to focused character
        self._captureScreenShots = False
        self._printStepReport = True
        self._screenShotNumber = 0
        self._worldOracle = Core.WorldOracle()
        self._worldOracle.initializeWorld( Physics.world() )
        self._kinematicMotion = False
        
        # Set-up starting list of characters and controllers
        self._characters = []
    
        # Define the observables
        self._controllerList = ObservableList() 
        self._characterObservable = PyUtils.Observable()
        self._animationObservable = PyUtils.Observable()
        self._cameraObservable = PyUtils.Observable()
        self._optionsObservable = PyUtils.Observable()
        self._curveList = ObservableList()
        self._snapshotTree = SnapshotBranch()
class SNMApp(wx.App):
    """A simple class that should handle almost everything a simbicon application typically needs."""

    def __init__(self, appTitle="Simbicon Application", 
                 fps = 30.0,
                 dt = 1/2000.0,
                 glCanvasSize=wx.DefaultSize,
                 size=wx.DefaultSize, redirect=False, filename=None,
                 useBestVisual=False, clearSigInt=True, showConsole=True):
        """
        appTitle is the window title
        fps is the desired number of frames per seconds
        dt is the desired simulation timestep
        :see: wx.BasicApp.__init__`
        """
        
        wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)

        # No annoying error logging window
        wx.Log.SetActiveTarget(wx.LogStderr())

        import UI

        # Setup the main window style
        style = wx.DEFAULT_FRAME_STYLE
        if size == wx.DefaultSize :
            size = wx.GetDisplaySize()
            size.height *= 0.75        
            size.width *= 0.75
            if glCanvasSize == wx.DefaultSize :
                style |= wx.MAXIMIZE
       
        # Setup the environment for the python interactive console
        consoleEnvironment = {
            "wx" : wx,
            "Physics" : Physics,
            "Utils" : Utils }
        exec "from MathLib import *\n" + \
             "app = wx.GetApp()\n" + \
             "from PyUtils import load" in consoleEnvironment, consoleEnvironment
       
        # Create the main window
        self._frame = UI.MainWindow(None, -1, appTitle, size = size, style = style, 
                                    fps = fps, glCanvasSize = glCanvasSize,
                                    showConsole = showConsole,
                                    consoleEnvironment = consoleEnvironment)
        
        # Define GL callbacks
        self._glCanvas = self._frame.getGLCanvas()
        self._glCanvas.addDrawCallback( self.draw )
        self._glCanvas.addPostDrawCallback( self.postDraw )
        self._glCanvas.addOncePerFrameCallback( self.advanceAnimation )
        self._glCanvas.setDrawAxes(False)
        self._glCanvas.setPrintLoad(True)
        self._glCanvas.setCameraTargetFunction( self.cameraTargetFunction )
        
        # Get the tool panel
        self._toolPanel = self._frame.getToolPanel()
        
        # Show the application
        self._frame.Show()
        
        # Set-up starting state
        self._dt = dt      
        self._drawShadows = True
        self._simulationSecondsPerSecond = 1   # 1 = real time, 2 = twice real time, 1/2 = half real time
        self._animationRunning = False
        self._cameraFollowCharacter = False
        self._drawCollisionVolumes = False
        self._followedCharacter = None # Pointer to focused character
        self._captureScreenShots = False
        self._printStepReport = True
        self._screenShotNumber = 0
        self._worldOracle = Core.WorldOracle()
        self._worldOracle.initializeWorld( Physics.world() )
        self._kinematicMotion = False
        
        # Set-up starting list of characters and controllers
        self._characters = []
    
        # Define the observables
        self._controllerList = ObservableList() 
        self._characterObservable = PyUtils.Observable()
        self._animationObservable = PyUtils.Observable()
        self._cameraObservable = PyUtils.Observable()
        self._optionsObservable = PyUtils.Observable()
        self._curveList = ObservableList()
        self._snapshotTree = SnapshotBranch()
            
    #
    # Private methods
        
    def draw(self):
        """Draw the content of the world"""
        world = Physics.world()
                    
        glEnable(GL_LIGHTING)
        if self._drawCollisionVolumes:
            world.drawRBs(Physics.SHOW_MESH|Physics.SHOW_CD_PRIMITIVES)
        else:
            world.drawRBs(Physics.SHOW_MESH|Physics.SHOW_COLOURS)            
#        world.drawRBs(Physics.SHOW_MESH|Physics.SHOW_CD_PRIMITIVES)
        glDisable(GL_LIGHTING);
    
        if self._drawShadows:
            self._glCanvas.beginShadows()
            world.drawRBs(Physics.SHOW_MESH)
            self._glCanvas.endShadows()    

    def postDraw(self):
        """Perform some operation once the entire OpenGL window has been drawn"""
        if self._captureScreenShots:
            self._glCanvas.saveScreenshot("../screenShots/%04d.bmp" % self._screenShotNumber )
            self._screenShotNumber += 1

    def advanceAnimation(self):
        """Called once per frame"""
        if self._animationRunning :
            self.simulationFrame()

    def simulationFrame(self):
        """Performs enough simulation steps to fill one frame"""
        
        # Enough time elapsed perform simulation loop and render
        simulationSeconds = 1.0/self._glCanvas.getFps() * self._simulationSecondsPerSecond
        nbSteps = int( math.ceil( simulationSeconds / self._dt ) )
 
        for i in range(0,nbSteps):
            self.simulationStep()

    def advanceAnimationUntilControllerEnds(self, controller):
        """Advances the animation until the specified controller reaches the end.
        Specify either a name, an index, or an instance of a controller object."""
        controller = self.getController(controller)
        initialPhi = controller.getPhase()
        currPhi = initialPhi + 1
        while currPhi > initialPhi :
            self.simulationStep()
            currPhi = controller.getPhase()
        
    def simulationStep(self):
        """Performs a single simulation step"""

        # TODO Quite hacky
        if self._kinematicMotion:
            import KeyframeEditor 
            from MathLib import Trajectory3dv
            try:
                pc = self._posableCharacter
                traj = self._stanceFootToSwingFootTrajectory
            except AttributeError:
                pc = self._posableCharacter = KeyframeEditor.PosableCharacter.PosableCharacter(self.getCharacter(0),self.getController(0))        
                traj = self._stanceFootToSwingFootTrajectory = Trajectory3dv()
                traj.addKnot(0,Vector3d(-0.13,0,-0.4))
                traj.addKnot(0.5,Vector3d(-0.13,0.125,0))
                traj.addKnot(1,Vector3d(-0.13,0,0.4))
                self._phase = 0                        
                self._stance = Core.LEFT_STANCE
                
            stanceToSwing = traj.evaluate_catmull_rom(self._phase)
            if self._stance == Core.RIGHT_STANCE:
                stanceToSwing.x = stanceToSwing.x * -1
            pc.updatePose( self._phase, stanceToSwing, self._stance, True )
            
            self._phase += 0.00069
            if self._phase >= 1.0:
                self._phase = 0
                if self._stance == Core.LEFT_STANCE:
                    self._stance = Core.RIGHT_STANCE
                else:
                    self._stance = Core.LEFT_STANCE
            return


        
        world = Physics.world()
        controllers = self._controllerList._objects
        contactForces = world.getContactForces()
        for controller in controllers :
            controller.performPreTasks(self._dt, contactForces)
        world.advanceInTime(self._dt)
        
        contactForces = world.getContactForces()
        for controller in controllers :
            if controller.performPostTasks(self._dt, contactForces) :
                step = Vector3d (controller.getStanceFootPos(), controller.getSwingFootPos())
                step = controller.getCharacterFrame().inverseRotate(step);
                v = controller.getV()
                phi = controller.getPhase()
                if self._printStepReport:
                    print "step: %3.5f %3.5f %3.5f. Vel: %3.5f %3.5f %3.5f  phi = %f" % ( step.x, step.y, step.z, v.x, v.y, v.z, phi)

        
    
    def cameraTargetFunction(self, currentTarget):
        """Private! Return the point to target, or None if nothing to target."""
        if not self._cameraFollowCharacter or self._followedCharacter == None:
            return None
        
        pos = self._followedCharacter.getRoot().getCMPosition()
        pos.y = currentTarget.y
        return pos
    

    #    
    # Accessors
    
    def getWorldOracle(self):
        """Return the world oracle for the application."""
        return self._worldOracle
    
    def getFrame(self):
        """Returns the application frame."""
        return self._frame
    
    def setDrawShadows(self, drawShadows):
        """Indicates whether the app should draw shadows or not"""
        self._drawShadows = drawShadows
        
    def getDrawShadows(self):
        """Checks if the app is drawing shadows"""
        return self._drawShadows
    
    def getGLCanvas(self):
        """Returns the GL canvas"""
        return self._glCanvas
    
    def getToolPanel(self):
        """Returns the tool panel"""
        return self._toolPanel
    
    def setAnimationRunning(self, animationRunning):
        """Indicates whether the animation should run or not"""
        self._animationRunning = animationRunning
        self._animationObservable.notifyObservers()

    def isAnimationRunning(self):
        """Return true if the animation is currently running"""
        return self._animationRunning

    def setSimulationSecondsPerSecond(self, simulationSecondsPerSecond):
        """Sets the speed of the playback. 1 is realtime, 0.5 is slower, 2 is faster"""
        self._simulationSecondsPerSecond = simulationSecondsPerSecond
        self._animationObservable.notifyObservers()

    def getSimulationSecondsPerSecond(self):
        """Return the speed of the playback"""
        return self._simulationSecondsPerSecond
    
    def setCameraFollowCharacter(self, follow):
        """Indicates whether the camera should follow a character or not"""
        if follow != self._cameraFollowCharacter:
            # Need to toggle
            self._cameraFollowCharacter = follow
            if self._followedCharacter == None :
                try: self._followedCharacter = self._characters[0]
                except IndexError: pass
            self._cameraObservable.notifyObservers()
    
    def doesCameraFollowCharacter(self):
        """Checks if the camera is currently following a character."""
        return self._cameraFollowCharacter  and  self._followedCharacter != None
    
    def setFollowedCharacter(self, character):
        """Indicates which character the camera should be following. Pass an index of a string."""
        character = self.getCharacter(character)

        self._cameraFollowCharacter = True
        self._followedCharacter = character
        self._cameraObservable.notifyObservers()

    def setCameraAutoOrbit(self, autoOrbit):
        """Indicates whether the camera should automatically orbit or not"""
        self._glCanvas.setCameraAutoOrbit(autoOrbit)
            
    def doesCameraAutoOrbit(self):
        """Checks if the camera is currently automatically orbiting."""
        return self._glCanvas.doesCameraAutoOrbit()    
        
    def drawCollisionVolumes(self, draw):
        """Indicates whether the application should draw collision volumes"""
        if draw != self._drawCollisionVolumes:
            self._drawCollisionVolumes = draw
            self._optionsObservable.notifyObservers()
    
    def getDrawCollisionVolumes(self):
        """Does the application draw collision volumes?"""
        return self._drawCollisionVolumes
        
    def setKinematicMotion(self, kinematicMotion):
        """Indicates whether the application should animate only kinematic motion"""
        if kinematicMotion != self._kinematicMotion:
            self._kinematicMotion = kinematicMotion
            self._optionsObservable.notifyObservers()
    
    def getKinematicMotion(self):
        """Does the application animate only kinematic motion?"""
        return self._kinematicMotion
    
    def captureScreenShots(self, capture):
        """Indicates whether the application should capture a screenshot at every frame."""
        if capture != self._captureScreenShots:
            self._captureScreenShots = capture
            self._optionsObservable.notifyObservers()
    
    def getCaptureScreenShots(self):
        """Does the application capture a screenshot at every frame?"""
        return self._captureScreenShots
    
    #
    # Public methods
       
    def deleteAllObjects(self):
        """Delete all objects: characters, rigid bodies, snapshots, etc."""
        if self._followedCharacter is not None :           
            self._followedCharacter = None
            self._cameraFollowCharacter = False
            self._cameraObservable.notifyObservers()        
        self._characters = []
        self._controllerList.clear()
        import Physics
        Physics.world().destroyAllObjects()
        self.deleteAllSnapshots()        
       
    def addCharacter(self, character):
        """Adds a character to the application and the world"""
        import Physics
        if PyUtils.sameObjectInList(character, self._characters) :
            raise KeyError ('Cannot add the same character twice to application.')
        Physics.world().addArticulatedFigure( character )
        self._characters.append( character )
        if self._followedCharacter is None :
            self._followedCharacter = character
            self._cameraFollowCharacter = True
            self._cameraObservable.notifyObservers()
        self._characterObservable.notifyObservers()

    def deleteCharacter(self, character):
        """Removes a character from the application. Specify either a name, an index, or an instance of a character object."""        
        character = self.getCharacter(character)
        if self._followedCharacter is character :           
            self._followedCharacter = None
            self._cameraFollowCharacter = False
            self._cameraObservable.notifyObservers()
        self._characters.remove(character)
        self._characterObservable.notifyObservers()
        
    def getCharacter(self, description ):
        """Returns a character. Specify either a name, an index. Anything else will be returned unmodified."""
        if isinstance(description,basestring) :
            try: 
                description = [char.getName() for char in self._characters].index(description)
            except ValueError: raise ValueError( "No character found with the specified name." )
        if isinstance(description,int) :
            return self._characters[description]
        return description
    
    def getCharacterCount(self):
        """Returns the number of characters."""
        return len( self._character )
    
    def recenterCharacter(self, character):
        """Reposition the character at the center of the world in X,Z. Specify either a name, an index, or an instance of a character object."""
        character = self.getCharacter(character)
        character.recenter()
        
    
    def addController(self, controller):
        """Adds a controller to the application"""
        return self._controllerList.add(controller)

    def deleteController(self, controller):
        """Removes a controller from the application. Specify either a name, an index, or an instance of a controller object."""        
        return self._controllerList.delete(controller)

    def getController(self, description):        
        """Returns a controller. Specify either a name, an index. Anything else will be returned unmodified."""
        return self._controllerList.get(description)

    def getControllerCount(self):
        """Returns the number of controllers."""
        return self._controllerList.getCount()
        
    def getControllerList(self):
        """Returns the controller list object. Useful for observation."""
        return self._controllerList
    
    
    def addCurve(self, name, trajectory1d, phiPtr = None):
        """Adds a curve to the application"""
        return self._curveList.add( Curve(name, trajectory1d, phiPtr) )

    def deleteCurve(self, curve):
        """Removes a curve from the application. Specify either a name, an index, or an instance of a controller object."""        
        return self._curveList.delete(curve)

    def clearCurves(self):
        """Remove all the curves from the application."""
        self._curveList.clear();
    
    def getCurve(self, description):
        """Returns a curve. Specify either a name, an index. Anything else will be returned unmodified."""
        return self._curveList.get(description)

    def getCurveCount(self):
        """Returns the number of curves."""
        return self._curveList.getCount()
        
    def getCurveList(self):
        """Returns the curve list object. Useful for observation."""
        return self._curveList
    
    def getSnapshotTree(self):
        """Returns the top-level SnapshotBranch that can be observed.""" 
        return self._snapshotTree
    
    def takeSnapshot(self):
        """Take a snapshot of the world.
        The snapshot will be returned and added to the snapshot tree."""
        return self._snapshotTree.takeSnapshot()
    
    def restoreActiveSnapshot(self, restoreControllerParams = True):
        """Restores the current snapshot. Return it."""
        return self._snapshotTree.restoreActive(restoreControllerParams)

    def previousSnapshot(self, restoreControllerParams = True):
        """Navigate to the previous snapshot. Return it, or None if failed."""
        return self._snapshotTree.previousSnapshot(restoreControllerParams)
    
    def nextSnapshot(self, restoreControllerParams = True):
        """Navigate to the next snapshot. Return it, or None if failed."""
        return self._snapshotTree.nextSnapshot(restoreControllerParams)

    def deleteAllSnapshots(self):
        """Delete all the snapshots of the world."""
        self._snapshotTree = SnapshotBranch()    
    #
    # For observers
    #    
    def addCharacterObserver(self, observer):
        self._characterObservable.addObserver(observer)
    
    def deleteCharacterObserver(self, observer):
        self._characterObservable.deleteObserver(observer)
    
    def addControllerObserver(self, observer):
        self._controllerList.addObserver(observer)
    
    def deleteControllerObserver(self, observer):
        self._controllerList.deleteObserver(observer)
    
    def addAnimationObserver(self, observer):
        self._animationObservable.addObserver(observer)
    
    def deleteAnimationObserver(self, observer):
        self._animationObservable.deleteObserver(observer)        
    
    def addCameraObserver(self, observer):
        self._cameraObservable.addObserver(observer)
    
    def deleteCameraObserver(self, observer):
        self._cameraObservable.deleteObserver(observer)
        
    def addOptionsObserver(self, observer):
        self._optionsObservable.addObserver(observer)
    
    def deleteOptionsObserver(self, observer):
        self._optionsObservable.deleteObserver(observer)
Ejemplo n.º 5
0
class Row(Prototype):

    """This class contains the functionality for rows.

    This class is used by :class:`knitting patterns
    <knittingpattern.KnittingPattern.KnittingPattern>`.
    """

    def __init__(self, row_id, values, parser):
        """Create a new row.

        :param row_id: an identifier for the row
        :param values: the values from the specification
        :param list inheriting_from: a list of specifications to inherit values
          from, see :class:`knittingpattern.Prototype.Prototype`

        .. note:: Seldomly, you need to create this row on your own. You can
          load it with the :mod:`knittingpattern` or the
          :class:`knittingpattern.Parser.Parser`.
        """
        super().__init__(values)
        self._id = row_id
        self._instructions = ObservableList()
        self._instructions.register_observer(self._instructions_changed)
        self._parser = parser

    def _instructions_changed(self, change):
        """Call when there is a change in the instructions."""
        if change.adds():
            for index, instruction in change.items():
                if isinstance(instruction, dict):
                    in_row = self._parser.instruction_in_row(self, instruction)
                    self.instructions[index] = in_row
                else:
                    instruction.transfer_to_row(self)

    @property
    def id(self):
        """The id of the row.

        :return: the id of the row
        """
        return self._id

    @property
    def instructions(self):
        """The instructions in this row.

        :return: a collection of :class:`instructions inside the row
          <knittingpattern.Instruction.InstructionInRow>`
        :rtype: ObservableList.ObservableList
        """
        return self._instructions

    @property
    def number_of_produced_meshes(self):
        """The number of meshes that this row produces.

        :return: the number of meshes that this row produces
        :rtype: int

        .. seealso::
          :meth:`Instruction.number_of_produced_meshes()
          <knittingpattern.Instruction.Instruction.number_of_produced_meshes>`,
          :meth:`number_of_consumed_meshes`
        """
        return sum(instruction.number_of_produced_meshes
                   for instruction in self.instructions)

    @property
    def number_of_consumed_meshes(self):
        """The number of meshes that this row consumes.

        :return: the number of meshes that this row consumes
        :rtype: int

        .. seealso::
          :meth:`Instruction.number_of_consumed_meshes()
          <knittingpattern.Instruction.Instruction.number_of_consumed_meshes>`,
          :meth:`number_of_produced_meshes`
        """
        return sum(instruction.number_of_consumed_meshes
                   for instruction in self.instructions)

    @property
    def produced_meshes(self):
        """The meshes that this row produces with its instructions.

        :return: a collection of :class:`meshes <knittingpattern.Mesh.Mesh>`
          that this instruction produces

        """
        return list(chain(*(instruction.produced_meshes
                            for instruction in self.instructions)))

    @property
    def consumed_meshes(self):
        """Same as :attr:`produced_meshes` but for consumed meshes."""
        return list(chain(*(instruction.consumed_meshes
                            for instruction in self.instructions)))

    def __repr__(self):
        """The string representation of this row.

        :return: a string representation of this row
        :rtype: str
        """
        return "<{} {}>".format(self.__class__.__qualname__, self.id)

    @property
    def color(self):
        """The color of the row.

        :return: the color of the row as specified or :obj:`None`
        """
        return self.get(COLOR)

    @property
    def instruction_colors(self):
        """The colors of the instructions in the row in the order tehy appear.

        :return: a list of colors of the knitting pattern in the order that
          they appear in
        :rtype: list
        """
        return unique(instruction.colors for instruction in self.instructions)

    @property
    def last_produced_mesh(self):
        """The last produced mesh.

        :return: the last produced mesh
        :rtype: knittingpattern.Mesh.Mesh
        :raises IndexError: if no mesh is produced

        .. seealso:: :attr:`number_of_produced_meshes`
        """
        for instruction in reversed(self.instructions):
            if instruction.produces_meshes():
                return instruction.last_produced_mesh
        raise IndexError("{} produces no meshes".format(self))

    @property
    def last_consumed_mesh(self):
        """The last consumed mesh.

        :return: the last consumed mesh
        :rtype: knittingpattern.Mesh.Mesh
        :raises IndexError: if no mesh is consumed

        .. seealso:: :attr:`number_of_consumed_meshes`
        """
        for instruction in reversed(self.instructions):
            if instruction.consumes_meshes():
                return instruction.last_consumed_mesh
        raise IndexError("{} consumes no meshes".format(self))

    @property
    def first_produced_mesh(self):
        """The first produced mesh.

        :return: the first produced mesh
        :rtype: knittingpattern.Mesh.Mesh
        :raises IndexError: if no mesh is produced

        .. seealso:: :attr:`number_of_produced_meshes`
        """
        for instruction in self.instructions:
            if instruction.produces_meshes():
                return instruction.first_produced_mesh
        raise IndexError("{} produces no meshes".format(self))

    @property
    def first_consumed_mesh(self):
        """The first consumed mesh.

        :return: the first consumed mesh
        :rtype: knittingpattern.Mesh.Mesh
        :raises IndexError: if no mesh is consumed

        .. seealso:: :attr:`number_of_consumed_meshes`
        """
        for instruction in self.instructions:
            if instruction.consumes_meshes():
                return instruction.first_consumed_mesh
        raise IndexError("{} consumes no meshes".format(self))

    @property
    def rows_before(self):
        """The rows that produce meshes for this row.

        :rtype: list
        :return: a list of rows that produce meshes for this row. Each row
          occurs only once. They are sorted by the first occurrence in the
          instructions.
        """
        rows_before = []
        for mesh in self.consumed_meshes:
            if mesh.is_produced():
                row = mesh.producing_row
                if rows_before not in rows_before:
                    rows_before.append(row)
        return rows_before

    @property
    def rows_after(self):
        """The rows that consume meshes from this row.

        :rtype: list
        :return: a list of rows that consume meshes from this row. Each row
          occurs only once. They are sorted by the first occurrence in the
          instructions.
        """
        rows_after = []
        for mesh in self.produced_meshes:
            if mesh.is_consumed():
                row = mesh.consuming_row
                if rows_after not in rows_after:
                    rows_after.append(row)
        return rows_after

    @property
    def first_instruction(self):
        """The first instruction of the rows instructions.

        :rtype: knittingpattern.Instruction.InstructionInRow
        :return: the first instruction in this row's :attr:`instructions`
        """
        return self.instructions[0]

    @property
    def last_instruction(self):
        """The last instruction of the rows instructions.

        :rtype: knittingpattern.Instruction.InstructionInRow
        :return: the last instruction in this row's :attr:`instructions`
        """
        return self.instructions[-1]
Ejemplo n.º 6
0
def test_initialize_with_list():
    items = (1, 2, 3)
    assert ObservableList(items) == list(items)
Ejemplo n.º 7
0
class Row(Prototype):

    """This class contains the functionality for rows.

    This class is used by :class:`knitting patterns
    <knittingpattern.KnittingPattern.KnittingPattern>`.
    """

    def __init__(self, row_id, values, parser):
        """Create a new row.

        :param row_id: an identifier for the row
        :param values: the values from the specification
        :param list inheriting_from: a list of specifications to inherit values
          from, see :class:`knittingpattern.Prototype.Prototype`

        .. note:: Seldomly, you need to create this row on your own. You can
          load it with the :mod:`knittingpattern` or the
          :class:`knittingpattern.Parser.Parser`.
        """
        super().__init__(values)
        self._id = row_id
        self._instructions = ObservableList()
        self._instructions.register_observer(self._instructions_changed)
        self._parser = parser

    def _instructions_changed(self, change):
        """Call when there is a change in the instructions."""
        if change.adds():
            for index, instruction in change.items():
                if isinstance(instruction, dict):
                    in_row = self._parser.instruction_in_row(self, instruction)
                    self.instructions[index] = in_row
                else:
                    instruction.transfer_to_row(self)

    @property
    def id(self):
        """The id of the row.

        :return: the id of the row
        """
        return self._id

    @property
    def instructions(self):
        """The instructions in this row.

        :return: a collection of :class:`instructions inside the row
          <knittingpattern.Instruction.InstructionInRow>`
        :rtype: ObservableList.ObservableList
        """
        return self._instructions

    @property
    def number_of_produced_meshes(self):
        """The number of meshes that this row produces.

        :return: the number of meshes that this row produces
        :rtype: int

        .. seealso::
          :meth:`Instruction.number_of_produced_meshes()
          <knittingpattern.Instruction.Instruction.number_of_produced_meshes>`,
          :meth:`number_of_consumed_meshes`
        """
        return sum(instruction.number_of_produced_meshes
                   for instruction in self.instructions)

    @property
    def number_of_consumed_meshes(self):
        """The number of meshes that this row consumes.

        :return: the number of meshes that this row consumes
        :rtype: int

        .. seealso::
          :meth:`Instruction.number_of_consumed_meshes()
          <knittingpattern.Instruction.Instruction.number_of_consumed_meshes>`,
          :meth:`number_of_produced_meshes`
        """
        return sum(instruction.number_of_consumed_meshes
                   for instruction in self.instructions)

    @property
    def produced_meshes(self):
        """The meshes that this row produces with its instructions.

        :return: a collection of :class:`meshes <knittingpattern.Mesh.Mesh>`
          that this instruction produces

        """
        return list(chain(*(instruction.produced_meshes
                            for instruction in self.instructions)))

    @property
    def consumed_meshes(self):
        """Same as :attr:`produced_meshes` but for consumed meshes."""
        return list(chain(*(instruction.consumed_meshes
                            for instruction in self.instructions)))

    def __repr__(self):
        """The string representation of this row.

        :return: a string representation of this row
        :rtype: str
        """
        return "<{} {}>".format(self.__class__.__qualname__, self.id)

    @property
    def color(self):
        """The color of the row.

        :return: the color of the row as specified or :obj:`None`
        """
        return self.get(COLOR)

    @property
    def instruction_colors(self):
        """The colors of the instructions in the row in the order tehy appear.

        :return: a list of colors of the knitting pattern in the order that
          they appear in
        :rtype: list
        """
        return unique(instruction.colors for instruction in self.instructions)

    @property
    def last_produced_mesh(self):
        """The last produced mesh.

        :return: the last produced mesh
        :rtype: knittingpattern.Mesh.Mesh
        :raises IndexError: if no mesh is produced

        .. seealso:: :attr:`number_of_produced_meshes`
        """
        for instruction in reversed(self.instructions):
            if instruction.produces_meshes():
                return instruction.last_produced_mesh
        raise IndexError("{} produces no meshes".format(self))

    @property
    def last_consumed_mesh(self):
        """The last consumed mesh.

        :return: the last consumed mesh
        :rtype: knittingpattern.Mesh.Mesh
        :raises IndexError: if no mesh is consumed

        .. seealso:: :attr:`number_of_consumed_meshes`
        """
        for instruction in reversed(self.instructions):
            if instruction.consumes_meshes():
                return instruction.last_consumed_mesh
        raise IndexError("{} consumes no meshes".format(self))

    @property
    def first_produced_mesh(self):
        """The first produced mesh.

        :return: the first produced mesh
        :rtype: knittingpattern.Mesh.Mesh
        :raises IndexError: if no mesh is produced

        .. seealso:: :attr:`number_of_produced_meshes`
        """
        for instruction in self.instructions:
            if instruction.produces_meshes():
                return instruction.first_produced_mesh
        raise IndexError("{} produces no meshes".format(self))

    @property
    def first_consumed_mesh(self):
        """The first consumed mesh.

        :return: the first consumed mesh
        :rtype: knittingpattern.Mesh.Mesh
        :raises IndexError: if no mesh is consumed

        .. seealso:: :attr:`number_of_consumed_meshes`
        """
        for instruction in self.instructions:
            if instruction.consumes_meshes():
                return instruction.first_consumed_mesh
        raise IndexError("{} consumes no meshes".format(self))

    @property
    def rows_before(self):
        """The rows that produce meshes for this row.

        :rtype: list
        :return: a list of rows that produce meshes for this row. Each row
          occurs only once. They are sorted by the first occurence in the
          instructions.
        """
        rows_before = []
        for mesh in self.consumed_meshes:
            if mesh.is_produced():
                row = mesh.producing_row
                if rows_before not in rows_before:
                    rows_before.append(row)
        return rows_before

    @property
    def rows_after(self):
        """The rows that consume meshes from this row.

        :rtype: list
        :return: a list of rows that consume meshes from this row. Each row
          occurs only once. They are sorted by the first occurence in the
          instructions.
        """
        rows_after = []
        for mesh in self.produced_meshes:
            if mesh.is_consumed():
                row = mesh.consuming_row
                if rows_after not in rows_after:
                    rows_after.append(row)
        return rows_after

    @property
    def first_instruction(self):
        """The first instruction of the rows instructions.

        :rtype: knittingpattern.Instruction.InstructionInRow
        :return: the first instruction in this row's :attr:`instructions`
        """
        return self.instructions[0]

    @property
    def last_instruction(self):
        """The last instruction of the rows instructions.

        :rtype: knittingpattern.Instruction.InstructionInRow
        :return: the last instruction in this row's :attr:`instructions`
        """
        return self.instructions[-1]
Ejemplo n.º 8
0
    def __init__(self,
                 appTitle="Simbicon Application",
                 fps=30.0,
                 dt=1 / 2000.0,
                 glCanvasSize=wx.DefaultSize,
                 size=wx.DefaultSize,
                 redirect=False,
                 filename=None,
                 useBestVisual=False,
                 clearSigInt=True,
                 showConsole=True):
        """
        appTitle is the window title
        fps is the desired number of frames per seconds
        dt is the desired simulation timestep
        :see: wx.BasicApp.__init__`
        """

        wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)

        # No annoying error logging window
        wx.Log.SetActiveTarget(wx.LogStderr())

        import UI

        # Setup the main window style
        style = wx.DEFAULT_FRAME_STYLE
        if size == wx.DefaultSize:
            size = wx.GetDisplaySize()
            size.height *= 0.75
            size.width *= 0.75
            if glCanvasSize == wx.DefaultSize:
                style |= wx.MAXIMIZE

        # Setup the environment for the python interactive console
        consoleEnvironment = {"wx": wx, "Physics": Physics, "Utils": Utils}
        exec "from MathLib import *\n" + \
             "app = wx.GetApp()\n" + \
             "from PyUtils import load" in consoleEnvironment, consoleEnvironment

        # Create the main window
        self._frame = UI.MainWindow(None,
                                    -1,
                                    appTitle,
                                    size=size,
                                    style=style,
                                    fps=fps,
                                    glCanvasSize=glCanvasSize,
                                    showConsole=showConsole,
                                    consoleEnvironment=consoleEnvironment)

        # Define GL callbacks
        self._glCanvas = self._frame.getGLCanvas()
        self._glCanvas.addDrawCallback(self.draw)
        self._glCanvas.addPostDrawCallback(self.postDraw)
        self._glCanvas.addOncePerFrameCallback(self.advanceAnimation)
        self._glCanvas.setDrawAxes(False)
        self._glCanvas.setPrintLoad(True)
        self._glCanvas.setCameraTargetFunction(self.cameraTargetFunction)

        self._glCanvas.setDrawGround(False)

        # Get the tool panel
        self._toolPanel = self._frame.getToolPanel()

        # Show the application
        self._frame.Show()

        # Set-up starting state
        self._dt = dt
        self._drawShadows = True
        self._simulationSecondsPerSecond = 1  # 1 = real time, 2 = twice real time, 1/2 = half real time
        self._animationRunning = False
        self._cameraFollowCharacter = False
        self._drawCollisionVolumes = False
        self._followedCharacter = None  # Pointer to focused character
        self._captureScreenShots = False
        self._printStepReport = True
        self._screenShotNumber = 0
        self._worldOracle = Core.WorldOracle()
        self._worldOracle.initializeWorld(Physics.world())
        self._kinematicMotion = False

        # Set-up starting list of characters and controllers
        self._characters = []

        # Define the observables
        self._controllerList = ObservableList()
        self._characterObservable = PyUtils.Observable()
        self._animationObservable = PyUtils.Observable()
        self._cameraObservable = PyUtils.Observable()
        self._optionsObservable = PyUtils.Observable()

        self._COMObservable = PyUtils.Observable()

        self._curveList = ObservableList()
        self._snapshotTree = SnapshotBranch()

        self._showAbstractView = False
        self._showAbstractViewSkeleton = False
        self._showBodyFrame = False
        self._showCDPrimitives = False
        self._showColors = False
        self._showFrictionParticles = False
        self._showJoints = False
        self._showMesh = True
        self._showMinBDGSphere = False
        self._showCenterOfMass = True

        self._COMErrorScale = 0.01

        params = [
            3.75162180e-04, 1.70361201e+00, -7.30441228e-01, -6.22795336e-01,
            3.05330848e-01
        ]
        fps = 100

        # params = [0, 0, 0, 0, 0]

        # fps = 100.0
        # model_order = (50, 50)
        # params = [0.00019815056771797725, 1.9687785869242351, -0.9709165752219967, -0.565841931234043, 0.3226849680645409]

        self._armaX = ArmaProcess(params[0], params[1:3], params[3:5], fps)
        self._armaY = ArmaProcess(params[0], params[1:3], params[3:5], fps)
        self._armaZ = ArmaProcess(params[0], params[1:3], params[3:5], fps)
Ejemplo n.º 9
0
def ol(onchange):
    """The observable list."""
    ol_ = ObservableList()
    ol_.register_observer(onchange)
    return ol_
Ejemplo n.º 10
0
class SNMApp(wx.App):
    """A simple class that should handle almost everything a simbicon application typically needs."""
    def __init__(self,
                 appTitle="Simbicon Application",
                 fps=30.0,
                 dt=1 / 2000.0,
                 glCanvasSize=wx.DefaultSize,
                 size=wx.DefaultSize,
                 redirect=False,
                 filename=None,
                 useBestVisual=False,
                 clearSigInt=True,
                 showConsole=True):
        """
        appTitle is the window title
        fps is the desired number of frames per seconds
        dt is the desired simulation timestep
        :see: wx.BasicApp.__init__`
        """

        wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)

        # No annoying error logging window
        wx.Log.SetActiveTarget(wx.LogStderr())

        import UI

        # Setup the main window style
        style = wx.DEFAULT_FRAME_STYLE
        if size == wx.DefaultSize:
            size = wx.GetDisplaySize()
            size.height *= 0.75
            size.width *= 0.75
            if glCanvasSize == wx.DefaultSize:
                style |= wx.MAXIMIZE

        # Setup the environment for the python interactive console
        consoleEnvironment = {"wx": wx, "Physics": Physics, "Utils": Utils}
        exec "from MathLib import *\n" + \
             "app = wx.GetApp()\n" + \
             "from PyUtils import load" in consoleEnvironment, consoleEnvironment

        # Create the main window
        self._frame = UI.MainWindow(None,
                                    -1,
                                    appTitle,
                                    size=size,
                                    style=style,
                                    fps=fps,
                                    glCanvasSize=glCanvasSize,
                                    showConsole=showConsole,
                                    consoleEnvironment=consoleEnvironment)

        # Define GL callbacks
        self._glCanvas = self._frame.getGLCanvas()
        self._glCanvas.addDrawCallback(self.draw)
        self._glCanvas.addPostDrawCallback(self.postDraw)
        self._glCanvas.addOncePerFrameCallback(self.advanceAnimation)
        self._glCanvas.setDrawAxes(False)
        self._glCanvas.setPrintLoad(True)
        self._glCanvas.setCameraTargetFunction(self.cameraTargetFunction)

        self._glCanvas.setDrawGround(False)

        # Get the tool panel
        self._toolPanel = self._frame.getToolPanel()

        # Show the application
        self._frame.Show()

        # Set-up starting state
        self._dt = dt
        self._drawShadows = True
        self._simulationSecondsPerSecond = 1  # 1 = real time, 2 = twice real time, 1/2 = half real time
        self._animationRunning = False
        self._cameraFollowCharacter = False
        self._drawCollisionVolumes = False
        self._followedCharacter = None  # Pointer to focused character
        self._captureScreenShots = False
        self._printStepReport = True
        self._screenShotNumber = 0
        self._worldOracle = Core.WorldOracle()
        self._worldOracle.initializeWorld(Physics.world())
        self._kinematicMotion = False

        # Set-up starting list of characters and controllers
        self._characters = []

        # Define the observables
        self._controllerList = ObservableList()
        self._characterObservable = PyUtils.Observable()
        self._animationObservable = PyUtils.Observable()
        self._cameraObservable = PyUtils.Observable()
        self._optionsObservable = PyUtils.Observable()

        self._COMObservable = PyUtils.Observable()

        self._curveList = ObservableList()
        self._snapshotTree = SnapshotBranch()

        self._showAbstractView = False
        self._showAbstractViewSkeleton = False
        self._showBodyFrame = False
        self._showCDPrimitives = False
        self._showColors = False
        self._showFrictionParticles = False
        self._showJoints = False
        self._showMesh = True
        self._showMinBDGSphere = False
        self._showCenterOfMass = True

        self._COMErrorScale = 0.01

        params = [
            3.75162180e-04, 1.70361201e+00, -7.30441228e-01, -6.22795336e-01,
            3.05330848e-01
        ]
        fps = 100

        # params = [0, 0, 0, 0, 0]

        # fps = 100.0
        # model_order = (50, 50)
        # params = [0.00019815056771797725, 1.9687785869242351, -0.9709165752219967, -0.565841931234043, 0.3226849680645409]

        self._armaX = ArmaProcess(params[0], params[1:3], params[3:5], fps)
        self._armaY = ArmaProcess(params[0], params[1:3], params[3:5], fps)
        self._armaZ = ArmaProcess(params[0], params[1:3], params[3:5], fps)

    #
    # Private methods

    def draw(self):
        """Draw the content of the world"""
        world = Physics.world()

        flags = 0
        if self._showAbstractView:
            flags = flags | Physics.SHOW_ABSTRACT_VIEW
        if self._showAbstractViewSkeleton:
            flags = flags | Physics.SHOW_ABSTRACT_VIEW_SKELETON
        if self._showBodyFrame:
            flags = flags | Physics.SHOW_BODY_FRAME
        if self._showCDPrimitives:
            flags = flags | Physics.SHOW_CD_PRIMITIVES
        if self._showColors:
            flags = flags | Physics.SHOW_COLOURS
        if self._showFrictionParticles:
            flags = flags | Physics.SHOW_FRICTION_PARTICLES
        if self._showJoints:
            flags = flags | Physics.SHOW_JOINTS
        if self._showMesh:
            flags = flags | Physics.SHOW_MESH
        if self._showMinBDGSphere:
            flags = flags | Physics.SHOW_MIN_BDG_SPHERE
        if self._showCenterOfMass:
            flags = flags | Physics.SHOW_CENTER_OF_MASS

        glEnable(GL_LIGHTING)
        world.drawRBs(flags)

        glDisable(GL_LIGHTING)

        if self._drawShadows:
            self._glCanvas.beginShadows()
            world.drawRBs(Physics.SHOW_MESH)
            self._glCanvas.endShadows()

        if len(self._characters) > 0:

            self.updateCOMError()

            self.COMPanel.update()

            self._characters[0].drawRealCOM(flags)
            self._characters[0].drawPercievedCOM(flags)

    def postDraw(self):
        """Perform some operation once the entire OpenGL window has been drawn"""
        if self._captureScreenShots:
            self._glCanvas.saveScreenshot("../screenShots/%04d.bmp" %
                                          self._screenShotNumber)
            self._screenShotNumber += 1

    def advanceAnimation(self):
        """Called once per frame"""
        if self._animationRunning:
            self.simulationFrame()

    def simulationFrame(self):
        """Performs enough simulation steps to fill one frame"""

        # Enough time elapsed perform simulation loop and render
        simulationSeconds = 1.0 / self._glCanvas.getFps(
        ) * self._simulationSecondsPerSecond
        nbSteps = int(math.ceil(simulationSeconds / self._dt))

        for i in range(0, nbSteps):
            self.simulationStep()

    def advanceAnimationUntilControllerEnds(self, controller):
        """Advances the animation until the specified controller reaches the end.
        Specify either a name, an index, or an instance of a controller object."""
        controller = self.getController(controller)
        initialPhi = controller.getPhase()
        currPhi = initialPhi + 1
        while currPhi > initialPhi:
            self.simulationStep()
            currPhi = controller.getPhase()

    def updateCOMError(self):

        # Apply ARMA process

        self.setCOMX(self._armaX.generate_frame() * 0.004 * 0)
        self.setCOMY(self._armaY.generate_frame() * 0.001 * 0)
        self.setCOMZ(self._armaZ.generate_frame() * 0.004 * 0)

#         sins = [0.3, 1, 2, 3, 0.5, 1.3, 1.8, 3.4, 0.4, 0.8, 1.5, 3.04]
#         t = time.time()
#
#         # Map each sin weight to the reciprocal of the frequency
#         sins = map(lambda x: (x, 1/x), sins)
#
#         x = self.discreteSinusoids(sins[:4], t)
#         y = self.discreteSinusoids(sins[4:8], t + 1021.34353)
#         z = self.discreteSinusoids(sins[8:], t + 543.4346)
#
#         (x, y, z) = map(lambda x: x * self._COMErrorScale, (x, y, z))
#
#         self.setCOMX(x)
#         self.setCOMY(y)
#         self.setCOMZ(z)
#

    def discreteSinusoids(self, sins, t):
        accumulator = 0
        for sin, weight in sins:
            # Here, sin is interpreted as `t-times` per second
            # And t is the number of seconds
            accumulator += math.sin((t * sin) * (2 * math.pi)) * weight

        return accumulator

    def simulationStep(self):
        """Performs a single simulation step"""

        # TODO Quite hacky
        if self._kinematicMotion:
            import KeyframeEditor
            from MathLib import Trajectory3dv
            try:
                pc = self._posableCharacter
                traj = self._stanceFootToSwingFootTrajectory
            except AttributeError:
                pc = self._posableCharacter = KeyframeEditor.PosableCharacter.PosableCharacter(
                    self.getCharacter(0), self.getController(0))
                traj = self._stanceFootToSwingFootTrajectory = Trajectory3dv()
                traj.addKnot(0, Vector3d(-0.13, 0, -0.4))
                traj.addKnot(0.5, Vector3d(-0.13, 0.125, 0))
                traj.addKnot(1, Vector3d(-0.13, 0, 0.4))
                self._phase = 0
                self._stance = Core.LEFT_STANCE

            stanceToSwing = traj.evaluate_catmull_rom(self._phase)
            if self._stance == Core.RIGHT_STANCE:
                stanceToSwing.x = stanceToSwing.x * -1
            pc.updatePose(self._phase, stanceToSwing, self._stance, True)

            self._phase += 0.00069
            if self._phase >= 1.0:
                self._phase = 0
                if self._stance == Core.LEFT_STANCE:
                    self._stance = Core.RIGHT_STANCE
                else:
                    self._stance = Core.LEFT_STANCE
            return

        world = Physics.world()
        controllers = self._controllerList._objects
        contactForces = world.getContactForces()
        for controller in controllers:
            controller.performPreTasks(self._dt, contactForces)
        world.advanceInTime(self._dt)

        contactForces = world.getContactForces()
        for controller in controllers:
            if controller.performPostTasks(self._dt, contactForces):
                step = Vector3d(controller.getStanceFootPos(),
                                controller.getSwingFootPos())
                step = controller.getCharacterFrame().inverseRotate(step)
                v = controller.getV()
                phi = controller.getPhase()
                if self._printStepReport:
                    print "step: %3.5f %3.5f %3.5f. Vel: %3.5f %3.5f %3.5f  phi = %f" % (
                        step.x, step.y, step.z, v.x, v.y, v.z, phi)

    def cameraTargetFunction(self, currentTarget):
        """Private! Return the point to target, or None if nothing to target."""
        if not self._cameraFollowCharacter or self._followedCharacter == None:
            return None

        pos = self._followedCharacter.getRoot().getCMPosition()
        pos.y = currentTarget.y
        return pos

    #
    # Accessors

    def getWorldOracle(self):
        """Return the world oracle for the application."""
        return self._worldOracle

    def getFrame(self):
        """Returns the application frame."""
        return self._frame

    def setDrawShadows(self, drawShadows):
        """Indicates whether the app should draw shadows or not"""
        self._drawShadows = drawShadows

    def getDrawShadows(self):
        """Checks if the app is drawing shadows"""
        return self._drawShadows

    def getGLCanvas(self):
        """Returns the GL canvas"""
        return self._glCanvas

    def getToolPanel(self):
        """Returns the tool panel"""
        return self._toolPanel

    def setAnimationRunning(self, animationRunning):
        """Indicates whether the animation should run or not"""
        self._animationRunning = animationRunning
        self._animationObservable.notifyObservers()

    def isAnimationRunning(self):
        """Return true if the animation is currently running"""
        return self._animationRunning

    def setSimulationSecondsPerSecond(self, simulationSecondsPerSecond):
        """Sets the speed of the playback. 1 is realtime, 0.5 is slower, 2 is faster"""
        self._simulationSecondsPerSecond = simulationSecondsPerSecond
        self._animationObservable.notifyObservers()

    def getSimulationSecondsPerSecond(self):
        """Return the speed of the playback"""
        return self._simulationSecondsPerSecond

    def setCameraFollowCharacter(self, follow):
        """Indicates whether the camera should follow a character or not"""
        if follow != self._cameraFollowCharacter:
            # Need to toggle
            self._cameraFollowCharacter = follow
            if self._followedCharacter == None:
                try:
                    self._followedCharacter = self._characters[0]
                except IndexError:
                    pass
            self._cameraObservable.notifyObservers()

    def doesCameraFollowCharacter(self):
        """Checks if the camera is currently following a character."""
        return self._cameraFollowCharacter and self._followedCharacter != None

    def setFollowedCharacter(self, character):
        """Indicates which character the camera should be following. Pass an index of a string."""
        character = self.getCharacter(character)

        self._cameraFollowCharacter = True
        self._followedCharacter = character
        self._cameraObservable.notifyObservers()

    def setCameraAutoOrbit(self, autoOrbit):
        """Indicates whether the camera should automatically orbit or not"""
        self._glCanvas.setCameraAutoOrbit(autoOrbit)

    def doesCameraAutoOrbit(self):
        """Checks if the camera is currently automatically orbiting."""
        return self._glCanvas.doesCameraAutoOrbit()

    def drawCollisionVolumes(self, draw):
        """Indicates whether the application should draw collision volumes"""
        if draw != self._drawCollisionVolumes:
            self._drawCollisionVolumes = draw
            self._optionsObservable.notifyObservers()

    def getDrawCollisionVolumes(self):
        """Does the application draw collision volumes?"""
        return self._drawCollisionVolumes

    def setKinematicMotion(self, kinematicMotion):
        """Indicates whether the application should animate only kinematic motion"""
        if kinematicMotion != self._kinematicMotion:
            self._kinematicMotion = kinematicMotion
            self._optionsObservable.notifyObservers()

    def getKinematicMotion(self):
        """Does the application animate only kinematic motion?"""
        return self._kinematicMotion

    def setOption(self, option):
        """ Generates a function for setting an attribute of this class instance. """
        def callable_(value):

            if value != getattr(self, option):
                setattr(self, option, value)
                self._optionsObservable.notifyObservers()

        return callable_

    def getOption(self, option):
        """ Generates a function for getting an attribute of this class instance. """
        def callable_():
            return getattr(self, option)

        return callable_

    def captureScreenShots(self, capture):
        """Indicates whether the application should capture a screenshot at every frame."""
        if capture != self._captureScreenShots:
            self._captureScreenShots = capture
            self._optionsObservable.notifyObservers()

    def getCaptureScreenShots(self):
        """Does the application capture a screenshot at every frame?"""
        return self._captureScreenShots

    #
    # Public methods

    def deleteAllObjects(self):
        """Delete all objects: characters, rigid bodies, snapshots, etc."""
        if self._followedCharacter is not None:
            self._followedCharacter = None
            self._cameraFollowCharacter = False
            self._cameraObservable.notifyObservers()
        self._characters = []
        self._controllerList.clear()
        import Physics
        Physics.world().destroyAllObjects()
        self.deleteAllSnapshots()

    def addCharacter(self, character):
        """Adds a character to the application and the world"""
        import Physics
        if PyUtils.sameObjectInList(character, self._characters):
            raise KeyError(
                'Cannot add the same character twice to application.')
        Physics.world().addArticulatedFigure(character)
        self._characters.append(character)
        if self._followedCharacter is None:
            self._followedCharacter = character
            self._cameraFollowCharacter = True
            self._cameraObservable.notifyObservers()
        self._characterObservable.notifyObservers()

    def deleteCharacter(self, character):
        """Removes a character from the application. Specify either a name, an index, or an instance of a character object."""
        character = self.getCharacter(character)
        if self._followedCharacter is character:
            self._followedCharacter = None
            self._cameraFollowCharacter = False
            self._cameraObservable.notifyObservers()
        self._characters.remove(character)
        self._characterObservable.notifyObservers()

    def getCharacter(self, description):
        """Returns a character. Specify either a name, an index. Anything else will be returned unmodified."""
        if isinstance(description, basestring):
            try:
                description = [char.getName()
                               for char in self._characters].index(description)
            except ValueError:
                raise ValueError("No character found with the specified name.")
        if isinstance(description, int):
            return self._characters[description]
        return description

    def getCharacterCount(self):
        """Returns the number of characters."""
        return len(self._character)

    def recenterCharacter(self, character):
        """Reposition the character at the center of the world in X,Z. Specify either a name, an index, or an instance of a character object."""
        character = self.getCharacter(character)
        character.recenter()

    def addController(self, controller):
        """Adds a controller to the application"""
        return self._controllerList.add(controller)

    def deleteController(self, controller):
        """Removes a controller from the application. Specify either a name, an index, or an instance of a controller object."""
        return self._controllerList.delete(controller)

    def getController(self, description):
        """Returns a controller. Specify either a name, an index. Anything else will be returned unmodified."""
        return self._controllerList.get(description)

    def getControllerCount(self):
        """Returns the number of controllers."""
        return self._controllerList.getCount()

    def getControllerList(self):
        """Returns the controller list object. Useful for observation."""
        return self._controllerList

    def addCurve(self, name, trajectory1d, phiPtr=None):
        """Adds a curve to the application"""
        return self._curveList.add(Curve(name, trajectory1d, phiPtr))

    def deleteCurve(self, curve):
        """Removes a curve from the application. Specify either a name, an index, or an instance of a controller object."""
        return self._curveList.delete(curve)

    def clearCurves(self):
        """Remove all the curves from the application."""
        self._curveList.clear()

    def getCurve(self, description):
        """Returns a curve. Specify either a name, an index. Anything else will be returned unmodified."""
        return self._curveList.get(description)

    def getCurveCount(self):
        """Returns the number of curves."""
        return self._curveList.getCount()

    def getCurveList(self):
        """Returns the curve list object. Useful for observation."""
        return self._curveList

    def getSnapshotTree(self):
        """Returns the top-level SnapshotBranch that can be observed."""
        return self._snapshotTree

    def takeSnapshot(self):
        """Take a snapshot of the world.
        The snapshot will be returned and added to the snapshot tree."""
        return self._snapshotTree.takeSnapshot()

    def restoreActiveSnapshot(self, restoreControllerParams=True):
        """Restores the current snapshot. Return it."""
        return self._snapshotTree.restoreActive(restoreControllerParams)

    def previousSnapshot(self, restoreControllerParams=True):
        """Navigate to the previous snapshot. Return it, or None if failed."""
        return self._snapshotTree.previousSnapshot(restoreControllerParams)

    def nextSnapshot(self, restoreControllerParams=True):
        """Navigate to the next snapshot. Return it, or None if failed."""
        return self._snapshotTree.nextSnapshot(restoreControllerParams)

    def deleteAllSnapshots(self):
        """Delete all the snapshots of the world."""
        self._snapshotTree = SnapshotBranch()

    def setCOMX(self, val):
        if len(self._characters) > 0:
            self._characters[0].COM_offset.x = val

    def getCOMX(self):
        if len(self._characters) > 0:
            return self._characters[0].COM_offset.x
        else:
            return 0

    def setCOMY(self, val):
        if len(self._characters) > 0:
            self._characters[0].COM_offset.y = val

    def getCOMY(self):
        if len(self._characters) > 0:
            return self._characters[0].COM_offset.y
        else:
            return 0

    def setCOMZ(self, val):
        if len(self._characters) > 0:
            self._characters[0].COM_offset.z = val

    def getCOMZ(self):
        if len(self._characters) > 0:
            return self._characters[0].COM_offset.z
        else:
            return 0

    #
    # For observers
    #
    def addCharacterObserver(self, observer):
        self._characterObservable.addObserver(observer)

    def deleteCharacterObserver(self, observer):
        self._characterObservable.deleteObserver(observer)

    def addControllerObserver(self, observer):
        self._controllerList.addObserver(observer)

    def deleteControllerObserver(self, observer):
        self._controllerList.deleteObserver(observer)

    def addAnimationObserver(self, observer):
        self._animationObservable.addObserver(observer)

    def deleteAnimationObserver(self, observer):
        self._animationObservable.deleteObserver(observer)

    def addCameraObserver(self, observer):
        self._cameraObservable.addObserver(observer)

    def deleteCameraObserver(self, observer):
        self._cameraObservable.deleteObserver(observer)

    def addOptionsObserver(self, observer):
        self._optionsObservable.addObserver(observer)

    def deleteOptionsObserver(self, observer):
        self._optionsObservable.deleteObserver(observer)

    def addCOMObserver(self, observer):
        self._COMObservable.addObserver(observer)

    def deleteCOMObserver(self, observer):
        self._COMObservable.deleteObserver(observer)
def ol(onchange):
    """The observable list."""
    ol_ = ObservableList()
    ol_.register_observer(onchange)
    return ol_
Ejemplo n.º 12
0
    def __init__(self,
                 appTitle="Simbicon Application",
                 fps=30.0,
                 dt=1 / 2000.0,
                 glCanvasSize=wx.DefaultSize,
                 size=wx.DefaultSize,
                 redirect=False,
                 filename=None,
                 useBestVisual=False,
                 clearSigInt=True,
                 showConsole=True):
        """
        appTitle is the window title
        fps is the desired number of frames per seconds
        dt is the desired simulation timestep
        :see: wx.BasicApp.__init__`
        """

        wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)

        # No annoying error logging window
        wx.Log.SetActiveTarget(wx.LogStderr())

        import UI

        # Setup the main window style
        style = wx.DEFAULT_FRAME_STYLE
        if size == wx.DefaultSize:
            size = wx.GetDisplaySize()
            size.height *= 0.75
            size.width *= 0.75
            if glCanvasSize == wx.DefaultSize:
                style |= wx.MAXIMIZE

        # Setup the environment for the python interactive console
        consoleEnvironment = {"wx": wx, "Physics": Physics, "Utils": Utils}
        exec "from MathLib import *\n" + \
             "app = wx.GetApp()\n" + \
             "from PyUtils import load" in consoleEnvironment, consoleEnvironment

        # Create the main window
        self._frame = UI.MainWindow(None,
                                    -1,
                                    appTitle,
                                    size=size,
                                    style=style,
                                    fps=fps,
                                    glCanvasSize=glCanvasSize,
                                    showConsole=showConsole,
                                    consoleEnvironment=consoleEnvironment)

        # Define GL callbacks
        self._glCanvas = self._frame.getGLCanvas()
        self._glCanvas.addDrawCallback(self.draw)
        self._glCanvas.addPostDrawCallback(self.postDraw)
        self._glCanvas.addOncePerFrameCallback(self.advanceAnimation)
        self._glCanvas.setDrawAxes(False)
        self._glCanvas.setPrintLoad(True)
        self._glCanvas.setCameraTargetFunction(self.cameraTargetFunction)

        # Get the tool panel
        self._toolPanel = self._frame.getToolPanel()

        # Show the application
        self._frame.Show()

        # Set-up starting state
        self._dt = dt
        self._drawShadows = True
        self._simulationSecondsPerSecond = 1  # 1 = real time, 2 = twice real time, 1/2 = half real time
        self._animationRunning = False
        self._cameraFollowCharacter = False
        self._drawCollisionVolumes = False
        self._followedCharacter = None  # Pointer to focused character
        self._captureScreenShots = False
        self._printStepReport = True
        self._screenShotNumber = 0
        self._worldOracle = Core.WorldOracle()
        self._worldOracle.initializeWorld(Physics.world())
        self._kinematicMotion = False

        # Set-up starting list of characters and controllers
        self._characters = []

        # Define the observables
        self._controllerList = ObservableList()
        self._characterObservable = PyUtils.Observable()
        self._animationObservable = PyUtils.Observable()
        self._cameraObservable = PyUtils.Observable()
        self._optionsObservable = PyUtils.Observable()
        self._curveList = ObservableList()
        self._snapshotTree = SnapshotBranch()
Ejemplo n.º 13
0
class SNMApp(wx.App):
    """A simple class that should handle almost everything a simbicon application typically needs."""
    def __init__(self,
                 appTitle="Simbicon Application",
                 fps=30.0,
                 dt=1 / 2000.0,
                 glCanvasSize=wx.DefaultSize,
                 size=wx.DefaultSize,
                 redirect=False,
                 filename=None,
                 useBestVisual=False,
                 clearSigInt=True,
                 showConsole=True):
        """
        appTitle is the window title
        fps is the desired number of frames per seconds
        dt is the desired simulation timestep
        :see: wx.BasicApp.__init__`
        """

        wx.App.__init__(self, redirect, filename, useBestVisual, clearSigInt)

        # No annoying error logging window
        wx.Log.SetActiveTarget(wx.LogStderr())

        import UI

        # Setup the main window style
        style = wx.DEFAULT_FRAME_STYLE
        if size == wx.DefaultSize:
            size = wx.GetDisplaySize()
            size.height *= 0.75
            size.width *= 0.75
            if glCanvasSize == wx.DefaultSize:
                style |= wx.MAXIMIZE

        # Setup the environment for the python interactive console
        consoleEnvironment = {"wx": wx, "Physics": Physics, "Utils": Utils}
        exec "from MathLib import *\n" + \
             "app = wx.GetApp()\n" + \
             "from PyUtils import load" in consoleEnvironment, consoleEnvironment

        # Create the main window
        self._frame = UI.MainWindow(None,
                                    -1,
                                    appTitle,
                                    size=size,
                                    style=style,
                                    fps=fps,
                                    glCanvasSize=glCanvasSize,
                                    showConsole=showConsole,
                                    consoleEnvironment=consoleEnvironment)

        # Define GL callbacks
        self._glCanvas = self._frame.getGLCanvas()
        self._glCanvas.addDrawCallback(self.draw)
        self._glCanvas.addPostDrawCallback(self.postDraw)
        self._glCanvas.addOncePerFrameCallback(self.advanceAnimation)
        self._glCanvas.setDrawAxes(False)
        self._glCanvas.setPrintLoad(True)
        self._glCanvas.setCameraTargetFunction(self.cameraTargetFunction)

        # Get the tool panel
        self._toolPanel = self._frame.getToolPanel()

        # Show the application
        self._frame.Show()

        # Set-up starting state
        self._dt = dt
        self._drawShadows = True
        self._simulationSecondsPerSecond = 1  # 1 = real time, 2 = twice real time, 1/2 = half real time
        self._animationRunning = False
        self._cameraFollowCharacter = False
        self._drawCollisionVolumes = False
        self._followedCharacter = None  # Pointer to focused character
        self._captureScreenShots = False
        self._printStepReport = True
        self._screenShotNumber = 0
        self._worldOracle = Core.WorldOracle()
        self._worldOracle.initializeWorld(Physics.world())
        self._kinematicMotion = False

        # Set-up starting list of characters and controllers
        self._characters = []

        # Define the observables
        self._controllerList = ObservableList()
        self._characterObservable = PyUtils.Observable()
        self._animationObservable = PyUtils.Observable()
        self._cameraObservable = PyUtils.Observable()
        self._optionsObservable = PyUtils.Observable()
        self._curveList = ObservableList()
        self._snapshotTree = SnapshotBranch()

    #
    # Private methods

    def draw(self):
        """Draw the content of the world"""
        world = Physics.world()

        glEnable(GL_LIGHTING)
        if self._drawCollisionVolumes:
            world.drawRBs(Physics.SHOW_MESH | Physics.SHOW_CD_PRIMITIVES)
        else:
            world.drawRBs(Physics.SHOW_MESH | Physics.SHOW_COLOURS)
#        world.drawRBs(Physics.SHOW_MESH|Physics.SHOW_CD_PRIMITIVES)
        glDisable(GL_LIGHTING)

        if self._drawShadows:
            self._glCanvas.beginShadows()
            world.drawRBs(Physics.SHOW_MESH)
            self._glCanvas.endShadows()

    def postDraw(self):
        """Perform some operation once the entire OpenGL window has been drawn"""
        if self._captureScreenShots:
            self._glCanvas.saveScreenshot("../screenShots/%04d.bmp" %
                                          self._screenShotNumber)
            self._screenShotNumber += 1

    def advanceAnimation(self):
        """Called once per frame"""
        if self._animationRunning:
            self.simulationFrame()

    def simulationFrame(self):
        """Performs enough simulation steps to fill one frame"""

        # Enough time elapsed perform simulation loop and render
        simulationSeconds = 1.0 / self._glCanvas.getFps(
        ) * self._simulationSecondsPerSecond
        nbSteps = int(math.ceil(simulationSeconds / self._dt))

        for i in range(0, nbSteps):
            self.simulationStep()

    def advanceAnimationUntilControllerEnds(self, controller):
        """Advances the animation until the specified controller reaches the end.
        Specify either a name, an index, or an instance of a controller object."""
        controller = self.getController(controller)
        initialPhi = controller.getPhase()
        currPhi = initialPhi + 1
        while currPhi > initialPhi:
            self.simulationStep()
            currPhi = controller.getPhase()

    def simulationStep(self):
        """Performs a single simulation step"""

        # TODO Quite hacky
        if self._kinematicMotion:
            import KeyframeEditor
            from MathLib import Trajectory3dv
            try:
                pc = self._posableCharacter
                traj = self._stanceFootToSwingFootTrajectory
            except AttributeError:
                pc = self._posableCharacter = KeyframeEditor.PosableCharacter.PosableCharacter(
                    self.getCharacter(0), self.getController(0))
                traj = self._stanceFootToSwingFootTrajectory = Trajectory3dv()
                traj.addKnot(0, Vector3d(-0.13, 0, -0.4))
                traj.addKnot(0.5, Vector3d(-0.13, 0.125, 0))
                traj.addKnot(1, Vector3d(-0.13, 0, 0.4))
                self._phase = 0
                self._stance = Core.LEFT_STANCE

            stanceToSwing = traj.evaluate_catmull_rom(self._phase)
            if self._stance == Core.RIGHT_STANCE:
                stanceToSwing.x = stanceToSwing.x * -1
            pc.updatePose(self._phase, stanceToSwing, self._stance, True)

            self._phase += 0.00069
            if self._phase >= 1.0:
                self._phase = 0
                if self._stance == Core.LEFT_STANCE:
                    self._stance = Core.RIGHT_STANCE
                else:
                    self._stance = Core.LEFT_STANCE
            return

        world = Physics.world()
        controllers = self._controllerList._objects
        contactForces = world.getContactForces()
        for controller in controllers:
            controller.performPreTasks(self._dt, contactForces)
        world.advanceInTime(self._dt)

        contactForces = world.getContactForces()
        for controller in controllers:
            if controller.performPostTasks(self._dt, contactForces):
                step = Vector3d(controller.getStanceFootPos(),
                                controller.getSwingFootPos())
                step = controller.getCharacterFrame().inverseRotate(step)
                v = controller.getV()
                phi = controller.getPhase()
                if self._printStepReport:
                    print "step: %3.5f %3.5f %3.5f. Vel: %3.5f %3.5f %3.5f  phi = %f" % (
                        step.x, step.y, step.z, v.x, v.y, v.z, phi)

    def cameraTargetFunction(self, currentTarget):
        """Private! Return the point to target, or None if nothing to target."""
        if not self._cameraFollowCharacter or self._followedCharacter == None:
            return None

        pos = self._followedCharacter.getRoot().getCMPosition()
        pos.y = currentTarget.y
        return pos

    #
    # Accessors

    def getWorldOracle(self):
        """Return the world oracle for the application."""
        return self._worldOracle

    def getFrame(self):
        """Returns the application frame."""
        return self._frame

    def setDrawShadows(self, drawShadows):
        """Indicates whether the app should draw shadows or not"""
        self._drawShadows = drawShadows

    def getDrawShadows(self):
        """Checks if the app is drawing shadows"""
        return self._drawShadows

    def getGLCanvas(self):
        """Returns the GL canvas"""
        return self._glCanvas

    def getToolPanel(self):
        """Returns the tool panel"""
        return self._toolPanel

    def setAnimationRunning(self, animationRunning):
        """Indicates whether the animation should run or not"""
        self._animationRunning = animationRunning
        self._animationObservable.notifyObservers()

    def isAnimationRunning(self):
        """Return true if the animation is currently running"""
        return self._animationRunning

    def setSimulationSecondsPerSecond(self, simulationSecondsPerSecond):
        """Sets the speed of the playback. 1 is realtime, 0.5 is slower, 2 is faster"""
        self._simulationSecondsPerSecond = simulationSecondsPerSecond
        self._animationObservable.notifyObservers()

    def getSimulationSecondsPerSecond(self):
        """Return the speed of the playback"""
        return self._simulationSecondsPerSecond

    def setCameraFollowCharacter(self, follow):
        """Indicates whether the camera should follow a character or not"""
        if follow != self._cameraFollowCharacter:
            # Need to toggle
            self._cameraFollowCharacter = follow
            if self._followedCharacter == None:
                try:
                    self._followedCharacter = self._characters[0]
                except IndexError:
                    pass
            self._cameraObservable.notifyObservers()

    def doesCameraFollowCharacter(self):
        """Checks if the camera is currently following a character."""
        return self._cameraFollowCharacter and self._followedCharacter != None

    def setFollowedCharacter(self, character):
        """Indicates which character the camera should be following. Pass an index of a string."""
        character = self.getCharacter(character)

        self._cameraFollowCharacter = True
        self._followedCharacter = character
        self._cameraObservable.notifyObservers()

    def setCameraAutoOrbit(self, autoOrbit):
        """Indicates whether the camera should automatically orbit or not"""
        self._glCanvas.setCameraAutoOrbit(autoOrbit)

    def doesCameraAutoOrbit(self):
        """Checks if the camera is currently automatically orbiting."""
        return self._glCanvas.doesCameraAutoOrbit()

    def drawCollisionVolumes(self, draw):
        """Indicates whether the application should draw collision volumes"""
        if draw != self._drawCollisionVolumes:
            self._drawCollisionVolumes = draw
            self._optionsObservable.notifyObservers()

    def getDrawCollisionVolumes(self):
        """Does the application draw collision volumes?"""
        return self._drawCollisionVolumes

    def setKinematicMotion(self, kinematicMotion):
        """Indicates whether the application should animate only kinematic motion"""
        if kinematicMotion != self._kinematicMotion:
            self._kinematicMotion = kinematicMotion
            self._optionsObservable.notifyObservers()

    def getKinematicMotion(self):
        """Does the application animate only kinematic motion?"""
        return self._kinematicMotion

    def captureScreenShots(self, capture):
        """Indicates whether the application should capture a screenshot at every frame."""
        if capture != self._captureScreenShots:
            self._captureScreenShots = capture
            self._optionsObservable.notifyObservers()

    def getCaptureScreenShots(self):
        """Does the application capture a screenshot at every frame?"""
        return self._captureScreenShots

    #
    # Public methods

    def deleteAllObjects(self):
        """Delete all objects: characters, rigid bodies, snapshots, etc."""
        if self._followedCharacter is not None:
            self._followedCharacter = None
            self._cameraFollowCharacter = False
            self._cameraObservable.notifyObservers()
        self._characters = []
        self._controllerList.clear()
        import Physics
        Physics.world().destroyAllObjects()
        self.deleteAllSnapshots()

    def addCharacter(self, character):
        """Adds a character to the application and the world"""
        import Physics
        if PyUtils.sameObjectInList(character, self._characters):
            raise KeyError(
                'Cannot add the same character twice to application.')
        Physics.world().addArticulatedFigure(character)
        self._characters.append(character)
        if self._followedCharacter is None:
            self._followedCharacter = character
            self._cameraFollowCharacter = True
            self._cameraObservable.notifyObservers()
        self._characterObservable.notifyObservers()

    def deleteCharacter(self, character):
        """Removes a character from the application. Specify either a name, an index, or an instance of a character object."""
        character = self.getCharacter(character)
        if self._followedCharacter is character:
            self._followedCharacter = None
            self._cameraFollowCharacter = False
            self._cameraObservable.notifyObservers()
        self._characters.remove(character)
        self._characterObservable.notifyObservers()

    def getCharacter(self, description):
        """Returns a character. Specify either a name, an index. Anything else will be returned unmodified."""
        if isinstance(description, basestring):
            try:
                description = [char.getName()
                               for char in self._characters].index(description)
            except ValueError:
                raise ValueError("No character found with the specified name.")
        if isinstance(description, int):
            return self._characters[description]
        return description

    def getCharacterCount(self):
        """Returns the number of characters."""
        return len(self._character)

    def recenterCharacter(self, character):
        """Reposition the character at the center of the world in X,Z. Specify either a name, an index, or an instance of a character object."""
        character = self.getCharacter(character)
        character.recenter()

    def addController(self, controller):
        """Adds a controller to the application"""
        return self._controllerList.add(controller)

    def deleteController(self, controller):
        """Removes a controller from the application. Specify either a name, an index, or an instance of a controller object."""
        return self._controllerList.delete(controller)

    def getController(self, description):
        """Returns a controller. Specify either a name, an index. Anything else will be returned unmodified."""
        return self._controllerList.get(description)

    def getControllerCount(self):
        """Returns the number of controllers."""
        return self._controllerList.getCount()

    def getControllerList(self):
        """Returns the controller list object. Useful for observation."""
        return self._controllerList

    def addCurve(self, name, trajectory1d, phiPtr=None):
        """Adds a curve to the application"""
        return self._curveList.add(Curve(name, trajectory1d, phiPtr))

    def deleteCurve(self, curve):
        """Removes a curve from the application. Specify either a name, an index, or an instance of a controller object."""
        return self._curveList.delete(curve)

    def clearCurves(self):
        """Remove all the curves from the application."""
        self._curveList.clear()

    def getCurve(self, description):
        """Returns a curve. Specify either a name, an index. Anything else will be returned unmodified."""
        return self._curveList.get(description)

    def getCurveCount(self):
        """Returns the number of curves."""
        return self._curveList.getCount()

    def getCurveList(self):
        """Returns the curve list object. Useful for observation."""
        return self._curveList

    def getSnapshotTree(self):
        """Returns the top-level SnapshotBranch that can be observed."""
        return self._snapshotTree

    def takeSnapshot(self):
        """Take a snapshot of the world.
        The snapshot will be returned and added to the snapshot tree."""
        return self._snapshotTree.takeSnapshot()

    def restoreActiveSnapshot(self, restoreControllerParams=True):
        """Restores the current snapshot. Return it."""
        return self._snapshotTree.restoreActive(restoreControllerParams)

    def previousSnapshot(self, restoreControllerParams=True):
        """Navigate to the previous snapshot. Return it, or None if failed."""
        return self._snapshotTree.previousSnapshot(restoreControllerParams)

    def nextSnapshot(self, restoreControllerParams=True):
        """Navigate to the next snapshot. Return it, or None if failed."""
        return self._snapshotTree.nextSnapshot(restoreControllerParams)

    def deleteAllSnapshots(self):
        """Delete all the snapshots of the world."""
        self._snapshotTree = SnapshotBranch()

    #
    # For observers
    #
    def addCharacterObserver(self, observer):
        self._characterObservable.addObserver(observer)

    def deleteCharacterObserver(self, observer):
        self._characterObservable.deleteObserver(observer)

    def addControllerObserver(self, observer):
        self._controllerList.addObserver(observer)

    def deleteControllerObserver(self, observer):
        self._controllerList.deleteObserver(observer)

    def addAnimationObserver(self, observer):
        self._animationObservable.addObserver(observer)

    def deleteAnimationObserver(self, observer):
        self._animationObservable.deleteObserver(observer)

    def addCameraObserver(self, observer):
        self._cameraObservable.addObserver(observer)

    def deleteCameraObserver(self, observer):
        self._cameraObservable.deleteObserver(observer)

    def addOptionsObserver(self, observer):
        self._optionsObservable.addObserver(observer)

    def deleteOptionsObserver(self, observer):
        self._optionsObservable.deleteObserver(observer)
Ejemplo n.º 14
0
                        pitch, yaw = calcRotation(skele.coords)
                        ks.send_coords(pitch, yaw)
                        ks.shoot()
                print("shot everyone")
            else:
                if alexa_cmd in known_face_names:  # fuzzy search probably
                    print("shot" + alexa_cmd)
                    # do laterrrr

            # hot keys
            if cv2.waitKey(1) & 0xFF == ord('q'):  # q quit application
                run = False
            if cv2.waitKey(1) & 0xFF == ord(' '):  # space bar resets skeletons
                reset_skeletons_array()

        kinect.close()

        print("Exiting")


# initialize skeletons_array
skeletons_array = ObservableList()
reset_skeletons_array()
argDict = {
    "show_video": True,
    "recognize_faces": False,
}

if __name__ == "__main__":
    main_loop(argDict)