Exemplo n.º 1
0
unsigned int AS_Engine_man( int newCall, int hoisting, int hoisted, int verbose, const AS_shaper *shp,
			    double uCommand, double uR, double DLc, double omega, double amaxH, double amaxS, double dt, 
			    double *aRp, AS_phasorSet *Setp ) 
{ 
  unsigned int sts=0;
  double SaComp,Sa0;

  if (shp->ID == AS_NO_AS) { /* If NO_AS shaper, remove unnecessary constraints */
    hoisting=0;
    hoisted=0;
    amaxS=amaxH;
  }

  /* Allocate or reallocate phasors if needed */

  /* Correct for hoisting */
  if (hoisting) { 

    /* Calculate compensation acceleration SaComp=-1.5*DLc*Dth/cos(thc) */ 
    SaComp=-1.5*DLc*(-getX(Setp))*omega/cos(-getY(Setp)); 

    /* If there is a chance SaComp can't be allocated - reduce and allocate residual separately */
    if (fabs(SaComp)>amaxH-amaxS) { 
      Sa0=AS_SIGN(SaComp)*(amaxH-amaxS);
      addPhasor(Setp, 0.0, -omega*dt, SaComp-Sa0); /* Add compensation residual */
      AS_collapseSet(Setp, shp, amaxS);
      SaComp=Sa0;
      sts |= AS_ERR_ACC_MARGIN;
      if (verbose >= AS_VERB_ERR)
	printf("AntiSway/Engine_man: Partial compensation through residual phasor addition: %f SaComp needed, %f available |amax margin|\n",SaComp,amaxH-amaxS);
    }
    /* Adjust set so that uCommand is still met, given the compensation phasor */
    sts |= makeSet_man(Setp, shp, uCommand-SaComp*dt, uR, amaxS, omega, verbose); 

    /* Add the compensation phasor */
    addPhasor(Setp, 0.0, -omega*dt, SaComp); 
    cleanSet(Setp);

  }

  /* If no hoisting -  adjust set if new command or new omega */
  else if (newCall || hoisted) { 
    sts |= makeSet_man(Setp, shp, uCommand, uR, amaxS, omega, verbose); 
  }    

  /* Step up time and return error status */
  *aRp=timeStepSet(Setp, omega*dt); 
  return sts;
}
Exemplo n.º 2
0
static unsigned int mergeSet(AS_phasorSet *Setp, const AS_shaper *shp, double SuDiff, double amax, double omega, int reflected, int verbose) 
{
  double ext, aRatio, uDiff, offset, S, tmp, offsetlim;
  int n, count, addCount;

  /* Initialize variables */
  S=AS_SIGN(SuDiff); /* Extracting the sign */
  uDiff=fabs(SuDiff); /* Absolute value */
   
  offset=0.0; /* Phase offset. Positive*/
  offsetlim=(reflected ? (shp->phi[shp->N - 1] - Setp->ph[Setp->N - 1].phiEnd) : DBL_MAX);
  count = 0;
  addCount = 0;
  while (fabs(uDiff) > AS_EPSILON && (offsetlim-offset > AS_EPSILON && count < AS_MERGE_ITER_LIM)) { /* Allocate phasors until uCommand is attained */
    ext=shp->DMin; /* Maximum phase extension of added phasors, initialized to DMin of shaper. Positive */
    aRatio=(reflected ? 1.0 : (shp->AMin + shp->AMax)/shp->AMin); /* Maximum possible relative magnitude of acceleration. Positive */
    for (n=0; n < shp->N; n++) /* Repeat for all the pulses in the shaper */
      phaseInterval(Setp, shp->phi[n]-offset, S*shp->A[n]*amax, AS_SIGN(S*shp->A[n])*AS_MAX(1.0,fabs(shp->A[n]))*amax, &aRatio, &ext, reflected);
    if (aRatio>0.0) { /* Possible to allocate phasors at current offset value ? */
      tmp=omega/(aRatio*shp->ASum*amax);
      ext=AS_MIN(ext,uDiff*tmp);
      uDiff-=ext/tmp; /* count down uDiff, the velocity change remaining to place out */
      for (n=0; n < shp->N; n++,addCount++) { /* allocate phasors at shaper locations  */
	tmp=shp->phi[n]-offset;
	addPhasor(Setp, tmp, tmp-ext, S*aRatio*shp->A[n]*amax); /* add phasor at phi[n]-offset of extension ext and */
                                                              /* acceleration sign*ratio*shaperMag*amax to the set */
      }
      cleanSet(Setp);
    }
    offset+=ext; /* count up offset */
    count++;
  } /* End of while loop */

  if (verbose >= AS_VERB_ALL)
    printf("\nAntiSway/mergeSet exited while loop, count=%d. Added %d phasors totally.\n",count,addCount);

  if (offsetlim-offset <= AS_EPSILON) /* Could not allocate phasors further (should be possible only in reflected mode). */
    return AS_ERR_MERGE_OFFSETLIM;

  if (count>=AS_MERGE_ITER_LIM) {
    if (verbose >= AS_VERB_ERR)
      AS_diagnose(Setp,omega,reflected,SuDiff,uDiff);
    return AS_ERR_MERGE_ITER;
  }

  return 0;
}
Exemplo n.º 3
0
unsigned RelationManager::cleanMap(map<const Class *, set<const Class *> > &map)
{
	unsigned deletedRecords = 0;
	std::set<const Class*>::iterator setIter;

	// associative-container erase idiom
	for (auto it = map.begin(); it != map.end();) {
		if (it->first == nullptr) {
			map.erase(it++);
			++deletedRecords;
		} else if ((setIter = std::find(it->second.cbegin(), it->second.cend(), nullptr)) != it->second.cend()) {
			deletedRecords += cleanSet(it->second);
			++it;
			++deletedRecords;
		}
		else {
			++it;
		}
	}

	return deletedRecords;
}
Exemplo n.º 4
0
 void AS_collapseSet(AS_phasorSet *Setp, const AS_shaper *shp, double amax) 
{ 
  double XSum,YSum,PhiNew,RNew,extp5,sArg,base;
  int n;
  
  if (Setp->N == 0) /* If no phasors in set - do nothing */
    return;
  if (shp->ID == AS_NO_AS) { /* If NO_AS shaper - remove all */
    AS_emptySet(Setp);
    return;
  }

  /* sum up phasors */
  XSum=getX(Setp);
  YSum=getY(Setp);
  /* Remove phasors */
  AS_emptySet(Setp);

  /* do loop over half planes */
  base=0.0;
  n=0;
  do { 
    /* Calculate residual phasor */
    PhiNew=arctan360N(YSum, XSum);
    RNew=sqrt(XSum*XSum + YSum*YSum);
    sArg=RNew*AS_GRAV_ACCEL/(2.0*amax);
    if (sArg>1.0) { /* Too large arcsin argument - reduce! (residual allocated in next half plane) */
      RNew=2.0*amax/AS_GRAV_ACCEL;
      extp5=0.5*AS_PI;
    }
    else
      extp5=asin(sArg); /* Half extension of residual phasor, given a=amax */
    /* Make sure PhiNew is in the half plane [base, base-AS_PI) */ 
    while (PhiNew <= base-AS_PI) { 
      PhiNew+=AS_PI;
      RNew*=-1.0;
    }
    while (PhiNew > base) { 
      PhiNew-=AS_PI;
      RNew*=-1.0;
    }

    /* Add the calculated residual phasor. */
    if (PhiNew+extp5 > base) { /* Overlap into previous phase? */
      addPhasor(Setp, base, PhiNew-extp5, AS_SIGN(-RNew)*amax);
      addPhasor(Setp, -AS_PI+PhiNew+extp5, base-AS_PI, AS_SIGN(RNew)*amax);
    }
    else if (PhiNew-extp5 < base-AS_PI) { /* Overlap into next half plane ? */
      addPhasor(Setp, base, PhiNew-extp5+AS_PI, AS_SIGN(RNew)*amax);
      addPhasor(Setp, PhiNew+extp5, base-AS_PI, AS_SIGN(-RNew)*amax);
    }
    else /* No overlap */   
      addPhasor(Setp, PhiNew+extp5, PhiNew-extp5, AS_SIGN(-RNew)*amax);

    /* Count down sums. Loop only over the newly added phasors. (Using that phasors are added at end positions)*/
    for ( ; n < Setp->N; n++) {
      XSum -= Setp->ph[n].R*cos(Setp->ph[n].Phi);
      YSum -= Setp->ph[n].R*sin(Setp->ph[n].Phi);
    }
    base-=AS_PI;
  } while (sArg>1.0);

  cleanSet(Setp);
 
} /* end of function */
Exemplo n.º 5
0
static unsigned int makeSet_auto(AS_phasorSet *Setp, const AS_shaper *shp, unsigned int *astsp, double SxDiff, double ext_match, double uc, 
				 double amaxH, double amaxS, double umaxH, double umaxS, double umin, double omega, int verbose, int overlap)
{
  unsigned int sts=0;
  double uCmd, Sxad, sfact, ext_a, phi_d, ext_travel, ext_min, uCmd_minext;
  AS_phasorSet aSet;
  AS_phasorSet dSet;

  aSet.ph=NULL;
  AS_emptySet(&aSet);
  dSet.ph=NULL;
  AS_emptySet(&dSet);  
  AS_collapseSet(Setp, shp, amaxS);   /* Collapse current set, regardless of whether shaper works optimally with collapse or not. */
  
  /* Loop over domain of command velocities */

  for (sfact=-1.0, ext_min=DBL_MAX, ext_travel=DBL_MAX, uCmd_minext=uc; sfact<=1.0; sfact+=AS_UAUTO_INCREMENT) {
    assignSet(&aSet,Setp); /* create work copy */
    uCmd=sfact*umaxS;
    sts |= mergeSet(&aSet, shp, (uCmd-uc - aSet.extSum/omega), amaxS, omega, 0, 0);
    sts |= mergeSet(&dSet, shp, uCmd, amaxS, omega, 0, 0); /* will be reflected, shifted and inverted, which is why -uCmd is not used */
    if (!sts && uCmd!=0.0) { /* If no error from mergeSet, and non-zero uCmd - continue on. */
      /* Calculate the distance that will be travelled during acceleration and deceleration. */
      Sxad = delta_x(&aSet, uc, 1.0/omega); /* distance travelled during acc. */
      Sxad += delta_x(&dSet, 0.0, 1.0/omega); /* add distance travelled during dec. Note that 0.0 is used as uc. */

      if (aSet.N == 0) /* No phasors allocated for the acceleration (u already equals uCmd) */
	ext_a=0.0;
      else
	ext_a=-(aSet.ph[aSet.N - 1].phiEnd); /* phase duration of acc=(end of last phasor) */    
      /* Determine phase location for deceleration = -omega*time_for_dec */
      phi_d=-(omega*(SxDiff-Sxad)/uCmd + ext_a);
      /* Determine total travel phase extension */
      if ((phi_d <= 0.0) && (overlap || -phi_d >= ext_a)) { /* Will only tolerate negative (or zero) phase (i.e. positive time), and deceleration start after acc if not overlap */
	if (dSet.N > 0) 
	  ext_travel=-(phi_d + dSet.ph[dSet.N - 1].phiEnd); /* total travel phase extension = offset_dec + ext_dec */
	else /* Empty set needs special treatment. Situation should not occur, however.. */
	  ext_travel=-phi_d;
	if (fabs(ext_travel-ext_match) < ext_min) { /* Found new minimum extension */
	  ext_min=fabs(ext_travel-ext_match);
	  uCmd_minext=uCmd;
	}
      }
    }
    else /* Reset error from mergeSet */
      sts=0; 

    AS_emptySet(&dSet);
    AS_emptySet(&aSet);
  }

  /* Check that a minimum positive extension was actually found before using uCmd_minext. */
  if (ext_min != DBL_MAX) {

    /* Use uCmd that yields min time */
    uCmd=uCmd_minext;
    assignSet(&aSet,Setp);
    sts=0;
    sts |= mergeSet(&aSet, shp, (uCmd-uc - aSet.extSum/omega), amaxS, omega, 0, verbose);
    sts |= mergeSet(&dSet, shp, uCmd, amaxS, omega, 0, verbose); /* will be reflected, shifted and inverted, which is why -uCmd is not used */
    /* Calculate the distance that will be travelled during acceleration and deceleration. */
    Sxad = delta_x(&aSet, uc, 1.0/omega); /* distance travelled during acc. */
    Sxad += delta_x(&dSet, 0.0, 1.0/omega); /* add distance travelled during dec. Note that 0.0 is used as uc. */
    if (aSet.N == 0) /* No phasors allocated for the acceleration (u already equals uCmd) */
      ext_a=0.0;
    else
      ext_a=-(aSet.ph[aSet.N - 1].phiEnd); /* phase duration of acc=(end of last phasor) */    
    /* Determine phase location for deceleration = -omega*time_for_dec */
    phi_d=-(omega*(SxDiff-Sxad)/uCmd+ext_a);
  
    /* Allocate phasors to final set. Acc part and Dec part. Collect status */
    reflectShiftAndInvertSet(&dSet, phi_d); /* Create the deceleration part by reflecting, shifting and inverting the phasors */
    assignSet(Setp,&aSet); /* Replace Set with the acceleration part */
    AS_emptySet(&aSet); /* get rid of aSet */
    appendSet(Setp, &dSet); /* Append the deceleration part */
    AS_emptySet(&dSet); /* get rid of dSet */
    qsort(Setp->ph, Setp->N, sizeof(AS_phasor), AS_cmpPhasors);
    cleanSet(Setp);

    /* Check for unallowed acc */
    if (supAmax(Setp, shp->AMax*amaxH)) {
      if (AS_SHP_NEG) { /* Negative shaper - redo with non-negative (dpulse or ddpulse) */
	*astsp |= AS_AUTO_REMADE_SHP;
	if (AS_SHP_ROBUST)
	  sts |= makeSet_auto(Setp, AS_SetupIST(AS_DDPULSE), astsp, SxDiff, ext_match, uc, amaxH, amaxS, umaxH, umaxS, umin, omega, verbose, overlap);
	else 
	  sts |= makeSet_auto(Setp, AS_SetupIST(AS_DPULSE), astsp, SxDiff, ext_match, uc, amaxH, amaxS, umaxH, umaxS, umin, omega, verbose, overlap);
      }
      else if (overlap) { /* Overlap - redo without overlap */
	*astsp |= AS_AUTO_REMADE_OVERLAP;
	sts |= makeSet_auto(Setp, shp, astsp, SxDiff, ext_match, uc, amaxH, amaxS, umaxH, umaxS, umin, omega, verbose, 0);
      }
      else {/* No more tricks in the bag.. Give up. */
	*astsp |= AS_AUTO_AMAX_FAILURE;
	sts |= mergeSet(Setp, shp, (0.0-uc - Setp->extSum/omega), amaxS, omega, 0, verbose);
	if (verbose >= AS_VERB_ERR)
	  printf("\nAntiSway/makeSet_auto: Could not make set without exceeding amax. Will set zero command velocity. amaxH=%f\n",shp->AMax*amaxH);
      }
    }
    /* Check for too low velocities */
    else if (subUmin(Setp, uc, 1.0/omega, umin)) { /* umin never exceeded */
      if (ext_match != 0.0) {/* if matching a given ext, redo without matching */
	*astsp |= AS_AUTO_REMADE_MATCH;
	sts |= makeSet_auto(Setp, shp, astsp, SxDiff, 0.0, uc, amaxH, amaxS, umaxH, umaxS, umin, omega, verbose, overlap);
      }
      else {
	*astsp |= AS_AUTO_UMIN_FAILURE;
	sts |= mergeSet(Setp, shp, (0.0-uc - Setp->extSum/omega), amaxS, omega, 0, verbose);
	if (verbose >= AS_VERB_ERR)
	  printf("\nAntiSway/makeSet_auto: Could not make set with uR > umin. Will set zero command velocity. umin=%f\n",umin);
	}
    }
    /* Check for too high velocities */
    else if (supUmax(Setp, uc, 1.0/omega, umaxH)) {
      if (overlap) {/* Overlap - redo without overlap */
	*astsp |= AS_AUTO_REMADE_OVERLAP;
	sts |= makeSet_auto(Setp, shp, astsp, SxDiff, ext_match, uc, amaxH, amaxS, umaxH, umaxS, umin, omega, verbose, 0);
      }
      else /* Resign.. use the set with umax violation (will be cut down in exec) */
	*astsp |= AS_AUTO_UMAX_FAILURE;
    }
  }

  /* No minimum positive extension found.. */
  else { 
    *astsp |= AS_AUTO_POSEXT_FAILURE;
    sts |= mergeSet(Setp, shp, (0.0-uc - Setp->extSum/omega), amaxS, omega, 0, verbose);
    if (verbose >= AS_VERB_ERR)
      printf("\nAntiSway/makeSet_auto: Could not find a minimum positive extension. Will set zero command velocity.\n");
  }  

  return sts;
}