def answer_server(self, req): gr = GuessResponse() gr.sender = self.name if not self.ready_to_publish: gr.no_data = True return gr gr.no_data = False self.guesser.handle_guess(req.points) gr.outPoints = self.guesser.pointList return gr
def answer_server(self, req): """ Provides a reply to a Guess service call. The Perfesser will call this after we've notified him that we have something worth saying about the robot's location. The call is simply passed into the bump_guess Guesser. """ gr = GuessResponse() gr.sender = self.name if self.guesser.handle_guess(req.inPoints): gr.no_data = False gr.outPoints = self.guesser.pointList gr.source_stamp = self.guesser.stamp gr.source_data = self.guesser.source_data else: gr.no_data = True return gr
def updateBelief(self, req): """ Takes a 'belief' object containing a set of points with a time stamp that indicate a location at some time in the past, and combines them with the Odometry messages received since then to formulate a new belief about where we are now. """ assert isinstance(req, GuessRequest) reply = GuessResponse() # Get the odometry messages since the source time recorded in # the request. More will be recorded soon. odoms = self.msmts.fromTime(req.source_stamp) # If there aren't enough odometry messages recorded, skip it. if len(odoms) < 2: reply.no_data = True return reply # Create a position array of zeros. The odometry messages # record what has happened to a position since the given time. # We will apply those changes to these zeros, and then add the # result to the input points. pts = [ Pt(point = [0.0, 0.0, 0.0]) for i in range(self.nPoints) ] # Add up the position, plus error, since then. for start, finish in zip(odoms, odoms[1:]): pts = self.propagateError(pts, start, finish) reply.source_data += "\n%s -> %s (%.4f -- %d)" % \ (self.tidyPrint(start), self.tidyPrint(finish), \ finish.header.stamp.to_sec(), finish.header.seq) reply.outPoints = [] # Add the errors to the input points. These are in different # reference frames, so the addition is not simple. We convert # the adjustment to polar coordinates and apply it as a relative # adjustment to the input points. # # We're also adding a little wiggle to simulate annealing. wiggle = lambda x: 1.0 * x * ((2 * np.random.random()) - 1) # A bit more about the wiggle: a belief is a collection of # individual points, but is intended to be a representation of # a probability distribution. Without the wiggle, over time # the distribution evolves into a collection of individual # points, and drifts away from being a decent representation # of a distribution. The wiggling helps keep the definition # clean, and it also helps adjust to sudden changes, like when # someone picks up the robot and moves it. for pt, inpt in zip(pts, req.inPoints): dR = math.hypot(pt.point[0], pt.point[1]) dPh = math.atan2(pt.point[1], pt.point[0]) dTh = pt.point[2] dX = dR * math.cos(inpt.point[2] + dPh) dY = dR * math.sin(inpt.point[2] + dPh) outpt = Pt(point= [ inpt.point[0] + dX + wiggle(self.posErrorMag), inpt.point[1] + dY + wiggle(self.posErrorMag), self.fixAngle(inpt.point[2] + dTh + \ wiggle(self.thetaErrorMag)) ]) reply.outPoints.append(outpt) # Reply. reply.no_data = False reply.sender = self.name last = odoms[-1] reply.source_stamp = last.header.stamp self.pdebug.publish(reply.source_data) self.lastUpdated = last.header.stamp return reply