예제 #1
0
 def __init__(self, name, clientID, sensorHandle, bodyHandle):
     '''
     Constructor
     '''
     self.resetParameters()
     controller = ActionValueTable(150, 5)   # pyBrain
     controller.initialize(1.)               # pyBrain
     learner = Q()                           # pyBrain
     self.__mind=AgentMind(controller, learner)  # with pyBrain
     self.__controller=controller
     self.__name=name
     self.__clientID=clientID          # Client ID of the Dummy object
     self.__sensorHandle=sensorHandle  # Proximity sensor handle of the V-Rep agent
     self.__bodyHandle=bodyHandle      # BubbleRob body handle
     self.__mind.setInput("name", name)
     self.__pybrainEnvironment = LocomotionEnvironment()
     self.__pybrainTask = LocomotionTask(self.__pybrainEnvironment)
예제 #2
0
class VRepAgent(VRepObject):
    '''
    classdocs
    '''
    __DistanceSalienceAttenuationCoefficient=-1.0
    ItemContactLimit=0.15
    ItemNearLimit=0.4
    ItemDirectionAhead=0.1
    BlockJudgeCount=200
    RelativeTranslation=0.0005
    DirectionAhead=0.01
    RefractoryPeriod=500

    def __init__(self, name, clientID, sensorHandle, bodyHandle):
        '''
        Constructor
        '''
        self.resetParameters()
        controller = ActionValueTable(150, 5)   # pyBrain
        controller.initialize(1.)               # pyBrain
        learner = Q()                           # pyBrain
        self.__mind=AgentMind(controller, learner)  # with pyBrain
        self.__controller=controller
        self.__name=name
        self.__clientID=clientID          # Client ID of the Dummy object
        self.__sensorHandle=sensorHandle  # Proximity sensor handle of the V-Rep agent
        self.__bodyHandle=bodyHandle      # BubbleRob body handle
        self.__mind.setInput("name", name)
        self.__pybrainEnvironment = LocomotionEnvironment()
        self.__pybrainTask = LocomotionTask(self.__pybrainEnvironment)
   
    def resetParameters(self):
        self.__velocity=0.0        # m/s
        self.__linearVelocity=None # vector
        self.__angularVelocity=0.0 # radian/s
        self.__orientation=None    # π radian
        self.__steering=0.0        # Steering value [-1,1]
        self.__thrust=1.0          # Accelerator value [-1,1]
        self.__emotion=0
        self.__position=None
        self.__initLoop=True
        self.__perceivedItems={}
        self.__perceivedAgents={}
        self.__driveBackStartTime=-99000
        self.__firstOrientation=None
        self.__cnt=0
        self.__carryingDirection = 0
        self.__thrustIntegral=0.0
        self.__thrustHistory = [0]*self.BlockJudgeCount
        self.__positionHistory = [[0.0,0.0]]*self.BlockJudgeCount   # May cause a bug
        self.__prevMostSalientDistance = 3  # 100000.0
        self.__blocked=False
        self.__prevMostSalient=None
        self.__prevApproachingRewardCnt=-1*VRepAgent.RefractoryPeriod
        
    def getName(self):
        return self.__name

    def getType(self):
        return "Agent"

    def observe(self):
        operationMode=vrep.simx_opmode_streaming
        if self.__initLoop:
            self.__initLoop=False
        else:
            operationMode=vrep.simx_opmode_buffer
        returnCode, orientation = vrep.simxGetObjectOrientation(self.__clientID, self.__bodyHandle, -1, operationMode)
        if returnCode==vrep.simx_return_ok:
            self.__orientation=orientation[2]
        else:
            self.__orientation = None
            # print >> sys.stderr, "Error in VRepBubbleRob.getOrientation()"
        self.__mind.setInput("orientation", self.__orientation)
        returnCode, position = vrep.simxGetObjectPosition(self.__clientID, self.__bodyHandle, -1, operationMode)
        if returnCode==vrep.simx_return_ok:
            self.__position=[0.0,0.0]
            self.__position[0]=position[0]  #X
            self.__position[1]=position[1]  #Y
        else:
            self.__position=None
            print >> sys.stderr, "Error in VRepBubbleRob.getPosition()",  self.__clientID, self.__bodyHandle
        returnCode, linearVelocity, angularVelocity = vrep.simxGetObjectVelocity(self.__clientID, self.__bodyHandle, operationMode)
        if returnCode==vrep.simx_return_ok:
            try:
                # self.__velocity=linearVelocity[0]*math.cos(self.__orientation)+linearVelocity[1]*math.sin(self.__orientation)
                self.__velocity=math.sqrt(linearVelocity[0]**2+linearVelocity[1]**2)
                self.__mind.setInput("velocity", self.__velocity)
                self.__linearVelocity=linearVelocity
            except TypeError:
                pass
                # if self.__name=="BubbleRob#1":
                #    print self.__velocity, linearVelocity[0], math.cos(self.__orientation), linearVelocity[1], math.sin(self.__orientation)
        else:
            self.__velocity=None
            # print >> sys.stderr, "Error in VRepBubbleRob.getVelocity()"
        returnCode, sensorTrigger, dp, doh, dsnv = vrep.simxReadProximitySensor(self.__clientID, self.__sensorHandle, operationMode)
        if returnCode==vrep.simx_return_ok:
            # We succeeded at reading the proximity sensor
            self.__mind.setInput("lastProximitySensorTime", vrep.simxGetLastCmdTime(self.__clientID))
            self.__mind.setInput("sensorTrigger", sensorTrigger)
        self.blocked()  # judge if blocked

    def act(self):
        self.__pybrainObservation() # integerateObservation before getAction
        self.__mind.applyRules()
        self.__mind.setStates()
        self.output()
        # increment counter
        self.__cnt=self.__cnt+1
            
    def output(self):
        if self.__mind.getOutput("steering")!=None:
            self.setSteering(self.__mind.getOutput("steering"))
        if self.__mind.getOutput("thrust")!=None:
            self.setThrust(self.__mind.getOutput("thrust"))
        if self.__mind.getOutput("reward")!=None:
            if self.__mind.getOutput("reward")>0.5:
                self.setEmotionalExpression(1)
            elif self.__mind.getOutput("reward")<-0.5:
                self.setEmotionalExpression(-1)
            else:
                self.setEmotionalExpression(0)
        getSignalReturnCode, dMessage = vrep.simxGetStringSignal(self.__clientID, "Debug", vrep.simx_opmode_streaming)
        if dMessage!="":
            print("Debug:"+dMessage)
        
    def setSteering(self, steering):
        # Steering value [-1,1]
        self.__steering = steering
        #if self.getName()=="BubbleRob#1":
        #    print self.getName(), steering
        vrep.simxSetFloatSignal(self.__clientID, self.__name+":Steering", self.__steering, vrep.simx_opmode_oneshot)
        # print self.__clientID, self.__name+":Steering", self.__steering
        
    def setThrust(self, thrust):
        # Average wheel speed
        self.__thrust = thrust
        vrep.simxSetFloatSignal(self.__clientID, self.__name+":Acceleration", self.__thrust, vrep.simx_opmode_oneshot)

    def getPosition(self):
        return self.__position

    def getOrientation(self):
        return self.__orientation
    
    def getVelocity(self):
        return self.__velocity

    def getAngularVelocity(self):
        return self.__angularVelocity
        # simxGetObjectVelocity

    def setEmotionalExpression(self, emotion):
        self.__emotion=emotion
        vrep.simxSetIntegerSignal(self.__clientID, self.__name+":Emotion", self.__emotion, vrep.simx_opmode_oneshot)
    
    def detectNearestItem(self):
        pass
        # return the id, direction, distance & features of the nearest item
    
    def setAttentionDirection(self, orientation):
        pass
    
    def setAttentionWidth(self, width):
        pass
    
    def setPerceivedAgents(self, agents):
        # set a list of perceived items
        self.__perceivedAgents=agents
        self.__visualSalience(agents)
        self.__mind.setInput("perceivedAgents", self.__perceivedAgents)

    def setPerceivedItems(self, items):
        # set a list of perceived items
        self.__perceivedItems=items
        self.__visualSalience(items)
        self.__mind.setInput("perceivedItems", self.__perceivedItems)

    def __visualSalience(self, objects):
        # give the score to perceived items
        for item in objects:
            score=0.0
            if item.has_key("direction") and item.has_key("distance"):
                direction=item["direction"]
                if -0.5*math.pi<direction and direction<0.5*math.pi:
                    # FOV: [-90,90] degrees
                    score=math.cos(direction)*math.exp(VRepAgent.__DistanceSalienceAttenuationCoefficient*item["distance"])
            item["score"]=score

    def __setCarryingReward(self, mostSalient):
        reward = 0
        # calculate reward of carrying the most salient item for the task
        if mostSalient!=None:
            velocityDirection = math.atan2(self.__linearVelocity[1], self.__linearVelocity[0])
            # TODO: normalization
            reward = math.cos(velocityDirection - self.__carryingDirection)
            # print "velocityDirection=",velocityDirection,"carryingD=", self.__carryingDirection, "RW=", reward
            # reward = self.__pybrainTask.getReward()
        return reward

    def __setItemLostFoundReward(self, mostSalient):
        reward = 0.0
        if mostSalient!=None and self.__prevMostSalient==None:
            reward=0.5
        if mostSalient==None and self.__prevMostSalient!=None:
            reward=-0.5
        self.__prevMostSalient=mostSalient
        return reward

    def __setApproachingReward(self, mostSalient):
        reward = 0.0
        distance = mostSalient["distance"]
        if distance!=None:
            if distance < self.__prevMostSalientDistance - 0.0015:
                reward = 0.5
            if self.__prevMostSalientDistance < distance - 0.0015:
                reward = -0.0
            #if reward!=0.0:
            #    print "setApproachingReward:", self.__name, reward, self.__prevMostSalientDistance-distance
            self.__prevMostSalientDistance = distance
        return reward

    def __setApproachingReward2(self, mostSalient):
        reward = 0.0
        distance = self.getMostSalientItemDistance(mostSalient)
        if self.__cnt-self.__prevApproachingRewardCnt>=VRepAgent.RefractoryPeriod:
            if distance < self.__prevMostSalientDistance:
                reward = 0.5
            elif self.__prevMostSalientDistance < distance:
                reward = -0.5
        if reward!=0:
            self.__prevApproachingRewardCnt=self.__cnt
        #    print "setApproachingReward:", self.__name, reward
        self.__prevMostSalientDistance = distance
        return reward

    def __setContactReward(self, mostSalient):
        reward = 0.0
        distance = self.getMostSalientItemDistance(mostSalient)
        if self.__cnt-self.__prevApproachingRewardCnt>=VRepAgent.RefractoryPeriod:
            if distance==0 and self.__prevMostSalientDistance==1:
                reward = 0.5
        if reward!=0:
            self.__prevApproachingRewardCnt=self.__cnt
        #    print "setApproachingReward:", self.__name, reward
        self.__prevMostSalientDistance = distance
        return reward

    def setRewards(self):
        mostSalientItem = self.__mind.getMostSalientItem()
        reward = 0.0 # self.__setItemLostFoundReward(mostSalientItem)
        if reward == 0.0:
            if mostSalientItem != None:
                reward = self.__setContactReward(mostSalientItem)
                # print "carryingReward, blocked", reward, self.getBlockedStatus()
        reward = reward - self.getBlockedStatus()
        if reward!=0:
            print "setReward:", self.__name, reward
        self.__mind.giveReward(reward)
        # if reward<0:
        #    print "setReward:", reward, self.__mind.history
    
    def pybrainLearn(self):
        self.__mind.learn() # episodes=1 by default
    
    def pybrainReset(self):
        self.__mind.reset()
    
    def setCarryingDirection(self, direction):
        print "setCarryingDirection:", direction 
        self.__carryingDirection = direction
    
    def __pybrainObservation(self):
        mostSalient=self.__mind.getMostSalientItem()
        self.__pybrainTask.setItemDistance(self.getMostSalientItemDistance(mostSalient))
        self.__pybrainTask.setItemDirection(self.getMostSalientItemDirection(mostSalient))
        self.__pybrainTask.setRelativeCarryingDirection(0) # self.getRelativeCarryingDirection())
        self.__pybrainTask.setBlockedStatus(self.getBlockedStatus())
        obs = self.__pybrainTask.getObservation()
        self.__mind.integrateObservation(obs)
        # if obs[0]!=0:
        #    print "Observation:", self.__mind.history

    def getMostSalientItemDistance(self, item):
        distance=2
        if item!=None and item.has_key("distance"):
            d = item["distance"]
            # print "getMostSalientItemDistance:", self.__name, d
            if d<self.ItemContactLimit:
                distance=0
            elif d<self.ItemNearLimit:
                distance=1
        return distance
    
    def getMostSalientItemDirection(self, item):
        direction=3 # out of sight
        if item!=None and item.has_key("direction"):
            d = item["direction"]
            direction=0
            if math.fabs(d)>self.DirectionAhead:
                if d>0:
                    if d<0.5*math.pi:
                        direction=2 # Left forward
                    else:
                        direction=3 # out of sight
                else:
                    if d>-0.5*math.pi:
                        direction=1 # Right forward
                    else:
                        direction=3 # out of sight
        # if self.__name=="BubbleRob#0":
        #    print "getMostSalientItemDirection:", self.__name, direction
        return direction
    
    def getRelativeCarryingDirection(self):
        direction=0
        if self.__orientation!=None and self.__carryingDirection!=None:
            d = self.__carryingDirection - self.__orientation
            if math.fabs(d)>self.DirectionAhead:
                if d>0:
                    if d<0.5*math.pi:
                        direction=2 # Left forward
                    else:
                        direction=4 # Left backward
                else:
                    if d>-0.5*math.pi:
                        direction=1 # Right forward
                    else:
                        direction=3 # Right backward
            # print "getRelativeCarryingDirection:", self.__name, direction
        return direction
    
    def getBlockedStatus(self):
        status = 0
        if self.__blocked:
            status = 1
        return status
    
    def blocked(self):
        # Judge blocked iff translation for a period is fractional relative to thrust integration
        self.__blocked = False
        pointer=self.__cnt % self.BlockJudgeCount
        pLast=(self.__cnt+1) % self.BlockJudgeCount
        self.__thrustHistory[pointer]=self.__thrust
        self.__thrustIntegral=self.__thrustIntegral+self.__thrust-self.__thrustHistory[pLast]
        self.__positionHistory[pointer]=self.__position
        if self.__cnt>=self.BlockJudgeCount and self.__thrustIntegral!=0.0 and self.__positionHistory[pLast]!=None:
            d = math.sqrt((self.__position[0]-self.__positionHistory[pLast][0])**2 + \
                          (self.__position[1]-self.__positionHistory[pLast][1])**2)
            if d/math.fabs(self.__thrustIntegral) < self.RelativeTranslation:
                self.__blocked = True
                print "blocked!", self.__name, d, self.__thrustIntegral, d/self.__thrustIntegral
    
    def getController(self):
        return self.__controller
    
    def getHistory(self):
        return self.__mind.history
    
    def getLastAction(self):
        return self.__mind.lastaction