Esempio n. 1
0
	def __init__(self, robotName):
		self.gazeboModelStater = GazeboModelStater()
		self.path = []
		self.cPathI = 0
		self.lookAhead = 1.5
		self.errorMultiplier = 1
		self.robotName = robotName
Esempio n. 2
0
	def __init__(self, robotName):
		self.gazeboModelStater = GazeboModelStater()
		self.path = []
		self.lookAhead = 1.5
		self.errorMultiplier = 1
		self.currentSegment = (-1,-1)
		self.robotName = robotName
Esempio n. 3
0
class DroneController():
	def __init__(self, robotName):
		self.gazeboModelStater = GazeboModelStater()
		self.pathPoses = []
		self.pathNames = []
		self.lookAhead = 1.5
		self.errorMultiplier = 1
		self.currentSegment = (-1,-1)
		self.robotName = robotName

	def addUpdateCallback(self, callback):
		self.gazeboModelStater.addUpdateCallback(callback)

	def setPath(self, path):
		self.pathNames = path
		self.pathPoses = getPathFromRings(self.gazeboModelStater, self.robotName, path)

	def getDroneState(self):
		return self.gazeboModelStater.get(self.robotName)

	def getClosestLineSegment(self, p):
		currentDist, currentProj = distToSegment2(self.pathPoses[self.currentSegment[0]],self.pathPoses[self.currentSegment[1]],p)
		for i in range(2):
			#start at the current position and look forward
			index1 = self.addToIndex(self.currentSegment[0], i)
			index2 = self.addToIndex(index1, 1)

			a = self.pathPoses[index1]
			b = self.pathPoses[index2]

			distance, projected = distToSegment2(a,b,p)
			if distance < currentDist:
				return (index1,index2), distance, projected
		return self.currentSegment, currentDist, currentProj

	def isForward(self, yaw, currentSegment):
		a = self.pathPoses[currentSegment[0]]
		b = self.pathPoses[currentSegment[1]]

		dir = [math.cos(yaw), math.sin(yaw)]

		dp = dot(dir,sub(b,a))
		if dp > 0:
			return True
		else:
			return False

	def getControlInfo(self):
		currentPose, currentTwist = self.getDroneState()
		if not currentPose or not self.pathPoses:
			return None, None, None, None
		pos = [currentPose.position.x, currentPose.position.y]
		pitch, roll, yaw = euler_from_quaternion([currentPose.orientation.x, currentPose.orientation.y, currentPose.orientation.z, currentPose.orientation.w])

		#calculate where we are on the path, and where we should be
		currentSegment, posErr, projected = self.getClosestLineSegment(pos)
		self.currentSegment = currentSegment
		#are we facing forward
		isForward = self.isForward(yaw, currentSegment)

		#calculate where we should drive too
		i = currentSegment[0]
		j = currentSegment[1]
		a = self.pathPoses[i]
		b = self.pathPoses[j]


		#if isForward:
		dirMult = 1 #always drive forward
		#else:
		#	dirMult = -1

		remainingLookAhead = self.lookAhead
		while remainingLookAhead > 0.01:
			follow = add(projected,scale(normalize(sub(b,a)),dirMult*remainingLookAhead))
			remainingLookAhead, projected = distToSegment2(a,b,follow)

			i = self.addToIndex(i, dirMult)
			j = self.addToIndex(j, dirMult)
			a = self.pathPoses[i]
			b = self.pathPoses[j]

		positionError = sub(follow,pos)
		targetYaw = math.atan2(positionError[1], positionError[0])
		angleError = targetYaw - yaw

		while angleError > math.pi:
			angleError -= 2*math.pi
		while angleError < -math.pi:
			angleError += 2*math.pi
		angleError *= self.errorMultiplier

		segmentNames = (self.pathNames[currentSegment[0]], self.pathNames[currentSegment[1]])
		return angleError, posErr, segmentNames, isForward

	def addToIndex(self, index, add):
		newi = index + add
		if newi < 0:
			newi += len(self.pathPoses)
		else:
			newi = newi % len(self.pathPoses)
		return newi
Esempio n. 4
0
class DroneController():
	def __init__(self, robotName):
		self.gazeboModelStater = GazeboModelStater()
		self.path = []
		self.cPathI = 0
		self.lookAhead = 1.5
		self.errorMultiplier = 1
		self.robotName = robotName

	def addUpdateCallback(self, callback):
		self.gazeboModelStater.addUpdateCallback(callback)

	def setPath(self, path):
		self.path = getPathFromRings(self.gazeboModelStater, self.robotName, path)

	def getDroneState(self):
		return self.gazeboModelStater.get(self.robotName)

	def getPathIndex(self):
		return self.cPathI

	def getPositionError(self):
		currentPose, currentTwist = self.gazeboModelStater.get(self.robotName)
		if not currentPose:
			return 0

		robotCoord = [currentPose.position.x, currentPose.position.y]

		#calculate path index
		while True:
			indexback = self.subIndex(self.cPathI)
			index = self.cPathI
			indexfront = self.addIndex(self.cPathI)

			if isPassed(robotCoord, self.path[index], self.path[indexback], self.path[indexfront]):
				self.cPathI = self.addIndex(self.cPathI)
			else:
				break
	
		cPathI1 = self.addIndex(self.cPathI)
	
		dirVect = normalize(add(self.path[cPathI1], neg(self.path[self.cPathI])))
		projection = getProjection(robotCoord, self.path[self.cPathI], dirVect)
		posError = math.sqrt(distance2(robotCoord, projection))
		return posError

	def getAngleError(self):
		currentPose, currentTwist = self.gazeboModelStater.get(self.robotName)
		if not currentPose:
			return 0

		robotCoord = [currentPose.position.x, currentPose.position.y]
		quaternionArray = [currentPose.orientation.x, currentPose.orientation.y, currentPose.orientation.z, currentPose.orientation.w]
		roll, pitch, robotYaw = euler_from_quaternion(quaternionArray)

		#calculate path index
		while True:
			indexback = self.subIndex(self.cPathI)
			index = self.cPathI
			indexfront = self.addIndex(self.cPathI)

			if isPassed(robotCoord, self.path[index], self.path[indexback], self.path[indexfront]):
				self.cPathI = self.addIndex(self.cPathI)
			else:
				break
	
		cPathI1 = self.addIndex(self.cPathI)
	
		dirVect = normalize(add(self.path[cPathI1], neg(self.path[self.cPathI])))
		projection = getProjection(robotCoord, self.path[self.cPathI], dirVect)
		followPoint = add(projection, scale(dirVect, self.lookAhead))

		#ensure follow point remains on path, could be adding lookAhead directs it away from next path coords
		followI = self.cPathI
		while True:
			index1 = self.addIndex(followI)

			segLen2 = distance2(self.path[followI], self.path[index1])
			followLen2 = distance2(self.path[followI], followPoint)
			if followLen2 > segLen2:
				#should place it to the next segment
				index2 = self.addIndex(index1)
				extraLen = math.sqrt(followLen2) - math.sqrt(segLen2)
				dirVect = normalize(add(self.path[index2], neg(self.path[index1])))
				followPoint = add(self.path[index1], scale(dirVect, extraLen))
				followI = index1
			else:
				break

		positionError = add(neg(robotCoord), followPoint)
		targetYaw = math.atan2(positionError[1], positionError[0])
		angleError = targetYaw - robotYaw

		while angleError > math.pi:
			angleError -= 2*math.pi
		while angleError < -math.pi:
			angleError += 2*math.pi
		return angleError * self.errorMultiplier

	def subIndex(self, index):
		newi = index - 1
		if newi < 0:
			newi = newi + len(self.path)
		return newi

	def addIndex(self, index):
		newi = (index + 1) % len(self.path)
		return newi
Esempio n. 5
0
class DroneController():
	def __init__(self, robotName):
		self.gazeboModelStater = GazeboModelStater()
		self.path = []
		self.lookAhead = 1.5
		self.errorMultiplier = 1
		self.currentSegment = (-1,-1)
		self.robotName = robotName

	def addUpdateCallback(self, callback):
		self.gazeboModelStater.addUpdateCallback(callback)

	def setPath(self, path):
		self.path = getPathFromRings(self.gazeboModelStater, self.robotName, path)

	def getDroneState(self):
		return self.gazeboModelStater.get(self.robotName)

	def getClosestLineSegment(self, p):
		closestDist = 99999
		closestSegment = (-1,-1)
		closestProjected = [0,0]
		shortestJump = 999999
		for i in range(len(self.path)):
			j = self.addToIndex(i,1)

			a = self.path[i]
			b = self.path[j]

			jump = abs(i-self.currentSegment[0])
			jumpFromLastSegment = min(jump, abs(jump-len(self.path)))

			distance, projected = distToSegment2(a,b,p)
			if distance < closestDist:
				if closestDist-distance > 1 or jumpFromLastSegment < shortestJump:
					closestDist = distance
					closestSegment = (i,j)
					closestProjected = projected
					shortestJump = jumpFromLastSegment

		return closestSegment, closestDist, closestProjected

	def isForward(self, yaw, currentSegment):
		a = self.path[currentSegment[0]]
		b = self.path[currentSegment[1]]

		dir = [math.cos(yaw), math.sin(yaw)]

		dp = dot(dir,sub(b,a))
		if dp > 0:
			return True
		else:
			return False

	def getControlInfo(self):
		currentPose, currentTwist = self.gazeboModelStater.get(self.robotName)
		if not currentPose:
			return 0
		pos = [currentPose.position.x, currentPose.position.y]
		pitch, roll, yaw = euler_from_quaternion([currentPose.orientation.x, currentPose.orientation.y, currentPose.orientation.z, currentPose.orientation.w])

		#calculate where we are on the path, and where we should be
		currentSegment, posErr, projected = self.getClosestLineSegment(pos)
		self.currentSegment = currentSegment
		#are we facing forward
		isForward = self.isForward(yaw, currentSegment)

		#calculate where we should drive too
		i = currentSegment[0]
		j = currentSegment[1]
		a = self.path[i]
		b = self.path[j]

		if isForward:
			dirMult = 1
		else:
			dirMult = -1

		remainingLookAhead = self.lookAhead
		while remainingLookAhead > 0.01:
			follow = add(projected,scale(normalize(sub(b,a)),dirMult*remainingLookAhead))
			remainingLookAhead, projected = distToSegment2(a,b,follow)

			i = self.addToIndex(i, dirMult)
			j = self.addToIndex(j, dirMult)
			a = self.path[i]
			b = self.path[j]

		positionError = sub(follow,pos)
		targetYaw = math.atan2(positionError[1], positionError[0])
		angleError = targetYaw - yaw

		while angleError > math.pi:
			angleError -= 2*math.pi
		while angleError < -math.pi:
			angleError += 2*math.pi
		angleError *= self.errorMultiplier
		return angleError, posErr, currentSegment, isForward

	def addToIndex(self, index, add):
		newi = index + add
		if newi < 0:
			newi += len(self.path)
		else:
			newi = newi % len(self.path)
		return newi