def move(self):
        """
        calculates movement vector
        :return: movement vector
        """
        pose = self._buffer.get_own_pose()
        g = None

        # strongest gradient
        grad = self._buffer.max_reach_attractive_gradient(self.frames,
                                                          self.static,
                                                          self.moving)

        if pose and grad:
            g = gradient.calc_attractive_gradient(grad, pose)

        if not g:
            return None

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

        return g
def calc_attractive_gradient_ge(gradient, pose):
    """
    calculate movement vector based on attractive gradient
    normalized version same as _calc_attractive_gradient
    :param gradient: attractive gradient message
    :param pose: position SoMessage of the robot
    :return: movement vector
    """
    v = Vector3()

    # distance goal - agent
    tmp = calc.delta_vector(gradient.p, pose.p)

    # shortest distance considered (goal_radius of agent == size of agent)
    d = np.linalg.norm([tmp.x, tmp.y, tmp.z]) - pose.goal_radius \
        - gradient.goal_radius

    if d <= 0:
        v = Vector3()
    elif 0 < d <= gradient.diffusion:
        v = calc.adjust_length(tmp, d)
    elif d > gradient.diffusion:
        if gradient.diffusion == 0:
            v = calc.adjust_length(tmp, 1)
        else:
            v = calc.adjust_length(tmp, gradient.diffusion)

    return v
Пример #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
    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
    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
def calc_attractive_gradient(gradient, pose):
    """
    calculate movement vector based on attractive gradient
    :param gradient: attractive gradient message
    :param pose: position SoMessage of the robot
    :return: movement vector
    """
    v = Vector3()

    # distance goal - agent
    tmp = calc.delta_vector(gradient.p, pose.p)

    # shortest distance considered (goal_radius of agent == size of agent)
    d = np.linalg.norm([tmp.x, tmp.y, tmp.z]) - pose.goal_radius \
        - gradient.goal_radius

    if d <= 0:
        v = Vector3()
    elif 0 < d <= gradient.diffusion:
        # calculate magnitude of vector
        magnitude = d / gradient.diffusion
        v = calc.adjust_length(tmp, magnitude)
    elif d > gradient.diffusion:
        # calculate attraction vector
        #v = calc.adjust_length(tmp, 1.0)#TODO Why this?
        v = tmp

    return v
Пример #7
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
Пример #8
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
    def move(self):
        """
        calculate movement vector
        :return: movement vector
        """
        pose = self._buffer.get_own_pose()
        g = None

        # strongest gradient
        grad = self._buffer.strongest_gradient(self.frames, self.static,
                                               self.moving)

        if pose:
            if grad:
                if grad.attraction == 1:
                    g = gradient.calc_attractive_gradient(grad, pose)
                elif grad.attraction == -1:
                    g = gradient.calc_repulsive_gradient(grad, pose)

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

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

        if not g:
            return None

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

        return g
Пример #10
0
    def move(self):
        """
        calculates random movement vector
        :return: movement vector
        """
        tmp = np.random.rand(1, 3)

        g = Vector3()
        g.x = 2 * tmp[0][0] - 1
        g.y = 2 * tmp[0][1] - 1
        g.z = 2 * tmp[0][2] - 1

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

        return g
Пример #11
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
Пример #12
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
def calc_repulsive_gradient(gradient, pose):
    """
    calc movement vector based on repulsive gradient
    :param gradient: repulsive gradient message
    :param pose: position SoMessage of the robot
    :return: movement vector
    """
    v = Vector3()

    # distance goal - agent
    tmp = calc.delta_vector(pose.p, gradient.p)

    # shortest distance considered (goal_radius of agent == size of agent)
    d = np.linalg.norm([tmp.x, tmp.y, tmp.z]) - pose.goal_radius \
        - gradient.goal_radius

    if d <= 0 or gradient.diffusion == np.inf:  # infinitely large repulsion
        v = Vector3(np.inf, np.inf, np.inf)
        # calculate norm vector for direction
        tmp = calc.unit_vector3(tmp)

        # calculate repulsion vector / adjust sign/direction
        if tmp.x != 0.0:
            v.x *= tmp.x
        if tmp.y != 0.0:
            v.y *= tmp.y
        if tmp.z != 0.0:
            v.z *= tmp.z

    elif 0 < d <= gradient.diffusion:
        # calculate magnitude of vector
        magnitude = (gradient.diffusion - d) / gradient.diffusion
        # calculate vector
        v = calc.adjust_length(tmp, magnitude)

    elif d > gradient.diffusion:
        v = Vector3()

    return v
Пример #14
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
    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