コード例 #1
0
    def move(self):
        """
        calculates movement vector considering all gradients
        :return: movement vector
        """

        pose = self._buffer.get_own_pose()
        result = None

        # repulsive gradients
        gradients = self._buffer.gradients(self.frames, self.static,
                                           self.moving)

        if pose:
            if gradients:
                result = Vector3()
                for grdnt in gradients:

                    if grdnt.attraction == 1:
                        result = calc.add_vectors(result, gradient.
                                                  calc_attractive_gradient(
                            grdnt, pose))
                    elif grdnt.attraction == -1:
                        grad = gradient.calc_repulsive_gradient(grdnt, pose)

                        # robot position is within obstacle goal radius
                        # handle infinite repulsion
                        if grad.x == np.inf or grad.x == -1 * np.inf:
                            # create random vector with length (goal_radius +
                            # gradient.diffusion)
                            dv = calc.delta_vector(pose.p, grdnt.p)

                            if calc.vector_length(dv) == 0:
                                result = calc.add_vectors(result,
                                                          calc.random_vector(
                                                              grdnt.goal_radius
                                                              + grdnt.diffusion
                                                          ))
                            else:
                                result = calc.add_vectors(result,
                                                          calc.adjust_length(
                                                              dv,
                                                              grdnt.goal_radius
                                                              + grdnt.diffusion
                                                          ))
                        else:
                                result = calc.add_vectors(result, grad)

        if not result:
            return None

        # adjust length
        d = calc.vector_length(result)
        if d > self.maxvel:
            result = calc.adjust_length(result, self.maxvel)
        elif 0 < d < self.minvel:
            result = calc.adjust_length(result, self.minvel)

        return result
コード例 #2
0
    def move(self):
        """
        calculates movement vector to avoid all repulsive gradients
        :return: movement vector
        """

        pose = self._buffer.get_own_pose()
        vector_repulsion = None

        # repulsive gradients
        gradients_repulsive = self._buffer.repulsive_gradients(self.frames,
                                                               self.static,
                                                               self.moving)

        if pose:
            if gradients_repulsive:
                vector_repulsion = Vector3()
                for grdnt in gradients_repulsive:

                    grad = gradient.calc_repulsive_gradient(grdnt, pose)

                    # robot position is within obstacle goal radius
                    # handle infinite repulsion
                    if grad.x == np.inf or grad.x == -1 * np.inf:
                        # create random vector with length (goal_radius +
                        # gradient.diffusion)
                        dv = calc.delta_vector(pose.p, grdnt.p)

                        if not vector_repulsion:
                            vector_repulsion = Vector3()

                        if calc.vector_length(dv) == 0:
                            vector_repulsion = calc.add_vectors(
                                vector_repulsion, calc.random_vector(
                                    grdnt.goal_radius + grdnt.diffusion))
                        else:
                            vector_repulsion = calc.add_vectors(
                                vector_repulsion, calc.adjust_length(dv,
                                        grdnt.goal_radius + grdnt.diffusion))
                    else:
                        vector_repulsion = calc.add_vectors(vector_repulsion,
                                                            grad)

        if not vector_repulsion:
            return None

        # adjust length
        d = calc.vector_length(vector_repulsion)
        if d > self.maxvel:
            vector_repulsion = calc.adjust_length(vector_repulsion, self.maxvel)
        elif 0 < d < self.minvel:
            vector_repulsion = calc.adjust_length(vector_repulsion, self.minvel)

        return vector_repulsion
コード例 #3
0
    def move(self):
        """
        :return: movement vector following trail
        """
        pose = self._buffer.get_own_pose()

        # get all gradients within view distance
        view = self._buffer.static_list_angle(self.frames, self.angle_xy,
                                              self.angle_yz)

        result = None

        if pose:
            if view:
                result = Vector3()
                for grdnt in view:
                    grad = gradient.calc_attractive_gradient_ge(grdnt, pose)
                    result = calc.add_vectors(result, grad)

        if not result:
            return None

        d = calc.vector_length(result)
        if d > self.maxvel:
            result = calc.adjust_length(result, self.maxvel)
        elif 0 < d < self.minvel:
            result = calc.adjust_length(result, self.minvel)

        return result
コード例 #4
0
    def move(self):
        """
        calculates repulsion vector based on Fernandez-Marquez
        :return: repulsion movement vector
        """

        pose = self._buffer.get_own_pose()
        view = self._buffer.agent_list(self.frames)

        mov = None

        if pose and view:
            repulsion_radius = pose.diffusion + pose.goal_radius
            mov = Vector3()

            for el in view:
                distance = calc.get_gradient_distance(el.p, pose.p) \
                           - el.goal_radius

                if distance <= self._buffer.view_distance:

                    if distance > 0:
                        diff = repulsion_radius - distance
                        mov.x += (pose.p.x - el.p.x) * diff / distance
                        mov.y += (pose.p.y - el.p.y) * diff / distance
                        mov.z += (pose.p.z - el.p.z) * diff / distance

                    # enhancement of formulas to cover case when gradients are
                    # collided (agent is in goal radius of neighbor)
                    elif distance <= 0:
                        # create random vector with length=repulsion radius
                        if distance == - el.goal_radius:
                            mov = calc.add_vectors(mov, calc.random_vector(
                                repulsion_radius))
                        # use direction leading away if available
                        else:
                            mov = calc.add_vectors(mov, calc.adjust_length(
                                calc.delta_vector(pose.p, el.p),
                                repulsion_radius))

            if not mov:
                return None

            if calc.vector_length(mov) > repulsion_radius:
                mov = calc.adjust_length(mov, repulsion_radius)

        return mov
コード例 #5
0
    def move(self):
        """
        calculates flocking vector based on Reynolds
        :return: movement Vector (Vector3)
        """

        pose = self._buffer.get_own_pose()
        view = self._buffer.agent_list([self.frame])

        mov = None

        if pose:
            mov = separation(pose, view)
            mov = calc.add_vectors(mov, cohesion(pose, view))
            mov = calc.add_vectors(mov, alignment(pose, view))

        if mov and calc.vector_length(mov) > self.max_velocity:
            mov = calc.adjust_length(mov, self.max_velocity)

        return mov
コード例 #6
0
    def move(self):
        """
        calculates repulsion vector based on agent gradients
        :return: repulsion movement vector
        """
        pose = self._buffer.get_own_pose()
        view = self._buffer.agent_list(self.frames)
        repulsion = None

        if pose and view:
            repulsion_radius = pose.diffusion + pose.goal_radius
            repulsion = Vector3()

            for el in view:
                grad = gradient.calc_repulsive_gradient(el, pose)

                # case: agents are collided
                if abs(grad.x) == np.inf or abs(grad.y) == np.inf or \
                                abs(grad.z) == np.inf:
                    dv = calc.delta_vector(pose.p, el.p)

                    if calc.vector_length(dv) == 0:
                        repulsion = calc.add_vectors(repulsion,
                                                     calc.random_vector(
                                                         repulsion_radius))
                    else:
                        repulsion = calc.add_vectors(repulsion,
                                                     calc.adjust_length(
                                                         dv, repulsion_radius))

                else:
                    repulsion = calc.add_vectors(repulsion, grad)

            if not repulsion:
                return None

            if calc.vector_length(repulsion) > repulsion_radius:
                repulsion = calc.adjust_length(repulsion, repulsion_radius)

        return repulsion
コード例 #7
0
    def move(self):
        """
        flocking calculations based on Olfati-Saber
        :return: movement vector
        """
        own_poses = self._buffer.own_pos

        # own position - we need minimum two values to calculate velocities
        if len(own_poses) >= 2:
            pose = own_poses[-1].p
        else:
            return

        # neighbors of agent
        view = self._buffer.agent_set(self.frame)

        # create array of tuples with neighbor position - neighbor velocity &
        # own pos & velocity (p, v)
        Boid = collections.namedtuple('Boid', ['p', 'v'])

        agent = Boid(pose, agent_velocity(own_poses[-1], own_poses[-2]))

        neighbors = []
        for neighbor in view:
            if len(neighbor) >= 2:  # at least 2 datapoints are available
                neighbors.append(
                    Boid(neighbor[-1].p,
                         agent_velocity(neighbor[-1], neighbor[0])))

        repulsion_radius = own_poses[-1].diffusion + own_poses[-1].goal_radius

        # calculate new velocity based on steering force
        acceleration = flocking_vector(neighbors, agent, self.epsilon, self.a,
                                       self.b, repulsion_radius,
                                       self._buffer.view_distance, self.h)

        if calc.vector_length(acceleration) > self.max_acceleration:
            acceleration = calc.adjust_length(acceleration,
                                              self.max_acceleration)

        velocity = calc.add_vectors(agent.v, acceleration)

        if calc.vector_length(velocity) > self.maxvel:
            velocity = calc.adjust_length(velocity, self.maxvel)

        return velocity
コード例 #8
0
def flocking_vector(neighbors, agent, epsilon, a, b, repulsion_radius,
                    view_distance, h):
    """
    calculate overall flocking vector
    :param neighbors: neighbor data
    :param agent: agent data
    :param epsilon: fixed parameter (0,1) of sigma_norm
    :param a: parameter action function
    :param b: parameter action function
    :param repulsion_radius: scale (desired distance between agents)
    :param view_distance: interaction range of robot
    :param h: parameter (0,1) of bump_function
    :return: vector of steering force
    """
    grad = gradient_based(neighbors, agent, epsilon, a, b, repulsion_radius,
                          view_distance, h)

    vel = velocity_consensus(neighbors, agent, epsilon, view_distance, h)

    return calc.add_vectors(grad, vel)
コード例 #9
0
def cohesion(agent, neighbors):
    """
    calculates cohesion steering force
    average of neighbor positions
    :param agent: agent position and orientation
    :param neighbors: list of neighbor positions and orientations
    :return: norm vector steering towards average position of neighbors
    """
    coh = Vector3()

    for q in neighbors:
        coh = calc.add_vectors(coh, q.p)

    if len(neighbors) > 0:
        coh.x /= len(neighbors)
        coh.y /= len(neighbors)
        coh.z /= len(neighbors)

        coh = calc.delta_vector(coh, agent.p)

    return coh
コード例 #10
0
    def move(self):
        """
        calculates movement vector, handling all gradients as repulsive
        :return: movement vector
        """

        # spread pheromone
        self.spread()

        pose = self._buffer.get_own_pose()
        result = None

        # repulsive gradients
        gradients = self._buffer.gradients(self.frames, self.static,
                                           self.moving)

        if pose:
            if gradients:
                result = Vector3()

                if len(gradients) > 1:

                    for grdnt in gradients:
                        grad = gradient.calc_repulsive_gradient(grdnt, pose)

                        # robot position is within obstacle goal radius
                        # handle infinite repulsion
                        if grad.x == np.inf or grad.x == -1 * np.inf:
                            # create random vector with length (goal_radius +
                            # gradient.diffusion)
                            dv = calc.delta_vector(pose.p, grdnt.p)

                            dv = calc.adjust_length(
                                dv, grdnt.goal_radius + grdnt.diffusion)

                            result = calc.add_vectors(result, dv)
                        else:
                            result = calc.add_vectors(result, grad)
                else:
                    grdnt = gradients[0]
                    result = calc.random_vector(grdnt.goal_radius +
                                                grdnt.diffusion)
            else:
                rospy.logwarn("No gradients of frames '%s' available",
                              self.frames)
        else:
            rospy.logwarn("No own pose available!")

        if not result:
            rospy.logwarn("No gradient vector available!")
            return None

        # adjust length
        d = calc.vector_length(result)
        if d > self.maxvel:
            result = calc.adjust_length(result, self.maxvel)
        elif 0 < d < self.minvel:
            result = calc.adjust_length(result, self.minvel)
        else:
            result = calc.random_vector(grdnt.goal_radius + grdnt.diffusion)

        return result
コード例 #11
0
    def move(self):
        """
        :return: movement vector
        """
        vector_repulsion = None

        pose = self._buffer.get_own_pose()

        # repulsive gradients
        gradients_repulsive = self._buffer.repulsive_gradients(self.frames,
                                                               self.static,
                                                               self.moving)

        # attractive gradient / set goal
        vector_attraction = self.goal_gradient()

        if pose:
            if gradients_repulsive:
                vector_repulsion = Vector3()
                for grdnt in gradients_repulsive:
                    if self.goal:
                        grad = gradient.calc_repulsive_gradient_ge(grdnt,
                                                                   self.goal,
                                                                   pose)
                    else:  # no attractive gradient, apply repulsion only
                        grad = gradient.calc_repulsive_gradient(grdnt, pose)

                    # robot position is within obstacle goal radius
                    # handle infinite repulsion
                    if abs(grad.x) == np.inf or abs(grad.y) == np.inf or \
                                    abs(grad.z) == np.inf:
                        # create random vector with length (goal_radius +
                        # gradient.diffusion)
                        dv = calc.delta_vector(pose.p, grdnt.p)

                        if calc.vector_length(dv) == 0:
                            vector_repulsion = calc.add_vectors(
                                vector_repulsion, calc.random_vector(
                                    grdnt.goal_radius + grdnt.diffusion))
                        else:
                            vector_repulsion = calc.add_vectors(
                                vector_repulsion, calc.adjust_length(dv,
                                        grdnt.goal_radius + grdnt.diffusion))
                    else:
                        vector_repulsion = calc.add_vectors(vector_repulsion,
                                                            grad)

        if vector_attraction and vector_repulsion:
            result = calc.add_vectors(vector_attraction, vector_repulsion)
        elif vector_repulsion:
            result = vector_repulsion
        elif vector_attraction:
            result = vector_attraction
        else:
            return None

        d = calc.vector_length(result)
        if d > self.maxvel:
            result = calc.adjust_length(result, self.maxvel)
        elif 0 < d < self.minvel:
            result = calc.adjust_length(result, self.minvel)

        return result