Beispiel #1
0
def _checkFruitTree(p):
    """Checks whether the given tree is valid or not
    """
    if p.x < 0:
        return False
    elif p.y < 0:
        return False
    elif p.x > dp.Island().shape[0] - 1:
        return False
    elif p.y > dp.Island().shape[1] - 1:
        return False
    elif p.z == 0:
        return False
    else:
        return True
Beispiel #2
0
def display_island(index=None, show=True, block=False):
    """ displays the island with fruit trees

        Keyword Arguments;
            index {int} -- index of  figure. If it is None no figure is created.  {Default: None}
            show {boolean} -- whether to immediately show the figure or not.  {Default: True}
            block {boolean} -- whether the figure blocks the excution.  {Default: True}

        Returns:
            {int} -- number of drawn figure. None if figure has been displayed and blocks
    """
    # reset block
    plt.ioff()
    # create figure if requested
    if index is not None:
        fig = plt.figure(index)

    #  display island
    plt.imshow(dp.Island().transpose())
    plt.axis('scaled')
    plt.draw()
    # optional
    if show:
        showfig(block)
    # return current figure number
    if not block:
        return plt.gcf().number
    else:
        return None
Beispiel #3
0
def _createCoor(xy):
    """Creates a Coordinates object from a set of points
    if the points are outside the dp.Island() z=0
    """
    try:
        return geo.Coordinates(xy[0], xy[1],
                               dp.Island()[int(xy[0]), int(xy[1])])
    except IndexError:
        return geo.Coordinates(xy[0], xy[1], 0)
import geometry as geo
import datepath as dtp
import dataparser as dp
import monkeyconstants as mc
import display as disp

# Path to real dataset
ORIG_PATH = 'D:\\OneDrive - Politecnico di Milano\\Documents\\University\\Thesis\\Data\\Original Data.csv'
DISTR_FILE = mc.REAL_PATH + 'Distributions.txt'

MIN_VALID_LEN = 900  # Minimum length for a path to be valid
SPECIES = ["Ateles geoffroyi"]  # Species of interest

# set global static variables
dtp.datepath.Island = dp.Island()
geo.Coordinates.Island = dp.Island()


def _converttoXY(lon, lat):
    """Compute xy coordinates from GPS

    Converts GPS coordinates to xy referenced to the origin of the island pic

    Arguments:
        lon {float} -- Longitude
        lat {float} -- Latitude
    """

    # Fixed Pixel-GPS Matches
    Px =  [[3800,4400], \
Beispiel #5
0
def buildFruitTree(density,
                   distr,
                   sd_factor=3,
                   mean=None,
                   num_clast=4,
                   min_dist=2000):
    """Creates the fruit trees on the dp.Island()

    Creates and distributes fruit tree according to parameters
    Arguments:
        density {float} -- density of fruit tree in trees/km^2
        distr {Distr} -- distribution of fruit trees on the dp.Island() (UNIFORM, NORMAL, CLUSTERED)
            NORMAL: median on the center of the dp.Island() or mean, standard deviation = mean/sd_factor
            CLUSTERED: creates num_clast clasters randomly (uniform) distributed over the dp.Island(). each cluster has a normal distribution with sd = dp.Island()side/sd_factor*num_clast
        sd_factor {float} -- factor representing mean wrt standard deviation, used to compute sd {default=3}
        mean {[int, int]} -- mean of normal distribution {default=None}
        num_clast {int} -- number of cluster {default=4}
        min_dist {int} -- minimum distance between cluster centers {default=2000}

    Returns:
        List of Coordinates -- each row containes the coordinates of a fruit tree
    """
    fruits = []
    area = np.count_nonzero(dp.Island())
    size = int(area / 1000000 * density)  # number of trees to compute
    # Compute Trees
    if distr == Distr.UNIFORM:
        while len(fruits) < size:
            f = [
                random.randint(0,
                               dp.Island().shape[0] - 1),
                random.randint(0,
                               dp.Island().shape[1] - 1)
            ]
            if dp.Island()[f[0], f[1]] > 0:
                fruits.append(
                    geo.Coordinates(f[0], f[1],
                                    dp.Island()[f[0], f[1]]))
    elif distr == Distr.NORMAL:
        if mean is None or mean[0] < 0 or mean[1] < 0 or mean[0] > dp.Island(
        ).shape[0] - 1 or mean[1] > dp.Island().shape[1] - 1:
            mean = [dp.Island().shape[0] / 2, dp.Island().shape[1] / 2]
        cov = [[math.pow(mean[0] / sd_factor, 2), 0],
               [0, math.pow(mean[1] / sd_factor,
                            2)]]  # covariance matrix. Axis are independent
        fruits = np.random.multivariate_normal(mean, cov, size)
        fruits = fruits.astype(int)
        fruits = [_createCoor(x) for x in fruits]
        fruits = [x for x in fruits if _checkFruitTree(x)]
    elif distr == Distr.CLUSTERED:
        clst = []
        while len(clst) < num_clast:
            c = [
                random.randint(0,
                               dp.Island().shape[0] - 1),
                random.randint(0,
                               dp.Island().shape[1] - 1)
            ]
            if dp.Island()[c[0], c[1]] > 0:
                p = geo.Coordinates(c[0], c[1], dp.Island()[c[0], c[1]])
                if not _checkMinDist(p, clst, min_dist):
                    continue
                clst.append(p)
        for c in clst:
            c_fruits = []
            mean = [c.x, c.y]
            cov = [[
                math.pow(dp.Island().shape[0] / (sd_factor * num_clast), 2), 0
            ], [
                0,
                math.pow(dp.Island().shape[1] / (sd_factor * num_clast), 2)
            ]]  # covariance matrix. Axis are independent
            c_fruits = np.random.multivariate_normal(mean, cov,
                                                     int(size / num_clast))
            c_fruits = c_fruits.astype(int)
            c_fruits = [_createCoor(x) for x in c_fruits]
            c_fruits = [x for x in c_fruits if _checkFruitTree(x)]
            fruits.extend(c_fruits)
    return fruits
Beispiel #6
0
def createMemoryDate(fruits,
                     orig=None,
                     totaltime=mc.DATE_DURATION_MIN,
                     startTime=mc.INIT_TIME,
                     max_mem_range=2000):
    """Computes the path for a date according to the memory model

    Arguments:
        fruits {List[Coordinates]} -- set of fruit trees

    Keyword Arguments:
        orig {Coordinates} -- starting point of hanging. If None choose random.  {Default: None}
        totaltime {float} -- duration of day in minutes.  {Default: mc.DATE_DURATION_MIN}
        startTime {time} -- timestamp of first point.   {Default: mc.INIT_TIME}
        max_mem_range {float} -- maximum bird's-eye distance from fruit tree to next fruit tree in path (default: {2000})

    Returns:
        List[Coordinates] -- List of coordinates
    """
    # Compute origin if none
    if orig is None:
        p = np.random.normal(2000, 500, [1, 2])[0]
        orig = geo.Coordinates(p[0], p[1], dp.Island()[int(p[0]), int(p[1])])
    # Variale initialization
    tot_steps = int(totaltime * 60 /
                    mc.DT)  # Duration of day expressed as number of datapoints
    path = []  # path is initially empty
    start = orig
    ignores = [start]  # add start to list of destination to ignore
    curr_plan = 0  # counter of planned steps (shortest path)
    rdm_index = int(np.random.uniform(0, len(fruits),
                                      1))  # get random fruit tree index

    # print("tot_steps = " + str(tot_steps))                # DEBUG!!!
    iterations = 0
    # external loop. Required if mc.PLANNING_STEPS are not enough to reach tot_steps
    while True:
        iterations = iterations + 1
        print("\t\t" + str(iterations))
        # if max iterations reached throw exception
        if iterations == mc.MAX_ITERATIONS:
            raise me.MaxIterationsReachedException()
        # randomly draw mc.PLANNING_STEPS fruit trees that will be visited
        curr_fruits = [start]  # list of fruit tree that I will visit
        for curr_plan in range(0, mc.PLANNING_STEPS):
            fruititer = 0
            while fruits[rdm_index].minDistance(curr_fruits)[0] > max_mem_range \
                    or fruits[rdm_index].minDistance(curr_fruits)[0] < mc.MIN_FRUIT_DIST or fruits[rdm_index] in ignores:
                rdm_index = int(np.random.uniform(0, len(fruits), 1))
                fruititer = fruititer + 1
                if fruititer == 50:
                    raise me.MaxIterationsReachedException()
            curr_fruits.append(fruits[rdm_index])
            ignores.append(fruits[rdm_index])
        curr_fruits.remove(start)
        # print("curr_fruits: " + str(curr_fruits))
        curr_fruits = geo.shortestPath(
            start, curr_fruits)  # sort fruits along shortest path
        # create sequential path to each fruit tree
        for f in curr_fruits:
            try:
                curr_path = _createDirect(start, f)
            # if path goes on water
            except me.PathOnWaterException:
                print("PathOnWaterException")
                #  return None            # GIVE UP overall
                continue  # skip tree
            # add new subpath to path and fruit tree to ignores
            # print("path: " + str(len(curr_path)))
            path.extend(curr_path)
            # ignores.append(start)
            start = curr_path[-1]
            # add hanging around fruit tree
            curr_path = hangAround(start, start, fruits=fruits, expand=False)
            path.extend(curr_path[0:-2])
            ignores.append(start)
            start = curr_path[-1]
            if len(path) > tot_steps:
                break
        if len(path) > tot_steps:
            break

    # add timing
    validpath = path[0:tot_steps]
    delta = timedelta(seconds=mc.DT)
    dtime = datetime.combine(date.today(), startTime)
    for p in validpath:
        p.set_time(dtime.time())
        dtime = dtime + delta

    if iterations > 1:
        print("memory validpath len: " + str(len(validpath)))

    return validpath
Beispiel #7
0
def createViewDate(fruits,
                   orig=None,
                   totaltime=mc.DATE_DURATION_MIN,
                   startTime=mc.INIT_TIME):
    """Computes the path for a date according to the view model

    Arguments:
        orig {Coordinates} -- starting point
        fruits {List[Coordinates]} -- set of fruit trees
        totaltime {float} -- duration of day in minutes
        startTime {time} -- timestamp of first point.   {Default: mc.INIT_TIME}

    Returns:
        List[Coordinates] -- List of coordinates
    """
    # Compute origin if none
    if orig is None:
        p = np.random.normal(2500, 500, [1, 2])[0]
        orig = geo.Coordinates(p[0], p[1], dp.Island()[int(p[0]), int(p[1])])

    # Variable initialization
    tot_steps = int(totaltime * 60 /
                    mc.DT)  # Duration of day expressed as number of datapoints
    path = []  # path initially empty
    curr_steps = 0  # step (datapoint) counter
    start = orig
    ignores = [start]  # add start to list of destination to ignore
    counter = 0

    # generation loop
    # print("orig is " + str(orig))
    while curr_steps < tot_steps and counter < mc.MAX_ITERATIONS:
        try:
            curr_path = createViewPath(start, fruits,
                                       ignores)  # generate a path
        # if path goes on water
        except me.PathOnWaterException:
            #  return None            # GIVE UP
            counter += 1
            continue  # try again
        # add new subpath to path and fruit tree to ignores
        path.extend(curr_path)
        start = curr_path[-1]
        ignores.append(start)
        # start = curr_path[-1 ]
        curr_steps = curr_steps + len(curr_path)
        # add hanging around fruit tree
        curr_path = hangAround(start, start, fruits=fruits, expand=False)
        path.extend(curr_path)
        # ignores.append(start)
        start = curr_path[-1]
        # handle loop values
        curr_steps = curr_steps + len(curr_path)

    # if max iterations reached throw exception
    if counter == mc.MAX_ITERATIONS:
        raise me.MaxIterationsReachedException()

    # add timing
    delta = timedelta(seconds=mc.DT)
    dtime = datetime.combine(date.today(), startTime)
    for p in path[0:tot_steps]:
        p.set_time(dtime.time())
        dtime = dtime + delta
    # cut to tot_steps
    return path[0:tot_steps]
Beispiel #8
0
def _createP2PPath(orig, dest, speed, angle):
    """Creates a path from orig to dest

    Arguments:
        orig {Coordinates} -- Origin point
        dest {Coordinates} -- Destination point
        speed {[float, float]} -- speed average and standard deviation [avg, std]
        angle {float} -- standard deviation of angles wrt destination

    Returns:
        List[Coordinates] -- Listo fo points of the path
    """
    # value initialization
    LOAD_SIZE = 100
    p = orig
    path = [orig]
    spds = np.array([])
    agls = np.array([])
    index = LOAD_SIZE
    angl_delta = mc.WATER_SHIFT
    water_index = 0
    counter = 0  # DEBUG!!!!
    # generation loop until almost there or MAX_ITERATIONS
    while (p.distance(dest) > mc.DT * speed[0] / 2
           and counter < mc.MAX_ITERATIONS):
        # Compute speed and angles for the next LOAD_SIZE rounds.
        if index == LOAD_SIZE:
            spds = np.random.normal(speed[0], speed[1], LOAD_SIZE)
            agls = np.random.normal(0, angle, LOAD_SIZE)
            index = 0
        # Compute next point
        delta = p.diff(dest, inplace=False)
        dist = mc.DT * spds[index]
        delta.scale(dist / delta.mag())
        delta.rotate(agls[index])
        nxt = p.add(delta, inplace=False)
        counter = counter + 1  # DEBUG!!!
        # Check if next point is on water or path goes through water
        nxt.z = dp.Island()[int(nxt.x), int(nxt.y)]
        # if nxt.z == 0 or p.inWater(nxt, dp.Island()):
        if nxt.z == 0 or p.inWater(nxt, dp.Island()):
            # if nxt.z == 0:
            #     print("WARNING: direct path into water from " + str(orig) + " towards " + str(nxt))
            # else:
            #     print("WARNING: direct path into water from " + str(orig))
            # print("WARNING: direct path into water")
            raise me.PathOnWaterException(
            )  # Raise path on water Exception and stop path creation
            # if water_index > 180 / WATER_SHIFT:
            #     angl_delta = -WATER_SHIFT
            #     water_index = 0
            # else:
            # angl_delta = angl_delta + mc.WATER_SHIFT
            # water_index = water_index + 1
            # agls[index] = agls[index] + angl_delta
            # continue
        # add point to path
        path.append(nxt)
        # handle loop variables
        water_index = 0
        p = nxt
        index = index + 1

    # print("Direct Counter " + str(counter))                                       # DEBUG!!!
    # if max iterations reached throw exception
    if counter == mc.MAX_ITERATIONS:
        raise me.MaxIterationsReachedException()
    # path.append(dest)
    return path
Beispiel #9
0
def _createP2RPath(orig, speed, angle, fruits, ignores):
    """Creates a random path up to seeing a fruit tree

    Arguments:
        orig {Coordinates} -- Origin point
        speed {[float, float]} -- speed average and standard deviation [avg, std]
        angle {float} -- standard deviation of angles wrt destination
        fruits {List[Coordinates]} -- List of fruit trees Coordinates
        ignores {List[Coordinates]} -- List of fruit trees to ignore: Already visited

    Returns:
        [List[Coordinates], Coordinate] -- List of points of the path and seen fruit tree
    """
    # values initialization
    p = orig.clone()  # set last point of path to origin
    path = [orig]  # path only contains origin
    spds = np.array([])  # initialize speeds array
    agls = np.array([])  # initialize angles array
    load_index = mc.DEF_LOAD_SIZE  # initialize loop counter for load size (decrementing)
    angl_delta = mc.WATER_SHIFT  # additional angle delta to avoid water
    water_index = 0  # counter of water avoidance trials
    counter = 0  # counter of all points computed
    valid_cnt = 0  # counter of valid points computed

    # generation loop
    f = p.sees(fruits, dp.Island(), p, ignores)
    # generation loop (continues until a tree is seen)
    while (f is None and counter < mc.MAX_ITERATIONS):
        # Compute speed and angles for the next LOAD_SIZE rounds.
        if load_index == mc.DEF_LOAD_SIZE:
            agl = np.random.normal(0, 360, 1)
            spds = np.random.normal(speed[0], speed[1], mc.DEF_LOAD_SIZE)
            agls = np.random.normal(agl, angle, mc.DEF_LOAD_SIZE)
            load_index = 0
        # Compute next point
        delta = geo.unit()
        dist = mc.DT * spds[load_index]
        delta.scale(dist / delta.mag())
        delta = delta.rotate(agls[load_index])
        nxt = p.add(delta, inplace=False)
        counter = counter + 1  # DEBUG!!!
        # Check if next point is on water or path goes through water
        try:
            nxt.z = dp.Island()[int(nxt.x), int(nxt.y)]
        except IndexError:
            nxt.z = 0
        if nxt.z == 0 or p.inWater(nxt, dp.Island()):
            print("WARNING: random path goes into water from " + str(orig))
            raise me.PathOnWaterException()  # If on water "Cancel"
            # if water_index > 180 / mc.WATER_SHIFT:
            #     angl_delta = -mc.WATER_SHIFT
            #     water_index = 0
            # else:
            #     angl_delta = angl_delta + mc.WATER_SHIFT
            # water_index = water_index + 1
            # agls[load_index] = agls[load_index] + angl_delta
            # continue
        # add point to path
        path.append(nxt)  # append new valid point to path
        f = nxt.sees(fruits, dp.Island(), p,
                     ignores)  # check if fruit tree is visible from new point
        # handle loop variables
        p = nxt
        water_index = 0
        load_index += 1
        valid_cnt += 1

    # if max iterations reached throw exception
    if counter == mc.MAX_ITERATIONS:
        raise me.MaxIterationsReachedException()
    # if no tree found
    if f is None:
        print("No tree visible")
    return [path, f]