// determines whether the next interpolated line segment along the path should be used
// by checking the distance the quadcopter has traveled along the line
void checkDistanceTraveled(void)
{
   double line_dist = 0;
   double line_dist_trav = 0;
   if(closestPointIndex != prevClosestPointIndex)
    {
    	line_dist =  distanceFormula ( pathPose.poses[closestPointIndex].position.x, pathPose.poses[prevClosestPointIndex].position.x, 
                                        pathPose.poses[closestPointIndex].position.y, pathPose.poses[prevClosestPointIndex].position.y );
        line_dist_trav =  distanceFormula ( closestPointOnLine.pose.position.x, pathPose.poses[prevClosestPointIndex].position.x, 
                                        closestPointOnLine.pose.position.y, pathPose.poses[prevClosestPointIndex].position.y );
        if( (line_dist_trav/line_dist) < LINE_DIST_RANGE )
        {
        	closestPointIndex = prevClosestPointIndex;
        }
    }
}
// Outputs a constant velocity term for the sliding mode controller
void calcConstVelTerm(void)
{
    double globalAngle = 0;
    double vector1[2] = {1, 0};
    double vector2[2] = {nextPointClosest.pose.position.x - closestPointOnLine.pose.position.x, 
                        nextPointClosest.pose.position.y - closestPointOnLine.pose.position.y};
    double dotProduct = (vector1[0]*vector2[0]) + (vector1[1]*vector2[1]);
    double absProduct = distanceFormula(nextPointClosest.pose.position.x, closestPointOnLine.pose.position.x,
                                        nextPointClosest.pose.position.y, closestPointOnLine.pose.position.y);
    
    if(absProduct == 0)
    {
    	std::cout << "---------------------------------------------------------------------\n";
    	std::cout << "Closest Point(reference):\nIndex: "<< closestPointIndex << "\n" << closestPointOnLine << "\n\n";
        std::cout << "Next Point:\n" << nextPointClosest << "\n";
        std::cout << "---------------------------------------------------------------------\n\n";
    }
    
    //if(absProduct != 0)
    //{
    	globalAngle = acos(dotProduct/absProduct);
    //} 
    //else globalAngle = 0; // FIXME: check output
    
    if(nextPointClosest.pose.position.y - closestPointOnLine.pose.position.y >= 0) // Check if angle is over 180 degrees
    {
        constVelTerm.linear.x = cos(globalAngle)*PATH_VEL;
        constVelTerm.linear.y = -sin(globalAngle)*PATH_VEL;
    }
    else
    {
        constVelTerm.linear.x = cos(2*PI - globalAngle)*PATH_VEL;
        constVelTerm.linear.y = -sin(2*PI - globalAngle)*PATH_VEL;
    }
}
// Interpolates to find closest point on the path using the bisection method
void findClosestPointOnLine(void)
{
    double point1[2] = {0,0};
    double point2[2] = {0,0};
    
    if(closestPointOnLine.pose.position.x != 0 && closestPointOnLine.pose.position.y != 0) // skip first iteration
    {
    	checkDistanceTraveled(); 
    }
    
    /*if(prevClosestPointIndex > closestPointIndex)
    {
    	closestPointIndex = prevClosestPointIndex + 1;
    }*/
    
    point1[0] = pathPose.poses[closestPointIndex].position.x;
    point1[1] = pathPose.poses[closestPointIndex].position.y;
    point2[0] = pathPose.poses[closestPointIndex + 1].position.x;
    point2[1] = pathPose.poses[closestPointIndex + 1].position.y;
    nextPointClosest.pose.position.x = point2[0];
    nextPointClosest.pose.position.y = point2[1];
    
    double distance1 = 0;
    double distance2 = 0;
    for(int i=0; i<NUM_ITERATIONS; i++)
    {
        distance1 = distanceFormula(poseEst.pose.position.x, point1[0], poseEst.pose.position.y, point1[1]);
        distance2 = distanceFormula(poseEst.pose.position.x, point2[0], poseEst.pose.position.y, point2[1]);
        calculateMidPoints (point2[0], point1[0], point2[1], point1[1]);
        if(distance1 < distance2)
        {
            point2[0] = midpoints[0];
            point2[1] = midpoints[1];
        }
        else
        {
            point1[0] = midpoints[0];
            point1[1] = midpoints[1];
        }
    }
    
    closestPointOnLine.pose.position.x = midpoints[0];
    closestPointOnLine.pose.position.y = midpoints[1];
}
Esempio n. 4
0
unsigned long verifyWeightsAndAssign(ResultList * results, Node * origin)
{
  ResultList * itr = results;
  while(itr->next != NULL) {
    Node * node1 = findVertexByValue(itr->value, origin);
    Node * node2 = findVertexByValue(itr->next->value, origin);
    int dist = distanceFormula(node1, node2);
    node2->weight = node1->weight + dist;
    itr = itr->next;
  }
  printf("I found the weight: %ld\n", itr->weight);
  return itr->weight;
}
Esempio n. 5
0
void updateAdjacentWeights(Node * internal, Node * origin)
{
  EdgeList * tmp = internal->edges;
  while(tmp != NULL) {
    Node * hld = findVertexByValue(tmp->connectedto, origin);
    int dist = distanceFormula(hld, internal);
    if((dist + internal->weight) < hld->weight) {
      hld->weight = dist + internal->weight;
      hld->prev = internal->value;
    }
    tmp = tmp->next;
  }
  internal->ingraph = 0;
}
// This function will identify the closest point on the path to the quadcopter
bool calcClosestPointOnPath (void)
{
  double closestDistance = 0; // distance from pose estimation to closest point on the path
  double tempClosestDistance = 0;
  
  for(int i = 0; i < pathPose.poses.size(); i++)
  {
    if ( (pathPose.poses[i].position.x == 0) && (pathPose.poses[i].position.y == 0) )
        {
            //continue;
            break;
        }
    tempClosestDistance = distanceFormula ( pathPose.poses[i].position.x, poseEst.pose.position.x, 
                                        pathPose.poses[i].position.y, poseEst.pose.position.y );

    if ( (closestDistance == 0) || (closestDistance > tempClosestDistance) )
      { 
        closestDistance = tempClosestDistance;
        prevClosestPointIndex = closestPointIndex;
        closestPointIndex = i;
      }
  }
}
Esempio n. 7
0
void crank(double ***matrix, double ***matrix_np1, int nx, int ny, int nz, double alpha, double dx, double C, int border, int NT){
    int i, j, k, l, f, g, h;
    double d;
    int b0;
    int bn;
    int when = 1;
    double ***temp;
    double *tempb;
    double *mat_b = (double*) malloc(sizeof(double)* nx*ny*nz);
    double *mat_newb = (double*) malloc(sizeof(double)* nx*ny*nz);
    double **mat_A = (double**) malloc(sizeof(double*) *nx*ny*nz);
    double **augmented = (double**) malloc(sizeof(double*) *nx*ny*nz);
    double *data = (double*) malloc(sizeof(double) * nx*nx*ny*ny*nz*nz);
    double *augdata = (double*) malloc(sizeof(double) * nx*nx*ny*ny*nz*nz+nx*ny*nz);/*care for last column - b*/
	    /*now need to make augmented matrix to pass into rref*/
	    for(h=0;h<nx*ny*nz;h++){
		*(augmented+h) = augdata + h*nx*ny*nz+1;/*care for augmented with b*/
	    }
    switch(border){
	case 0:
	    b0 = 0;
	    bn = 0;
	    break;
	case 1:
	    b0 = 3;
	    bn = 3;
	    break;
	case 2:
	    b0 = nx;
	    bn = 0;
	    break;
	default :
	    b0 = 0;
	    bn = 0;
    }
    print3DMatrix(matrix, nx, ny, nz, dx, dx, dx, when);
    when++;
    /*malloc space for A*/
    for(i=0;i<nx*ny*nz;i++){
	*(mat_A+i) = data + i*nx*ny*nz;
    }
    /*make matrix b which is 1-D from init 3-D matrix --flattened*/
    for(i = 0 ; i< nx ; i++){
	for(j = 0 ; j < ny ; j++){
	    for(k = 0 ; k < nz ; k++){
		*(mat_b + i*ny*nz + j*nz + k) = *(*(*(matrix + i) + j) +k);
	    }
	}
    }

    for(k=0;k<NT;k++){


	for(i = 0; i< nx*ny*nz ; i++){
	    for(j = 0;j< nx*ny*nz ; j++){
		if( i == j){
		    *(*(mat_A+i)+j) = /*mat_b[i]**/1+6.0*C;
		}	
		else if (i == j-1 ){
		    if( i != 0%nz){
			*(*(mat_A+i)+j) = /**(mat_b + i-1)**/(-1.0*C);
		    }
		    else if(i ==0%nz && border== 2){
			*(*(mat_A+i)+j) = /**(mat_b + (i-1)%nz)**/(-1.0*C);

		    }

		}
		else if (i == j+1){
		    if( i != (nz-1)%(nz-1)){
			*(*(mat_A+i)+j) =/* *(mat_b + i+1)**/(-1.0*C);
		    }
		    else if(i == (nz-1)%(nz-1) && border == 2){
			*(*(mat_A+i)+j) =/* *(mat_b + (i+1)%nz)**/(-1.0*C);

		    }

		}
		else if(i == j-ny*nz){
		    if( i > ny*nz){
			*(*(mat_A+i)+j) =/* *(mat_b + i-ny*nz)**/(-1.0*C);
		    }
		    else if(i <= ny*nz && border == 2){
			*(*(mat_A+i)+j) =/* *(mat_b + (i-ny*nz)%(nx*ny*nz))**/(-1.0*C);

		    }
		}
		else if(i == j+ny*nz){
		    if( i < ny*nz){
			*(*(mat_A+i)+j) = /**(mat_b + i+ny*nz)**/(-1.0*C);
		    }
		    else if(i >= ny*nz && border == 2){
			*(*(mat_A+i)+j) = /**(mat_b + (i+ny*nz)%(nx*ny*nz))**/(-1.0*C);

		    }

		}
		else if(i == j+ny){
		    if( i != (ny-1)%(ny-1)){
			*(*(mat_A+i)+j) =/* *(mat_b + i+ny)**/(-1.0*C);
		    }
		    else if(i ==(ny-1)%(ny-1) && border == 2){
			*(*(mat_A+i)+j) =/* *(mat_b + (i+ny)%ny)**/(-1.0*C);

		    }

		}
		else if(i == j-ny){
		    if( i != 0%ny){
			*(*(mat_A+i)+j) =/* *(mat_b + i-ny)**/(-1.0*C);
		    }
		    else if(i == 0%ny && border == 2){
			*(*(mat_A+i)+j) =/* *(mat_b + (i-ny)%ny)**/(-1.0*C);

		    }

		}
		else{
		    *(*(mat_A+i)+j) = 0.0;

		}
	    }

	    /*at this point A is created*/
	    for(g = 0; g< nx*ny*nz ; g++){
		for(h = 0;h< nx*ny*nz ; h++){
		    if(h == nx*ny*nz-1){
			*(*(augmented+g)+h) = *(mat_b+g);
		    }
		    else{
			*(*(augmented+g)+h) = *(*(mat_A+g)+h);
		    }
		}
	    }
	    /*at this point i have Ax=b in augmented matrix form to use rref on {augmented | b}  */
	    rref(augmented, nx*ny*nz,  nx*ny*nz+1);
	    /*now i need to extract the nx*ny*nz+1 column to cpy back to my old mat_b, mat_A*/
	    for(g = 0; g< nx*ny*nz ; g++){
		for(h = 0;h< nx*ny*nz ; h++){
		    if(h == nx*ny*nz-1){
			*(mat_newb+g)  = *(*(augmented+g)+h);
		    }
	/*	    else{
			*(*(mat_A+g)+h) = *(*(augmented+g)+h);
		    }*/
		}
	    }
	    d = distanceFormula(mat_newb, mat_b, nx*ny*nz);
	    //printf("%f \n",d);
	    tempb = mat_b;
	    mat_b = mat_newb;
	    mat_newb = tempb;

	    for(f = 0 ; f< nx ; f++){
		for(g = 0 ; g < ny ; g++){
		    for( h = 0 ; h < nz ; h++){
			*(*(*(matrix + f) + g) +h) =  *(mat_b + f*ny*nz + g*nz + h);
		    }
		}
	    }
	}
	if( k==0){
	    print3DMatrix(matrix, nx, ny, nz, dx, dx, dx, when);
	    when++;
	}
    }
}
int main(int argc, char **argv)
{
    ros::init(argc, argv, "path_follower"); //Ros Initialize
    ros::start();
    ros::Rate loop_rate(T); //Set Ros frequency to 50/s (fast)

    ros::NodeHandle n;
    ros::Subscriber pathSub;
    ros::Subscriber poseEstSub;
    ros::Subscriber centroidEstSub;
    ros::Publisher goalPub;
    ros::Publisher velPub;
    ros::Publisher centroidPub;
    ros::Publisher gaussPosition;

    pathSub = n.subscribe<geometry_msgs::PoseArray>("/path", 1, pathCallback);
    poseEstSub = n.subscribe<geometry_msgs::PoseStamped>("/poseEstimation", 1, poseEstCallback);
    centroidEstSub = n.subscribe<tf2_msgs::TFMessage>("/poseEstimationC", 1,  centroidEstCallback);
    goalPub = n.advertise<geometry_msgs::PoseStamped>("/goal_pose", 1000, true);
    centroidPub = n.advertise<geometry_msgs::PoseArray>("/gauss", 1000, true);
    velPub = n.advertise<geometry_msgs::Twist>("/path_vel", 1000, true);
    gaussPosition = n.advertise<geometry_msgs::PoseStamped>("/poseEstimation", 1000, true);
   
    // Initialize msgs and flags
    newPath = false;
    closestPointOnLine.pose.position.x = 0;
    closestPointOnLine.pose.position.y = 0;
    constVelTerm.linear.x = 0;
    constVelTerm.linear.y = 0;
    constVelTerm.linear.z = 0;
    constVelTerm.angular.x = 0;
    constVelTerm.angular.y = 0;
    constVelTerm.angular.z = 0;
    gauss.poses.resize(50);
    gPos.header.frame_id="gauss";

    while (ros::ok()) 
    {
        ros::spinOnce();
        
        if(newPath) // check if a new path has been set
        {
            findIndexOfLastPointOnPath();
            if(isOpenLoop) // path given is OPEN
            {
                newPath = false; // reset flag
                goalPose.pose = (pathPose.poses)[0]; // publish first point on path
                goalPose.pose.orientation = tf::createQuaternionMsgFromYaw(0);
		if (pathPose.header.frame_id.compare("SWARM")==0){
			gauss.poses[0]=goalPose.pose;
			gauss.poses[0].position.z=.25;
			gPos.pose=goalPose.pose;
			gPos.pose.position.z=.25;
			centroidPub.publish(gauss);
			gaussPosition.publish(gPos);
		}
		else {
			goalPub.publish(goalPose);
		}
                
                while( distanceFormula(pathPose.poses[0].position.x, poseEst.pose.position.x, 
                                        pathPose.poses[0].position.y, poseEst.pose.position.y) >= BOUNDARY_RADIUS ) // FIXME: Implement this sleep cycle as a function
                    {
                        ros::spinOnce();
                        loop_rate.sleep();
                        if(newPath || !ros::ok())
                        {
                            break;
                        }
                    }
                closestPointIndex = 0; // initialize to first point in path 
                while(closestPointIndex != lastPointOnPathIndex) // use interpolation
                {
                    if(newPath || !ros::ok()) // FIXME: break out if a different pose is published
                    {
                        break;
                    }
			//std::cout << "goalPose" <<  gPos <<"\n\n";
                    //ROS_INFO("on interpolation loop OPEN\n");
                    findClosestPointOnLine();
                    closestPointOnLine.pose.orientation = tf::createQuaternionMsgFromYaw(0);
                    calcConstVelTerm();
                   // std::cout << "Goal pose:\n" << closestPointOnLine << "\n\n";
                    //std::cout << "Constant vel:\n" << constVelTerm << "\n\n";
                    velPub.publish(constVelTerm);
                    if (pathPose.header.frame_id.compare("SWARM")==0){
			gauss.poses[0]=goalPose.pose;
			gauss.poses[0].position.z=.25;
			gPos.pose=goalPose.pose;
			gPos.pose.position.z=.25;
			centroidPub.publish(gauss);
			gaussPosition.publish(gPos);
		}
		else {
			goalPub.publish(goalPose);
		}
                    //pathPose.poses[closestPointIndex].position.x = 0;
                    //pathPose.poses[closestPointIndex].position.y = 0;
                    calcClosestPointOnPath();
                    ros::spinOnce();
                    loop_rate.sleep();
                }
                goalPose.pose = (pathPose.poses)[lastPointOnPathIndex]; // publish final point on path
                goalPose.pose.orientation = tf::createQuaternionMsgFromYaw(0);
                if (pathPose.header.frame_id.compare("SWARM")==0){
			gauss.poses[0]=goalPose.pose;
			gauss.poses[0].position.z=.25;
			gPos.pose=goalPose.pose;
			gPos.pose.position.z=.25;
			centroidPub.publish(gauss);
			gaussPosition.publish(gPos);
		}
		else {
			goalPub.publish(goalPose);
		}
                //pathPose.poses[closestPointIndex].position.x = 0;
                //pathPose.poses[closestPointIndex].position.y = 0;
		constVelTerm.linear.x = 0;
		constVelTerm.linear.y = 0;
		velPub.publish(constVelTerm);
		// FIXME: reset path variables
		//prevClosestPointIndex = 0;
            }
            else // path given is CLOSED
            {
                newPath = false; // reset flag and set stopping condition for while loop
                calcClosestPointOnPath();
                sortPathArray(); // array now starts at the closest point index
                closestPointIndex = 0;
                while( !newPath || ros::ok() ) // while no new path has been published
                {

                    //ROS_INFO("on interpolation loop CLOSED");
                    findClosestPointOnLine();
                    closestPointOnLine.pose.orientation = tf::createQuaternionMsgFromYaw(0);
                    calcConstVelTerm();
                    //std::cout << "Goal pose:\n" << closestPointOnLine << "\n\n";
                    //std::cout << "Constant vel:\n" << constVelTerm << "\n\n";
                    velPub.publish(constVelTerm);
                    goalPub.publish(closestPointOnLine);
                    calcClosestPointOnPath();
                    if (closestPointIndex == lastPointOnPathIndex)
                    {
                        closestPointIndex = 0;
                    }
                    ros::spinOnce();
                    loop_rate.sleep();
                }
                constVelTerm.linear.x = 0;
		constVelTerm.linear.y = 0;
		velPub.publish(constVelTerm);
		//ROS_INFO("finished CLOSED loop");
            }
        }
        
        loop_rate.sleep();
    }
}