double PathFollowingGeometry::getCurveRadius()
{
	if (!this->has_curve_radius) {
		PointArr points = this->getCurvatureDetectionPoints();	
		if (!points.empty()) {
			Point center = this->getFeedforwardCurveCenterPoint();
			
			//Equation 13
			double radius = 0;
			for (PointArrIt it = points.begin(); it < points.end(); it++) {
				radius += distance(*it, center);
			}
			radius /= points.size();
			this->curve_radius = radius;
			
			//std::stringstream sstr;
			//sstr << center;
						
			//ROS_INFO("Getting curve radius %f, pts.size %d. %.2f, %.2f", radius, (unsigned int)points.size(), center.x, center.y);
			
			this->has_curve_radius = true;
		}
		else {
			//ROS_WARN("Failed to calculate radius. Detection points are empty");
		}
	}
	return this->curve_radius;
}
Point PathFollowingGeometry::getFeedforwardCurveCenterPoint()
{
	if (!this->has_feedforward_center) {
		PointArr points = this->getCurvatureDetectionPoints();
		if (points.size() >= 5) {
			Point p1 = points.at(0);
			Point p2 = points.at(2);
			Point p3 = points.at(4);
			
			//ROS_INFO("p1 %.2f,%2.f; p2 %.2f,%2.f; p3 %.2f,%2.f", p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
			
			//Equation 12
			double l12 = (p2.y-p1.y)/(p2.x-p1.x);
			double l23 = (p3.y-p2.y)/(p3.x-p2.x);
			
			//Equation 10
			this->feedforward_center.x = -(p1.y+p2.y)/2+(p2.y+p3.y)/2
							  -(p1.x+p2.x)/(2*l12)+(p2.x+p3.x)/(2*l23);
							  
			//Equation 11
			this->feedforward_center.y = -(p2.y+p3.y)/2-this->feedforward_center.x/l23*this->feedforward_center.x+(p2.x+p3.x)/(2*l23);
			
			this->has_feedforward_center = true;
		}
		else {
			//ROS_WARN("Can't get curve center. Expected 5 detection points.");
		}
	}
	return this->feedforward_center;			
}
示例#3
0
void GpsItem::download_tracklog()
{
    wstatus = W_DOWNLOADING;
    progress = 0;
    Gipsy::notify(this, "gps_changed");
    
    if (gpstype == G_COMPEO || gpstype == G_IQ) {
        for (size_t i=0; i < selected_tracks.size(); i++) {
            string igccontent = gps->download_igc(selected_tracks[i], _progress_updater, (void *)this);
            if (igccontent.size()) {
                Igc *igc = new OriginalIgc(igccontent);
                igc->gpsname = gps->gpsname;
                igc->gpsunitid = gps->gpsunitid;
                obtained_tracklog(igc, false);
            }
        }
        wstatus = W_DOWNCOMPLETE;
        Gipsy::notify(this, "gps_changed");
    } else {
        gps->selected_tracks = selected_tracks;
        PointArr parr = gps->download_tracklog(_progress_updater, (void *)this);

        if (gpstype == GPS_MLR)
            wstatus = W_CONNECTED;
        else
            wstatus = W_DOWNCOMPLETE;
        Gipsy::notify(this, "gps_changed");

        // If tracklog is not empty...
        if (!parr.size())
            return;

        // Add tracklog to downloaded_tracklog vector
        // AddRef will be done in the notification handler
        Igc *igc = new Igc(parr, gps->gpsname, gps->gpsunitid);
        // Add custom signed fields
        igc->x_params.push_back(pair<string,string>("Xversion", GIPSY_VERSION));
        time_t now = time(NULL);
        char tmptime[31];
        struct tm mnow;
        strftime(tmptime, 30, "%Y-%m-%d %H:%M:%S GMT", gmtime_r(&now, &mnow));
        igc->x_params.push_back(pair<string,string>("XDownloadtime", tmptime));
        
        igc->gen_g_record(); // Generate g-record on the downloaded tracklog
        
        obtained_tracklog(igc, true);
    }
}
示例#4
0
文件: tracklog.cpp 项目: Trogie/gipsy
/* Create new tracklog from select break-sections */
NS_IMETHODIMP Tracklog::IgcBreakSelect(uint32_t count, int32_t *bpoints, 
				       IGPSIGC **_retval)
{
    PointArr selection;
    int lastidx = -1;
    int bpointcount;
    
    if (!count) {
	*_retval = NULL;
	return NS_OK;
    }

    IgcBreakCount(&bpointcount);

    for (unsigned int i=0; i < count; i++) {
	int idx = bpoints[i];
	if (idx < 0 || idx >= bpointcount)
	    return NS_ERROR_UNEXPECTED;

	// Check that the input array is sorted
	if (idx < lastidx)
	    return NS_ERROR_UNEXPECTED;

	lastidx = idx;

	int bstart;
	int len;
	IgcBreak(idx, &bstart);
	IgcBreakLen(idx, &len);

	for (int j=0;j < len; j++)
	    selection.push_back(igc->tracklog[j + bstart]);
    }
    
    Igc *newigc = new Igc(*igc);
    newigc->tracklog = selection;

    if (igc->validate()) {
	if (! newigc->gen_g_record()) // Failed crypto library?
	    return NS_ERROR_UNEXPECTED;
    }

    *_retval = new Tracklog(newigc);
    NS_ADDREF(*_retval);

    return NS_OK;
}
void PathFollowingGeometry::updateLocalFrame()
{
	//Transform points to robot-centered coordinate frame
	//Depending on where (left or right) feedback path point is
	//make reference distance positive or negative
	
	//Transformation
	this->feedback_path_point_in_local_frame = this->localFramePoint(this->getFeedbackPathPoint());
	this->feedback_point_in_local_frame = this->localFramePoint(this->getFeedbackPoint());
	this->feedforward_point_in_local_frame = this->localFramePoint(this->getFeedforwardPoint());
	this->deviation_path_point_in_local_frame = this->localFramePoint(this->getDeviationPathPoint());
	
	PointArr points = this->getCurvatureDetectionPoints();
	this->curvature_detection_points_in_local_frame.clear();
	for (PointArrIt it = points.begin(); it < points.end(); it++) {
		this->curvature_detection_points_in_local_frame.push_back(this->localFramePoint(*it));
	}
	this->has_local_frame = true;
}
示例#6
0
文件: gpstest.cpp 项目: Trogie/gipsy
int main(int argc, char **argv)
{
    //cout << "Getting ports" << endl;
    //PortList ports = get_ports(true);

    Gps *gps = make_gps("/dev/ttyUSB0", GPS_FLYMASTER);
    cout << "GPS type: " << gps->gpsname << ", unitid: " << gps->gpsunitid << endl;
    cerr << "Downloading" << endl;
    gps->selected_tracks.push_back(0);
    try {
        PointArr result = gps->download_tracklog(NULL, NULL);
        for (int i=0; i < result.size(); i++) {
            Trackpoint *point = &result[i];
            cout << point->lat << " " << point->lon << " " << point->new_trk << " " << point->time << endl;
        }
    } catch (Exception e) {
        cerr << e.error << endl;
        exit(1);
    }
    
/*
    for (unsigned int i=0; i < ports.size(); i++) {
	cout << "Device: " << ports[i].device << ", devname: " << ports[i].devname << endl;
        try {
            Gps *gps = make_gps(ports[i].device, GPS_GARMIN);
            if (gps) {
                cout << "GPS type: " << gps->gpsname << ", unitid: " << gps->gpsunitid << endl;
                PointArr result;
                result = gps->download_tracklog(NULL, NULL);
                for (int i=0; i < result.size(); i++) {
                    Trackpoint *point = &result[i];
                    cout << point->lat << " " << point->lon << " " << point->new_trk << " " << point->time << endl;
                }
                cout << "done" << endl;
            } else {
                cout << "GPS open failed" << endl;
            }
        } catch (Exception e) {
            cout << "Got exception, GPS open failed: " << e.error << endl;
        }
    }
*/
}
PointArr PathFollowingGeometry::interpolate(Point p1, Point p2)
{
	PointArr result;
	double length_between_waypoints = distance(p1, p2);
	int temp = round(length_between_waypoints*INTERPOLATION_PTS_PER_M);
	unsigned int num_points = std::max(1, temp);
	
	//ROS_INFO("Interpolating %f with %d pts", length_between_waypoints, num_points);
	
	result.push_back(p1);
	for (unsigned int i = 1; i < num_points-1; i++) {
		double fraction = (double)(i/(double)num_points);
		//ROS_INFO("Fraction %f", fraction);
		double x = p1.x+(p2.x-p1.x)*fraction;
		double y = p1.y+(p2.y-p1.y)*fraction;
		result.push_back(CreatePoint(x, y));
	}
	result.push_back(p2);
	return result;
}
Point PathFollowingGeometry::getClosestPointFromSet(Point referencePoint, PointArr pointSet)
{
	Point result;
	if (pointSet.size() > 0) {
		result = pointSet.at(0);
		double closest_distance = distance(referencePoint, result);
		for (PointArrIt it = pointSet.begin()+1; it < pointSet.end(); it++) {
			double new_distance = distance(referencePoint, *it);
			
			//ROS_INFO("%.2f,%.2f -> %.2f,%.2f = %.4f", referencePoint.x, referencePoint.y, (*it).x, (*it).y, new_distance);
			if (new_distance < closest_distance) {
				closest_distance = new_distance;
				result = *it;
			}
		}
		
	//	ROS_WARN("Shortest %.2f,%.2f -> %.2f,%.2f = %.4f", referencePoint.x, referencePoint.y, result.x, result.y, closest_distance);
	}
	else {
		result = referencePoint;
	}
	return result;
}
示例#9
0
文件: tracklog.cpp 项目: Trogie/gipsy
/* Expect that the array is sorted */
NS_IMETHODIMP Tracklog::IgcSelectPoints(uint32_t count, int32_t *points, 
					IGPSIGC **_retval)
{
    PointArr selection;
    int lastidx = -1;

    if (!count) {
	*_retval = NULL;
	return NS_OK;
    }

    for (unsigned int i=0; i < count; i++) {
	int idx = points[i];
	if (idx < 0 || idx >= (int) igc->tracklog.size())
	    return NS_ERROR_UNEXPECTED;

	// Check that the input array is sorted
	if (idx < lastidx)
	    return NS_ERROR_UNEXPECTED;

	lastidx = idx;

	selection.push_back(igc->tracklog[idx]);
    }
    
    Igc *newigc = new Igc(*igc);
    newigc->tracklog = selection;

    if (igc->validate())
	newigc->gen_g_record();

    *_retval = new Tracklog(newigc);
    NS_ADDREF(*_retval);

    return NS_OK;
}
void MotionControlNode::callbackGoal(const lunabotics::Goal::ConstPtr &msg)
{
	this->_waypoints.clear();
	
	this->_motionConstraints.point_turn_angle_accuracy = msg->angleAccuracy;
	this->_motionConstraints.point_turn_distance_accuracy = msg->distanceAccuracy;
	
	//Specify params
	Point goal = Point_from_geometry_msgs_Point(msg->point);
		//ROS_INFO("Requesting path between (%.1f,%.1f) and (%.1f,%.1f)",
		//	  this->_currentPose.position.x, this->_currentPose.position.y,
		//	  goal.x, goal.y);
	float resolution;
	PathPtr path = this->findPath(this->_currentPose, goal, resolution);
	
	if (path->is_initialized()) {
		std::stringstream sstr;
		
		nav_msgs::Path pathMsg;
		pathMsg.header.stamp = ros::Time::now();
		pathMsg.header.seq = this->_sequence++;
		pathMsg.header.frame_id = "map";
		
		
		PointArr corner_points = path->cornerPoints(resolution);
		PointArr pts;
		
		
		if (this->_steeringMode == lunabotics::proto::ACKERMANN) {
			unsigned int size = corner_points.size();
			if (size > 2) {
				delete this->_trajectory;
				this->_trajectory = new Trajectory();
				Point startPoint = corner_points.at(0);
				Point endPoint = corner_points.at(size-1);
				IndexedPointArr closest_obstacles = path->closestObstaclePoints(resolution);
				unsigned int obst_size = closest_obstacles.size();
				
				pts.push_back(startPoint);
			
				//Get bezier quadratic curves for each point-turn
				for (unsigned int i = 1; i < size-1; i++) {
					Point q0, q2;
					Point prev = corner_points.at(i-1);
					Point curr = corner_points.at(i);
					Point next = corner_points.at(i+1);
					
					bool hasObstacle = false;
					Point obstaclePoint;
					
					//Since obstacle is the center of occupied cell, we want p to be at its edge
					if (obst_size > 0) {
						int start = std::min(obst_size-1, i-1);
						for (int j = start; j >= 0; j--) {
							IndexedPoint indexedObstacle = closest_obstacles.at(j);
							if (indexedObstacle.index == (int)i) {
								hasObstacle = true;
								obstaclePoint = indexedObstacle.point;
								break;
							}
						}
					}
					
					
					if (i == 1) {
						q0 = prev;
					}
					else {
						q0 = midPoint(prev, curr);
					}
					if (i == size-2) {
						q2 = next;
					}
					else {
						q2 = midPoint(next, curr);
					}
					
					TrajectorySegment s;
					if (hasObstacle) {
						Point p = midPoint(obstaclePoint, curr);
						s.curve = CreateConstrainedBezierCurve(q0, curr, q2, p, this->_motionConstraints.bezier_segments_num);
						//ROS_INFO("Curve from tetragonal q0=(%f,%f) q1=(%f,%f), q2=(%f,%f), p=(%f,%f)", q0.x, q0.y, curr.x, curr.y, q2.x, q2.y, p.x, p.y);
					}
					else {
						s.curve = new BezierCurve(q0, curr, q2, this->_motionConstraints.bezier_segments_num);
						//ROS_INFO("Curve without tetragonal q0=(%f,%f) q1=(%f,%f), q2=(%f,%f)", q0.x, q0.y, curr.x, curr.y, q2.x, q2.y);
					}
					this->_trajectory->appendSegment(s);
				}	
				pts = this->_trajectory->getPoints();
				pts.push_back(endPoint);
				
				ROS_WARN("Trajectory max curvature %f (Min ICR radius %f m)", this->_trajectory->maxCurvature(), 1/this->_trajectory->maxCurvature());
					
			}
			else {
				pts = corner_points;
			}
		}
		else {
			pts = corner_points;
		}
		
		int poseSeq = 0;
		for (PointArr::iterator it = pts.begin(); it != pts.end(); it++) {
			Point pt = *it;
			
			//float x_m = node.x*resolution;
			//float y_m = node.y*resolution;
			//float x_m = pt.x;
			//float y_m = pt.y;
			
			this->_waypoints.push_back(pt);
	//		sstr << "->(" << x_m << "," << y_m << ")";
			
			
			geometry_msgs::PoseStamped pose;
			pose.header.seq = poseSeq++;
			pose.header.stamp = ros::Time::now();
			pose.header.frame_id = "map";
			pose.pose.position = geometry_msgs_Point_from_Point(pt);
			pose.pose.orientation = tf::createQuaternionMsgFromYaw(0);
			pathMsg.poses.push_back(pose);
		}
		this->_PIDHelper->setTrajectory(pts);
		
		 this->_waypointsIt = this->_steeringMode == lunabotics::proto::ACKERMANN ? this->_waypoints.begin() : this->_waypoints.begin()+1;		
	//	ROS_INFO("Returned path: %s", sstr.str().c_str());
		//Point waypoint = this->_waypoints.at(0);
		//ROS_INFO("Heading towards (%.1f,%.1f)", (*this->_waypointsIt).x, (*this->_waypointsIt).y);
		
		this->_publisherPath.publish(pathMsg);
		
		this->_autonomyEnabled = true;
		lunabotics::ControlParams controlParamsMsg;
		controlParamsMsg.driving = this->_autonomyEnabled;
		controlParamsMsg.next_waypoint_idx =  this->_waypointsIt < this->_waypoints.end() ?  this->_waypointsIt-this->_waypoints.begin()+1 : 0;
		this->_publisherControlParams.publish(controlParamsMsg);
	}
	else {
		ROS_INFO("Path is empty");
	}
	
	delete path;


}
示例#11
0
文件: tracklog.cpp 项目: Trogie/gipsy
NS_IMETHODIMP Tracklog::IgcLoadGPX(nsILocalFile *file)
{
    nsresult rv;
    int64_t fsize;
    
    nsCOMPtr<nsIDOMParser> domparser = do_CreateInstance("@mozilla.org/xmlextras/domparser;1", &rv);
    if (NS_FAILED(rv)) 
	return rv;
    
    file->GetFileSize(&fsize);

    nsCOMPtr<nsIFileInputStream> instream=
	    do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv);
    if (NS_FAILED(rv))
	return rv;
    
    rv = instream->Init(file, PR_RDONLY, 0, nsIFileInputStream::CLOSE_ON_EOF);
    if (NS_FAILED(rv))
	return rv;

    nsCOMPtr<nsIDOMDocument> document;
    
    rv = domparser->ParseFromStream(instream, "UTF-8", fsize, "text/xml", getter_AddRefs(document));
    if (NS_FAILED(rv))
	return rv;

    nsCOMPtr<nsIDOMNodeList> seglist;
    rv = document->GetElementsByTagName(NS_LITERAL_STRING("trkseg"), getter_AddRefs(seglist));
    if (NS_FAILED(rv))
	return rv;
    uint32_t listlength;
    seglist->GetLength(&listlength);
    
    PointArr parr;
    for (uint32_t i=0; i < listlength; i++) {
	nsCOMPtr<nsIDOMNodeList> pointlist;
	nsCOMPtr<nsIDOMNode> trkseg;
	seglist->Item(i, getter_AddRefs(trkseg));

	rv = document->GetElementsByTagName(NS_LITERAL_STRING("trkpt"), getter_AddRefs(pointlist));
	if (NS_FAILED(rv))
	    return rv;
	
	uint32_t pointnum;
	pointlist->GetLength(&pointnum);
	for (uint32_t j=0; j < pointnum; j++) {
	    nsCOMPtr<nsIDOMNode> trkpt_n;
	    pointlist->Item(j, getter_AddRefs(trkpt_n));
	    nsCOMPtr<nsIDOMElement> trkpt(do_QueryInterface(trkpt_n));
	    
	    Trackpoint point;
	    point.new_trk = (j == 0);

	    /* Lat & Lon */
	    nsAutoString lstr;
	    trkpt->GetAttribute(NS_LITERAL_STRING("lat"), lstr);
	    point.lat = my_atof(NS_ConvertUTF16toUTF8(lstr).get());
	    trkpt->GetAttribute(NS_LITERAL_STRING("lon"), lstr);
	    point.lon = my_atof(NS_ConvertUTF16toUTF8(lstr).get());

	    string alt = get_subelement(NS_LITERAL_STRING("ele"), trkpt);
	    point.gpsalt = my_atof(alt.c_str());
	    
	    string time = get_subelement(NS_LITERAL_STRING("time"), trkpt);
	    point.time = decode_time(time);
	    parr.push_back(point);
	}
    }
    igc = new Igc(parr, "GPX Import", 0);
    make_break_points();

    return NS_OK;
}
示例#12
0
文件: garmin.cpp 项目: Trogie/gipsy
/* Download tracklog using A300, A301 & A302 protocols */
PointArr GarminGps::A30xdownload(int proto, dt_callback cb, void *arg) 
{
    uint8_t pid = 0;
    Data data;
    PointArr result;
    uint16_t cmdid;
    Trackpoint point;
    int pktcount = 0;
    bool suspend = false; // If true, do not save trackpoints
    int dataproto = (proto == 300) ? 300 : proto_data[proto][1];
    
    send_command(Cmnd_Transfer_Trk);
    int exp_count = get_records();

    if (!exp_count) // No trackpoints expected
	return result;

    while (pid != Pid_Xfer_Complete) {
	phys->recv_packet(pid, data);

	if (cb) {
	    bool rv = cb(arg, pktcount, exp_count); 
	    if (!rv) { // Abort
		send_command(Cmnd_Abort_Transfer);
		throw Exception("Aborted.");
	    }
	}
	pktcount++;
	
	switch (pid) {
	case Pid_Trk_Hdr:
	    // if the protocol is not D310 || D312
	    if (proto_data[proto][0] != 310 && proto_data[proto][0] != 312)
		break;
	    // If we are "high version", download all tracklogs
	    if (gpsid >= NEW_VERSION)
		break;
	    // else throw out everything that is not 'active log'
	    if (!strncmp((const char *)&data.buffer[2], "ACTIVE LOG", data.size-2))
		suspend = false;
	    else
		suspend = true;
	    break;
	case Pid_Trk_Data:
	    if (!suspend) {
		point = decode_trk_data(data, dataproto);
                
                // Discard if latitude > 90 
                // Foretrex signals lost fix with 0x7FFFFFFF values, but latitude
                // should be in (-90,90) anyway
                if (point.lat > 90 || point.lat < -90) 
                    ;
                // If the point is older then the last point, discard the
                // last point
		else if (gpsid < NEW_VERSION && result.size() && point.time < result[result.size() - 1].time)
		    result[result.size() - 1] = point;
                else
		    result.push_back(point);
	    }
	    break;
	case Pid_Xfer_Complete:
	    cmdid = le16_to_host(*((uint16_t *)data.buffer));
	    if (cmdid != Cmnd_Transfer_Trk)
		throw Exception("Bad command id on command completion.");
	    break;
	default:
	    throw Exception("Unexpected data packed.");
	}
    }

    return result;
}