示例#1
0
    def _calculate_separation(self, boats):
        '''
        Function to calculate separation vector

        Args:
            boats: list of dictionaries containing data from other boats
        
        Returns:
            A vector containing separation for unit
        '''
        separation = Vector()
        total = 0.0
        average_vector = Vector()

        for boid in boats:
            if boid['distance'] < self.perception and boid['distance'] != 0.0: # only boids within perception calculated
                diff = Vector(-boid['x'], -boid['y'])
                diff = diff.__truediv__(boid['distance'])
                average_vector += diff
                total += 1.0

        if total > 0.0 and average_vector.magnitude != 0.0 and average_vector.angle != 0.0:          
            separation = average_vector.__truediv__(total)
            separation_tot = m.sqrt(m.pow(separation.magnitude, 2.0)+m.pow(separation.angle, 2.0))

            if separation_tot > 0.0: #Proportions the vector to maxSpeed
                separation = (separation.__truediv__(separation_tot)) * self.maxSpeed
            if separation_tot > self.maxForce:
                separation = (separation.__truediv__(separation_tot)) * self.maxForce

        return separation
示例#2
0
class swarmWanted():
    '''Helper class to fetch data from behaviour through ROS'''
    def __init__(self):
        '''Initialises subscribers to behaviour topics'''
        self.topic_main = "/swarm/behaviour/"

        topic_movement = "/swarm/behaviour/movement"
        topic_position = "/swarm/behaviour/position"
        try:
            rospy.Subscriber(topic_movement, Movement, self._update_movement)
            rospy.Subscriber(topic_position, Position, self._update_position)

        except rospy.exceptions.ROSException as e:
            print("could not subscribe to topic with error: {s}", format(e))

        self.swarm_movement = Vector()
        self.swarm_position = GPS()

        self.time_since = 0
        self.last_receive = rospy.get_rostime().secs
        self.newest = ''
        self.recieving_data = False

    def __call__(self):
        '''Call function that returns newest data

        Returns either:
            Vector of newest movement wanted
            GPS point wanted
        '''
        if self.newest == 'movement':
            return self.swarm_movement

        else:
            return self.swarm_position

    def _update_movement(self, data):
        self.swarm_movement.set(data.velocity, data.bearing)

        self.last_receive = rospy.get_rostime().secs
        self.newest = 'movement'

    def _update_position(self, data):
        self.swarm_position.set(data.latitude, data.longitude)

        self.last_receive = rospy.get_rostime().secs
        self.newest = 'position'

    def is_recieving(self):
        '''Helper function to return if topics are published to

        Returns:
            Boolean on wether its receiving or not
        '''
        self.time_since = rospy.get_rostime().secs - self.last_receive
        if self.time_since < 2 and self.newest != '':
            self.recieving_data = True

        return self.recieving_data
示例#3
0
    def get_Vector(self):
        '''Helper function get current movement vector

        Returns:
            Vector object containing current movement
        '''
        self.vector = Vector(self.velocity, self.bearing)
        return self.vector
示例#4
0
    def _calculate_cohesion(self, boats):
        '''
        Function to calculate cohesion vector

        Args:
            boats: list of dictionaries containing data from other boats
        
        Returns:
            A vector containing cohesion for unit
        '''
        cohesion = Vector()
        total = 0.0
        center_of_mass = Vector()

        for boid in boats:
            if boid['distance'] < self.perception and boid['distance'] != 0.0: # only boids within perception calculated
                center_of_mass.magnitude += boid['x']
                center_of_mass.angle     += boid['y']
                total += 1.0

        if total > 0.0 and center_of_mass.magnitude != 0.0 and center_of_mass.angle != 0.0: #only manipulates vector if there is one
            cohesion = center_of_mass.__truediv__(total) #- self.position
            cohesion_tot = m.sqrt(m.pow(cohesion.magnitude, 2.0)+m.pow(cohesion.angle, 2.0))

            if cohesion_tot > 0.0: #Proportions the vector to maxSpeed
                cohesion = (cohesion.__truediv__(cohesion_tot)) * self.maxSpeed
            if cohesion_tot > self.maxForce:
                cohesion = (cohesion.__truediv__(cohesion_tot)) * self.maxForce

        return cohesion # vector towards center of mass - cohesion
示例#5
0
    def _calculate_alignment(self, boats): 
        '''
        Function to calculate alignment vector

        Args:
            boats: list of dictionaries containing data from other boats
        
        Returns:
            A vector containing alignment for unit
        '''

        alignment = Vector()
        total = 0.0
        average_temp = Vector(0.0, 0.0)
        average_vector = Vector(0.0, 0.0)

        for boid in boats:
            if boid['distance'] < self.perception and boid['distance'] != 0.0: #finds number of boids within perception

                dx = boid['speed'] * m.sin(m.radians(boid['bearing'])) #converts vector to x,y components
                dy = boid['speed'] * m.cos(m.radians(boid['bearing']))
                average_temp.set(dx,dy)

                average_vector += average_temp
                total += 1.0

        if total > 0.0:
            try:
                alignment.magnitude = average_vector.magnitude / total
            except ValueError:
                pass

            try:
                alignment.angle = average_vector.angle / total
            except ValueError:
                pass

            alignment_tot = m.sqrt(m.pow(average_vector.magnitude, 2.0) + m.pow(average_vector.angle, 2.0))

            if alignment_tot > self.maxForce:
                alignment = (alignment.__truediv__(alignment_tot)) * self.maxForce

        return alignment
示例#6
0
    def __init__(self):
        '''Initialises subscribers to behaviour topics'''
        self.topic_main = "/swarm/behaviour/"

        topic_movement = "/swarm/behaviour/movement"
        topic_position = "/swarm/behaviour/position"
        try:
            rospy.Subscriber(topic_movement, Movement, self._update_movement)
            rospy.Subscriber(topic_position, Position, self._update_position)

        except rospy.exceptions.ROSException as e:
            print("could not subscribe to topic with error: {s}", format(e))

        self.swarm_movement = Vector()
        self.swarm_position = GPS()

        self.time_since = 0
        self.last_receive = rospy.get_rostime().secs
        self.newest = ''
        self.recieving_data = False
示例#7
0
    def __init__(self):

        self.Ka = 1.5   #Adjusting alignment
        self.Kc = 1.85  #Adjusting cohesion
        self.Ks = 0.5   #Adjusting separation

        self.maxForce   = 1.2 # maximum magnitude of cohesion and separation
        self.maxSpeed   = 2.0 # Maximum speed in m/s
        self.perception = 100.0 # Max distance to percieve other boats

        self.position = GPS()
        self.movement = Vector()

        self.has_newCurr = False
示例#8
0
def main():
    nav = navData()
    autopilot = Autopilot()
    time.sleep(0.2)
    autopilot_talker = Talker()
    time.sleep(0.2)
    wait_time, clicks = 0.0, 0
    wanted_GPS = GPS(60.365625, 5.264544)

    wanted_vector = Vector(0.4, 180.0)

    while nav.is_ready() == False:
        #waits for both systems to connect
        wait_time += 0.1
        time.sleep(0.1)
        if wait_time > 10.0:  #exit if timeout is over 10s
            sys.exit(0)

    if nav.is_ready() == True:
        print("Pixhawk is connected and ready at: ", nav.mode)

    print("entering autopilot loop...")

    while not rospy.is_shutdown():
        try:
            # wanted_GPS = new_gps(wanted_GPS)

            # fetches newest current speed and position
            current_GPS = nav.get_GPS()
            current_vector = nav.get_Vector()

            autopilot.set_wanted_vector(wanted_vector)

            change_vector = autopilot(current_vector)

            #publishing to ROS
            autopilot_talker(current_vector, current_GPS, wanted_vector,
                             change_vector)

            clicks += 1

            time.sleep(0.2)

        except rospy.ROSInterruptException():
            sys.exit()
        finally:
            pass
示例#9
0
    def run(self) -> None:
        global functions_sequence

        self.run_available = True

        while self.run_available:
            sleep(self.sleep_time)

            if len(functions_sequence[0]) > 0:
                function = functions_sequence[0].pop(0)
                arguments = functions_sequence[1].pop(0)
                key_word_arguments = functions_sequence[2].pop(0)
                function(*arguments, **key_word_arguments)

            if self.serial is not None:
                if not self.serial.is_open:
                    self.serial.open()

                while self.serial.in_waiting:
                    try:
                        data: bytes = self.serial.readline()

                        if type(data) == bytes:
                            data: str = data.decode('utf-8').strip()

                        if data != "":
                            data = data.replace('$', '')
                            data = data.replace(';', '')
                            data = data.strip()
                            parse = data.split()
                            parse = {
                                "+x":
                                self.plus_x_filter.latest_noisy_measurement(
                                    float(parse[0][2:])) - self.plus_x_cof,
                                "-x":
                                self.minus_x_filter.latest_noisy_measurement(
                                    float(parse[1][2:])) - self.minus_x_cof,
                                "+y":
                                self.plus_y_filter.latest_noisy_measurement(
                                    float(parse[2][2:])) - self.plus_y_cof,
                                "-y":
                                self.minus_y_filter.latest_noisy_measurement(
                                    float(parse[3][2:])) - self.minus_y_cof
                            }
                            vec1 = Vector((0, 0, 0),
                                          (-parse['-x'], 0, parse['-x']))
                            vec2 = Vector((0, 0, 0),
                                          (parse['+x'], 0, parse['+x']))
                            vec3 = Vector((0, 0, 0),
                                          (0, -parse['-y'], parse['-y']))
                            vec4 = Vector((0, 0, 0),
                                          (0, parse['+y'], parse['+y']))

                            sum_vec = vec1 + vec2 + vec3 + vec4
                            sum_vec.set_length(
                                abs(parse['-x']) + abs(parse['+x']) +
                                abs(parse['-y']) + abs(parse['+y']))

                            if len(self.buffer) >= self.data_buffer_len:
                                self.writing_in_buffer_flag = True
                                self.buffer.append((sum_vec, parse))
                                self.buffer.pop(0)
                                self.writing_in_buffer_flag = False
                            else:
                                self.writing_in_buffer_flag = True
                                self.buffer.append((sum_vec, parse))
                                self.writing_in_buffer_flag = False

                            if self.graph is not None:
                                self.graph.add_to_buffer((sum_vec, parse))
                    except:
                        pass
示例#10
0
#!/usr/bin/env python
import time

from Classes.PID import PID 
from Classes.GPS_class import GPS
from Classes.Ranger import autoRange
from Classes.Vector_class import Vector



v1 = Vector(10.0,190.0)
v2 = Vector(10.0,190.0)

g1 = GPS(60.366468, 5.258200)
g2 = GPS(60.366455, 5.258232)

v3 = g1.calculate(g2)

v3.showVector()

pid = PID()

pid.set_wanted(v1)

pid_out = pid.update(v2)

pid_out.showVector()

rangespeed = autoRange(0.0,20.0,0.0,90.0)
rangeangle = autoRange(-45.0,45.0,0.0,180.0)
示例#11
0
def main():
    #definitin of status dictionary
    status = {'pixhawk': False, 'arduino': False, 'fix': False, 'wifi': False}

    #initiating objects for autopilot
    nav = navData()
    autopilot = Autopilot()
    time.sleep(0.2)
    talker = Talker()  # change between for sim or real
    # sim = Sim()
    time.sleep(0.2)
    arduino = Arduino('/dev/Arduino',
                      speedLimit=0.8)  #speed limiter for testing
    time.sleep(0.2)
    behaviour = swarmWanted()
    time.sleep(0.2)

    wait_time, clicks = 0.0, 0

    #waits for both systems to connect
    while not nav.is_ready() and not arduino.is_ready():
        wait_time += 0.1
        time.sleep(0.1)
        if wait_time > 10.0:  #exit if timeout is over 10s
            sys.exit(0)

    rospy.loginfo("Pixhawk is connected and ready: {}".format(nav.mode))
    rospy.loginfo("Arduino is connected and started at: {}".format(
        arduino.port))
    rospy.loginfo("Behaviour is publishing data at: {}".format(
        behaviour.topic_main))

    status = {'pixhawk': True, 'arduino': True, 'fix': False, 'wifi': False}

    print("entering loop...")

    while not rospy.is_shutdown():
        try:
            current_GPS = nav.get_GPS()  #gets newest
            current_vector = nav.get_Vector()

            if behaviour.is_recieving(
            ):  # check if behaviour is sending wanted
                wanted = behaviour()
                if isinstance(wanted, GPS):
                    wanted_vector = current_GPS.calculate(wanted)
                else:
                    wanted_vector = wanted
            else:  #if not recieving from behaviour stop USV
                print("did not recieve")
                wanted_vector = Vector(0.0, 0.0)

            #sets wanted value for regulator
            autopilot.set_wanted_vector(wanted_vector)

            #calculates vector for new mvoement
            change_vector = autopilot(current_vector)

            #sends vector with new movmement to arduino
            arduino(change_vector.magnitude,
                    change_vector.angle)  #possible addition

            #publishes current data to ROS
            talker(current_vector, current_GPS, wanted_vector,
                   change_vector)  #change between for sim or real
            # sim()

            #publishes status of USV every 20 clicks
            if clicks >= 20:
                talker.publish_status(status)
                clicks = 0
            else:
                clicks += 1
            #comment out for full test
            time.sleep(0.5)

        except rospy.ROSInterruptException():
            arduino()
            sys.exit()
        finally:
            pass
    arduino()  # to reset boat when exiting node
示例#12
0
    if ids is not None:
        ids_dict = {}
        ids_middle = {}
        for i in range(ids.size):
            ids_dict[int(ids[i][0])] = corners[i][0]
            ids_middle[int(ids[i][0])] = find_middle(corners[i][0])

        strg = ''
        for i in range(0, ids.size):
            strg += str(ids[i][0]) + ', '
            _id = ids[i][0]
            if _id in zero_ids:
                if _id == 0:
                    mid_zero = ids_middle[ids[i][0]]
                    ADAPTIVE_CONSTANT = Zero_marker0.size / \
                                        Vector(ids_dict[ids[i][0]][0], ids_dict[ids[i][0]][1]).length()
                    move_vector = Vector(mid_zero, frame_center)
                    if move_vector.length() > 2:
                        move_vector.set_length(move_vector.length() * ADAPTIVE_CONSTANT)
                        manipulator.move_by_vector(move_vector)

                if mid_zero is not None:
                    if _id == 1:
                        if ids_middle.get(0, False):
                            x_vector = Vector(ids_middle[0], ids_middle[1])
                            x_vector_move = x_vector.copy()
                            x_vector_move.set_length(x_vector.length() * ADAPTIVE_CONSTANT)
                    if _id == 2:
                        if ids_middle.get(0, False):
                            y_vector = Vector(ids_middle[0], ids_middle[2])
                            y_vector_move = y_vector.copy()
示例#13
0
    if ids is not None:
        ids_dict = {}
        ids_middle = {}
        for i in range(ids.size):
            ids_dict[int(ids[i][0])] = corners[i][0]
            ids_middle[int(ids[i][0])] = find_middle(corners[i][0])

        strg = ''
        for i in range(0, ids.size):
            strg += str(ids[i][0]) + ', '
            _id = ids[i][0]
            if _id in zero_ids:
                if _id == 0:
                    mid_zero = ids_middle[ids[i][0]]
                    ADAPTIVE_CONSTANT = Zero_marker0.size / \
                                        Vector(ids_dict[ids[i][0]][0], ids_dict[ids[i][0]][1]).length()
                    move_vector = Vector(mid_zero, frame_center)
                    if move_vector.length() > 2:
                        move_vector.set_length(move_vector.length() *
                                               ADAPTIVE_CONSTANT)
                        manipulator.move_by_vector(move_vector)

                if mid_zero is not None:
                    if _id == 1:
                        if ids_middle.get(0, False):
                            x_vector = Vector(ids_middle[0], ids_middle[1])
                            x_vector_move = x_vector.copy()
                            x_vector_move.set_length(x_vector.length() *
                                                     ADAPTIVE_CONSTANT)
                    if _id == 2:
                        if ids_middle.get(0, False):