示例#1
0
void vtAgeTracks(struct lnMinList *now,
		 struct lnMinList *old,
		 struct lnMinList *pool)
{
    struct vision_track *vt;
    
    assert(now != NULL);
    assert(old != NULL);

    while ((vt = (struct vision_track *)lnRemHead(old)) != NULL) {
	if (vt->vt_age < MAX_TRACK_AGE) {
	    float distance = MERGE_TOLERANCE;
	    
	    if (vtFindMin(vt,
			  (struct vision_track *)now->lh_Head,
			  &distance) == NULL) {
		vt->vt_age += 1;
		lnAddHead(now, &vt->vt_link);
		vt = NULL;
	    }
	}

	if (vt != NULL)
	    lnAddHead(pool, &vt->vt_link);
    }
}
示例#2
0
static void *mypcap_reader(void *pcap)
{
    struct lnMinNode *next_node = NULL;
    pcap_t *p = pcap;

    while (1) {
        int cc, idx;

        pthread_mutex_lock(&mypcap_data.mpd_mutex);
        if (next_node != NULL) {
            lnAddTail(&mypcap_data.mpd_buflist, next_node);
            pthread_cond_signal(&mypcap_data.mpd_cond);
        }
        if ((next_node = lnRemHead(&mypcap_data.mpd_freelist))
                == NULL) {
            next_node = lnRemHead(&mypcap_data.mpd_buflist);
        }
        pthread_mutex_unlock(&mypcap_data.mpd_mutex);

        idx = next_node - mypcap_data.mpd_nodes;
again:
        cc = read(p->fd,
                  (char *)mypcap_data.mpd_buffer[idx],
                  p->bufsize);
        if (cc < 0) {
            /* Don't choke when we get ptraced */
            switch (errno) {
            case EINTR:
                goto again;

            case EWOULDBLOCK:
                return (0);
            }
            snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s",
                     pcap_strerror(errno));
            return NULL;
        }
        mypcap_data.mpd_buflen[idx] = cc;
    }
}
示例#3
0
void vtCopyTracks(struct lnMinList *dst,
		  struct lnMinList *src,
		  struct lnMinList *pool)
{
    struct vision_track *vt;
    
    assert(dst != NULL);
    assert(src != NULL);
    assert(pool != NULL);

    vt = (struct vision_track *)src->lh_Head;
    while (vt->vt_link.ln_Succ != NULL) {
	struct vision_track *vt_copy = (struct vision_track *)lnRemHead(pool);

	*vt_copy = *vt;
	lnAddTail(dst, &vt_copy->vt_link);
	vt = (struct vision_track *)vt->vt_link.ln_Succ;
    }
}
示例#4
0
int mypcap_read(pcap_t *pd, void *user)
{
    static struct lnMinNode *node = NULL;
    int idx, cc, retval = 0;
    char *bp, *ep;

    pthread_mutex_lock(&mypcap_data.mpd_mutex);
    if (node != NULL) {
        lnAddHead(&mypcap_data.mpd_freelist, node);
    }
    while ((node = lnRemHead(&mypcap_data.mpd_buflist)) == NULL) {
        pthread_cond_wait(&mypcap_data.mpd_cond,
                          &mypcap_data.mpd_mutex);
    }
    pthread_mutex_unlock(&mypcap_data.mpd_mutex);

    idx = node - mypcap_data.mpd_nodes;
    bp = mypcap_data.mpd_buffer[idx];
    cc = mypcap_data.mpd_buflen[idx];
    /*
     * Loop through each packet.
     */
#define bhp ((struct bpf_hdr *)bp)
    ep = bp + cc;
    while (bp < ep) {
        register int caplen, hdrlen;
        caplen = bhp->bh_caplen;
        hdrlen = bhp->bh_hdrlen;
        /*
         * XXX A bpf_hdr matches a pcap_pkthdr.
         */
        (*mypcap_data.mpd_callback)(user,
                                    (struct pcap_pkthdr*)bp,
                                    bp + hdrlen);
        bp += BPF_WORDALIGN(caplen + hdrlen);
    }
#undef bhp

    return retval;
}
示例#5
0
pp_plot_code_t pp_plot_waypoint(struct path_plan *pp)
{
    struct lnMinList dextra, sextra, intersections;
    float distance, cross, theta;
    pp_plot_code_t retval;
    int in_ob = 0;
    
    assert(pp != NULL);

    if (debug > 0) {
	info(" plot %.2f %.2f -> %.2f %.2f\n",
	     pp->pp_actual_pos.x, pp->pp_actual_pos.y,
	     pp->pp_goal_pos.x, pp->pp_goal_pos.y);
    }
    
    lnNewList(&dextra);
    lnNewList(&sextra);
    lnNewList(&intersections);
    
    retval = PPC_NO_WAYPOINT; /* if nothing else */
    
    /*
     * We have to iterate over one or more waypoints, so we start with the
     * Initial waypoint is the goal point.
     */
    pp->pp_waypoint = pp->pp_goal_pos;
    
    do {
	struct obstacle_node *on, *min_on = NULL;
	int goal_in_ob = 0, robot_ob = 0;
	float min_distance = FLT_MAX;

	/*
	 * The path doesn't cross enough of the obstacle box for us to worry
	 * about it so we dump it on the extra list so the intersect doesn't
	 * return it again.  XXX The number is partially a guess and
	 * empirically derived.
	 */
	cross = PP_MIN_OBSTACLE_CROSS;
	/*
	 * First we find all of the obstacles that intersect with this path
	 * and locate the minimum distance to an obstacle.
	 */
	if (debug)
	    info("wp %.2f %.2f\n", pp->pp_waypoint.x, pp->pp_waypoint.y);
	while ((on = ob_find_intersect2(&pp->pp_actual_pos,
					&pp->pp_waypoint,
					&distance,
					&cross)) != NULL) {
#if 0
	    info("intr %d %.2f %.2f\n",
		 on->on_natural.id,
		 distance,
		 cross);
#endif
	    
	    if (on->on_type == OBT_ROBOT)
		robot_ob = 1;

	    switch (pp_point_identify(&pp->pp_actual_pos, &on->on_expanded)) {
	    case PPT_INTERNAL:
	    case PPT_CORNERPOINT:
	    case PPT_OUTOFBOUNDS:
		in_ob = 1;
		break;
	    default:
		break;
	    }

	    if (rc_compute_code(pp->pp_goal_pos.x,
				pp->pp_goal_pos.y,
				&on->on_expanded) == 0) {
		goal_in_ob = 1;
	    }
	    
	    lnRemove(&on->on_link);
	    /* Record the intersection and */
	    lnAddTail(&intersections, &on->on_link);
	    /* ... check if this is the closest obstacle. */
	    if (distance < min_distance) {
		min_distance = distance;
		min_on = on;
	    }
	    
	    cross = PP_MIN_OBSTACLE_CROSS;
	}
	
	/* Check if there was an actual intersection. */
	if (min_on != NULL) {
	    if (debug > 1)
		info("closest %d\n", min_on->on_natural.id);
	    
	    pp->pp_flags |= PPF_HAS_OBSTACLE;
	    lnRemove(&min_on->on_link); // from the intersections list
	    lnAddTail(min_on->on_type == OBT_STATIC ? &sextra : &dextra,
		      &min_on->on_link);
	    pp->pp_obstacle = min_on->on_expanded;

	    /*
	     * Find all obstacles that the path intersects with and overlap the
	     * closest one.  The rest of the obstacles will be dealt with after
	     * we get around the closest one.
	     */
	    while ((on = (struct obstacle_node *)
		    lnRemHead(&intersections)) != NULL) {
		if (rc_rect_intersects(&pp->pp_obstacle, &on->on_expanded)) {
		    if (debug > 1)
			info("merging %d\n", on->on_natural.id);
		    
		    ob_merge_obstacles(&pp->pp_obstacle, &on->on_expanded);
		}
		lnAddTail(on->on_type == OBT_STATIC ? &sextra : &dextra,
			  &on->on_link);
	    }
	    
	    if (goal_in_ob) {
		struct robot_position rp;
		struct rc_line rl;
		float r;
		
		mtp_polar(&pp->pp_goal_pos, &pp->pp_actual_pos, &r, &theta);
		if (robot_ob)
		    theta += M_PI_2;
		mtp_cartesian(&pp->pp_goal_pos, r + 1000.0, theta, &rp);
		rl.x0 = pp->pp_goal_pos.x;
		rl.y0 = pp->pp_goal_pos.y;
		rl.x1 = rp.x;
		rl.y1 = rp.y;
		rc_clip_line(&rl, &pp->pp_obstacle);
		pp->pp_waypoint.x = rl.x1;
		pp->pp_waypoint.y = rl.y1;
		if (pp_point_distance(&pp->pp_waypoint,
				      &pp->pp_actual_pos) > 0.075) {
		    if (pp_point_reachable(pp, &pp->pp_waypoint))
			retval = PPC_WAYPOINT;
		    else if (pp_next_cornerpoint(pp))
			retval = PPC_WAYPOINT;
		    else
			retval = PPC_BLOCKED;
		}
		else {
		    retval = PPC_GOAL_IN_OBSTACLE;
		}
	    }
	    else if (pp_next_cornerpoint(pp)) {
		retval = PPC_WAYPOINT;
	    }
	    else {
		retval = PPC_BLOCKED;
	    }
	}

	/* Restore the active obstacle list.  XXX Shouldn't do this here. */
	lnPrependList(&ob_data.od_active, &dextra); // dynamics first
	lnAppendList(&ob_data.od_active, &sextra); // statics last
	
	/* Check for obstacles on the path to our new waypoint. */
	cross = PP_MIN_OBSTACLE_CROSS;
    } while ((retval == PPC_WAYPOINT) &&
	     (ob_find_intersect2(&pp->pp_actual_pos,
				 &pp->pp_waypoint,
				 &distance,
				 &cross) != NULL) &&
	     !in_ob);
    
    /* And make sure it is still sane. */
    assert(ob_data_invariant());
    
    /* restrict final waypoint to MAX_DISTANCE */
    mtp_polar(&pp->pp_actual_pos,
	      (retval == PPC_WAYPOINT) ? &pp->pp_waypoint : &pp->pp_goal_pos,
	      &distance,
	      &theta);
    if (distance > pp_data.ppd_max_distance) {
	mtp_cartesian(&pp->pp_actual_pos,
		      pp_data.ppd_max_distance,
		      theta,
		      &pp->pp_waypoint);
	retval = PPC_WAYPOINT;
    }

    switch (retval) {
    case PPC_WAYPOINT:
	info("set waypoint(%s) %.2f %.2f\n",
	     pp->pp_robot->hostname,
	     pp->pp_waypoint.x,
	     pp->pp_waypoint.y);
	break;
    case PPC_NO_WAYPOINT:
	info("set waypoint(%s) NONE\n", pp->pp_robot->hostname);
	break;
    case PPC_BLOCKED:
	info("set waypoint(%s) BLOCKED\n", pp->pp_robot->hostname);
	break;
    case PPC_GOAL_IN_OBSTACLE:
	info("set waypoint(%s) GOAL_IN_OBSTACLE\n", pp->pp_robot->hostname);
	break;
    }
    
    return retval;
}
示例#6
0
int vtUpdate(struct lnMinList *now,
	     struct vmc_client *vc,
	     struct mtp_packet *mp,
	     struct lnMinList *pool)
{
    int retval = 0;
    
    assert(now != NULL);
    assert(vc != NULL);
    assert(mp != NULL);
    assert(pool != NULL);

    if (debug > 2) {
	mtp_print_packet(stdout, mp);
	fflush(stdout);
    }
    
    switch (mp->data.opcode) {
    case MTP_CONTROL_ERROR:
	retval = 1;
	break;
    case MTP_UPDATE_POSITION:
	{
	    struct mtp_update_position *mup;
	    struct vision_track *vt;
	    
	    mup = &mp->data.mtp_payload_u.update_position;
	    vt = (struct vision_track *)lnRemHead(pool);
	    assert(vt != NULL);

	    vt->vt_position = mup->position;
	    vt->vt_client = vc;
	    vt->vt_age = 0;
	    vt->vt_userdata = NULL;


	    /* zero out the smoothing data for this 
	     * track!
	     */
	    //vt->ma.oldest_index = 0;
	    //vt->ma.number_valid_positions = 0;


	    lnAddTail(now, &vt->vt_link);

	    /* Adjust the cameras viewable area based on this track. */
	    if (mup->position.x < vc->vc_left)
		vc->vc_left = mup->position.x;
	    if (mup->position.x > vc->vc_right)
		vc->vc_right = mup->position.x;
	    if (mup->position.y < vc->vc_top)
		vc->vc_top = mup->position.y;
	    if (mup->position.y > vc->vc_bottom)
		vc->vc_bottom = mup->position.y;

	    retval = (mup->status == MTP_POSITION_STATUS_CYCLE_COMPLETE);
	}
	break;
    default:
	error("unhandled vmc-client packet %d\n", mp->data.opcode);
	break;
    }
    
    return retval;
}