Beispiel #1
0
static void constrain(popcorn_struct *popcorn, t_symbol *s, int argc, t_atom *argv) {
	int i;
	t_atom *arg = argv;
	if (argc == 0) {
		// reset to full limits of search ranges
		popcorn -> h_lo = M_h_lo;
		popcorn -> h_hi = M_h_hi;
		return;
	}
	if (argc == 1) {
		// set the ranges based on percentage of full range
		double percent = atom_getfloat(arg);
		double h_spread = ((M_h_hi - M_h_lo) * percent) / 2;
		popcorn -> h_lo = popcorn -> h - h_spread;
		popcorn -> h_hi = popcorn -> h + h_spread;
		limiter(popcorn);
		return;
	}
	if (argc != M_param_count * 2) {
		post("Invalid number of arguments for popcorn constraints, requires 2 values, got %d", argc);
		return;
	}
	popcorn -> h_lo = atom_getfloat(arg++);
	popcorn -> h_hi = atom_getfloat(arg++);
	limiter(popcorn);
}
Beispiel #2
0
static void constrain(mlogistic_struct *mlogistic, t_symbol *s, int argc, t_atom *argv) {
	int i;
	t_atom *arg = argv;
	if (argc == 0) {
		// reset to full limits of search ranges
		mlogistic -> c_lo = M_c_lo;
		mlogistic -> c_hi = M_c_hi;
		return;
	}
	if (argc == 1) {
		// set the ranges based on percentage of full range
		double percent = atom_getfloat(arg);
		double c_spread = ((M_c_hi - M_c_lo) * percent) / 2;
		mlogistic -> c_lo = mlogistic -> c - c_spread;
		mlogistic -> c_hi = mlogistic -> c + c_spread;
		limiter(mlogistic);
		return;
	}
	if (argc != M_param_count * 2) {
		post("Invalid number of arguments for mlogistic constraints, requires 2 values, got %d", argc);
		return;
	}
	mlogistic -> c_lo = atom_getfloat(arg++);
	mlogistic -> c_hi = atom_getfloat(arg++);
	limiter(mlogistic);
}
Beispiel #3
0
static void constrain(standardmap_struct *standardmap, t_symbol *s, int argc, t_atom *argv) {
	int i;
	t_atom *arg = argv;
	if (argc == 0) {
		// reset to full limits of search ranges
		standardmap -> k_lo = M_k_lo;
		standardmap -> k_hi = M_k_hi;
		return;
	}
	if (argc == 1) {
		// set the ranges based on percentage of full range
		double percent = atom_getfloat(arg);
		double k_spread = ((M_k_hi - M_k_lo) * percent) / 2;
		standardmap -> k_lo = standardmap -> k - k_spread;
		standardmap -> k_hi = standardmap -> k + k_spread;
		limiter(standardmap);
		return;
	}
	if (argc != M_param_count * 2) {
		post("Invalid number of arguments for standardmap constraints, requires 2 values, got %d", argc);
		return;
	}
	standardmap -> k_lo = atom_getfloat(arg++);
	standardmap -> k_hi = atom_getfloat(arg++);
	limiter(standardmap);
}
Beispiel #4
0
static void constrain(base3_struct *base3, t_symbol *s, int argc, t_atom *argv) {
	int i;
	t_atom *arg = argv;
	if (argc == 0) {
		// reset to full limits of search ranges
		base3 -> a_lo = M_a_lo;
		base3 -> a_hi = M_a_hi;
		base3 -> b_lo = M_b_lo;
		base3 -> b_hi = M_b_hi;
		return;
	}
	if (argc == 1) {
		// set the ranges based on percentage of full range
		double percent = atom_getfloat(arg);
		double a_spread = ((M_a_hi - M_a_lo) * percent) / 2;
		double b_spread = ((M_b_hi - M_b_lo) * percent) / 2;
		base3 -> a_lo = base3 -> a - a_spread;
		base3 -> a_hi = base3 -> a + a_spread;
		base3 -> b_lo = base3 -> b - b_spread;
		base3 -> b_hi = base3 -> b + b_spread;
		limiter(base3);
		return;
	}
	if (argc != M_param_count * 2) {
		post("Invalid number of arguments for base3 constraints, requires 4 values, got %d", argc);
		return;
	}
	base3 -> a_lo = atom_getfloat(arg++);
	base3 -> a_hi = atom_getfloat(arg++);
	base3 -> b_lo = atom_getfloat(arg++);
	base3 -> b_hi = atom_getfloat(arg++);
	limiter(base3);
}
double PIDController::calc(double processVariable) {
    if(!isEnabled) {
        return lastControlVariable;
    }
    sample_timer.stop();
    
    double error = setpoint - processVariable;
    double samplingTime = (sample_timer.elapsed().wall)/1e9;
    
    double diffProcessVariable = (processVariable - lastProcessVariable)/samplingTime;
    double percent = (processVariable/setpoint) - 1;
    
    if(abs(diffProcessVariable) < 0.5) {
		setpointReached = true;
	}
	else {
		setpointReached = false;
	}
    
    double differentiator = (setpoint - lastSetpoint)/samplingTime;
    integrator += (error * samplingTime);
    integrator = limiter(integrator, lowerOutputLimit, upperOutputLimit);
    double controlVariable = kp * error + ki * integrator - kd * differentiator;
    
    controlVariable = limiter(controlVariable, lowerOutputLimit, upperOutputLimit);
    lastControlVariable = controlVariable;
    lastSetpoint = setpoint;
    lastProcessVariable = processVariable;
    
    sample_timer.start();

    return controlVariable;
}
Beispiel #6
0
static void constrain(three_d_struct *three_d, t_symbol *s, int argc, t_atom *argv) {
	int i;
	t_atom *arg = argv;
	if (argc == 0) {
		// reset to full limits of search ranges
		three_d -> a_lo = M_a_lo;
		three_d -> a_hi = M_a_hi;
		three_d -> b_lo = M_b_lo;
		three_d -> b_hi = M_b_hi;
		three_d -> c_lo = M_c_lo;
		three_d -> c_hi = M_c_hi;
		three_d -> d_lo = M_d_lo;
		three_d -> d_hi = M_d_hi;
		three_d -> e_lo = M_e_lo;
		three_d -> e_hi = M_e_hi;
		return;
	}
	if (argc == 1) {
		// set the ranges based on percentage of full range
		double percent = atom_getfloat(arg);
		double a_spread = ((M_a_hi - M_a_lo) * percent) / 2;
		double b_spread = ((M_b_hi - M_b_lo) * percent) / 2;
		double c_spread = ((M_c_hi - M_c_lo) * percent) / 2;
		double d_spread = ((M_d_hi - M_d_lo) * percent) / 2;
		double e_spread = ((M_e_hi - M_e_lo) * percent) / 2;
		three_d -> a_lo = three_d -> a - a_spread;
		three_d -> a_hi = three_d -> a + a_spread;
		three_d -> b_lo = three_d -> b - b_spread;
		three_d -> b_hi = three_d -> b + b_spread;
		three_d -> c_lo = three_d -> c - c_spread;
		three_d -> c_hi = three_d -> c + c_spread;
		three_d -> d_lo = three_d -> d - d_spread;
		three_d -> d_hi = three_d -> d + d_spread;
		three_d -> e_lo = three_d -> e - e_spread;
		three_d -> e_hi = three_d -> e + e_spread;
		limiter(three_d);
		return;
	}
	if (argc != M_param_count * 2) {
		post("Invalid number of arguments for three_d constraints, requires 10 values, got %d", argc);
		return;
	}
	three_d -> a_lo = atom_getfloat(arg++);
	three_d -> a_hi = atom_getfloat(arg++);
	three_d -> b_lo = atom_getfloat(arg++);
	three_d -> b_hi = atom_getfloat(arg++);
	three_d -> c_lo = atom_getfloat(arg++);
	three_d -> c_hi = atom_getfloat(arg++);
	three_d -> d_lo = atom_getfloat(arg++);
	three_d -> d_hi = atom_getfloat(arg++);
	three_d -> e_lo = atom_getfloat(arg++);
	three_d -> e_hi = atom_getfloat(arg++);
	limiter(three_d);
}
Beispiel #7
0
float equal_power(float x1, float x2, long i, long n)
{
    float f_in  = float(i) / float(n-1);
    float f_out = float(n-i) / float(n);
    float val = logFactor(f_out) * x1 + logFactor(f_in) * x2;
    return limiter(val);
}
Beispiel #8
0
static PyObject* cAction_fade(PyObject* self, PyObject* args)
{
    PyObject *objInSound;
    float volume = 1.0f;
    float from = 0.0f;
    float to = 1.0f;

    if (!PyArg_ParseTuple(args, "O|f|f|f", &objInSound, &volume, &from, &to))
        return NULL;

    PyArrayObject *inSound = get_pyarray(objInSound);
    if (inSound == NULL)
        return NULL;

    uint nSamples = inSound->dimensions[0];
    uint nChannels = inSound->dimensions[1];
    // float *inSamples = (Float32 *)NA_OFFSETDATA(inSound);
    float *inSamples =  (float*) PyArray_DATA(inSound);

    // Limit:
    for (uint j = 0; j < nChannels; j++)
    {
        for (uint i = 0; i < nSamples; i++)
        {
            float frac = ((float)(nSamples - i) / (float) nSamples) * (to - from) + from;
            float f = inSamples[nChannels * i + j];
            inSamples[nChannels * i + j] = limiter(frac * f * volume);
        }
    }

    // Do we need to make a copy before returning, or can we return the modified original?
    return PyArray_Return(inSound);
}
Beispiel #9
0
bool check(FILE *f)
{
  JsonState state;
  state.reset(true);
  state.validateEscapes=true;
  state.validateNumbers=true;
//state.allowUnquotedKeys=true;

  LimitDepth limiter(20);
  state.setListener(&limiter);

  int pos=0,c;
  while ((c=fgetc(f))!=EOF) {
    pos++;
// FIXME: decode utf8
    if (!state.Echar(c)) {
      break;
    }
  }
  if (!state.Eend()) {
    printf("Json error at %d: %s\n",pos,state.error());
//puts("");state.dump();
    return false;
  }
  return true;
}
void PIDController::targetSetpoint(double setpoint) {
    setpoint = limiter(setpoint, lowerInputLimit, upperInputLimit);
    if(setpoint != this->setpoint) {
        this->setpoint = setpoint;
        sample_timer.start();
    }
}
Beispiel #11
0
static PyObject* cAction_limit(PyObject* self, PyObject* args)
{
    PyObject *objInSound;
    if (!PyArg_ParseTuple(args, "O", &objInSound))
        return NULL;

    PyArrayObject *inSound = get_pyarray(objInSound);
    if (inSound == NULL)
        return NULL;

    uint nSamples = inSound->dimensions[0];
    uint nChannels = inSound->dimensions[1];
    // float *inSamples = (Float32 *)NA_OFFSETDATA(inSound);
    float *inSamples =  (float*) PyArray_DATA(inSound);

    // Limit:
    for (uint j = 0; j < nChannels; j++)
    {
        for (uint i = 0; i < nSamples; i++)
        {
            float f = inSamples[nChannels*i  + j];
            inSamples[nChannels*i + j] = limiter(f);
        }
    }

    // Do we need to make a copy before returning, or can we return the modified original?
    return PyArray_Return(inSound);
}
Beispiel #12
0
static void constrain(ikeda_struct *ikeda, t_symbol *s, int argc, t_atom *argv) {
	int i;
	t_atom *arg = argv;
	if (argc == 0) {
		// reset to full limits of search ranges
		ikeda -> a_lo = M_a_lo;
		ikeda -> a_hi = M_a_hi;
		ikeda -> b_lo = M_b_lo;
		ikeda -> b_hi = M_b_hi;
		ikeda -> c_lo = M_c_lo;
		ikeda -> c_hi = M_c_hi;
		ikeda -> rho_lo = M_rho_lo;
		ikeda -> rho_hi = M_rho_hi;
		return;
	}
	if (argc == 1) {
		// set the ranges based on percentage of full range
		double percent = atom_getfloat(arg);
		double a_spread = ((M_a_hi - M_a_lo) * percent) / 2;
		double b_spread = ((M_b_hi - M_b_lo) * percent) / 2;
		double c_spread = ((M_c_hi - M_c_lo) * percent) / 2;
		double rho_spread = ((M_rho_hi - M_rho_lo) * percent) / 2;
		ikeda -> a_lo = ikeda -> a - a_spread;
		ikeda -> a_hi = ikeda -> a + a_spread;
		ikeda -> b_lo = ikeda -> b - b_spread;
		ikeda -> b_hi = ikeda -> b + b_spread;
		ikeda -> c_lo = ikeda -> c - c_spread;
		ikeda -> c_hi = ikeda -> c + c_spread;
		ikeda -> rho_lo = ikeda -> rho - rho_spread;
		ikeda -> rho_hi = ikeda -> rho + rho_spread;
		limiter(ikeda);
		return;
	}
	if (argc != M_param_count * 2) {
		post("Invalid number of arguments for ikeda constraints, requires 8 values, got %d", argc);
		return;
	}
	ikeda -> a_lo = atom_getfloat(arg++);
	ikeda -> a_hi = atom_getfloat(arg++);
	ikeda -> b_lo = atom_getfloat(arg++);
	ikeda -> b_hi = atom_getfloat(arg++);
	ikeda -> c_lo = atom_getfloat(arg++);
	ikeda -> c_hi = atom_getfloat(arg++);
	ikeda -> rho_lo = atom_getfloat(arg++);
	ikeda -> rho_hi = atom_getfloat(arg++);
	limiter(ikeda);
}
Beispiel #13
0
static void constrain(rossler_struct *rossler, t_symbol *s, int argc, t_atom *argv) {
	int i;
	t_atom *arg = argv;
	if (argc == 0) {
		// reset to full limits of search ranges
		rossler -> h_lo = M_h_lo;
		rossler -> h_hi = M_h_hi;
		rossler -> a_lo = M_a_lo;
		rossler -> a_hi = M_a_hi;
		rossler -> b_lo = M_b_lo;
		rossler -> b_hi = M_b_hi;
		rossler -> c_lo = M_c_lo;
		rossler -> c_hi = M_c_hi;
		return;
	}
	if (argc == 1) {
		// set the ranges based on percentage of full range
		double percent = atom_getfloat(arg);
		double h_spread = ((M_h_hi - M_h_lo) * percent) / 2;
		double a_spread = ((M_a_hi - M_a_lo) * percent) / 2;
		double b_spread = ((M_b_hi - M_b_lo) * percent) / 2;
		double c_spread = ((M_c_hi - M_c_lo) * percent) / 2;
		rossler -> h_lo = rossler -> h - h_spread;
		rossler -> h_hi = rossler -> h + h_spread;
		rossler -> a_lo = rossler -> a - a_spread;
		rossler -> a_hi = rossler -> a + a_spread;
		rossler -> b_lo = rossler -> b - b_spread;
		rossler -> b_hi = rossler -> b + b_spread;
		rossler -> c_lo = rossler -> c - c_spread;
		rossler -> c_hi = rossler -> c + c_spread;
		limiter(rossler);
		return;
	}
	if (argc != M_param_count * 2) {
		post("Invalid number of arguments for rossler constraints, requires 8 values, got %d", argc);
		return;
	}
	rossler -> h_lo = atom_getfloat(arg++);
	rossler -> h_hi = atom_getfloat(arg++);
	rossler -> a_lo = atom_getfloat(arg++);
	rossler -> a_hi = atom_getfloat(arg++);
	rossler -> b_lo = atom_getfloat(arg++);
	rossler -> b_hi = atom_getfloat(arg++);
	rossler -> c_lo = atom_getfloat(arg++);
	rossler -> c_hi = atom_getfloat(arg++);
	limiter(rossler);
}
Beispiel #14
0
static void constrain(latoomutalpha_struct *latoomutalpha, t_symbol *s, int argc, t_atom *argv) {
	int i;
	t_atom *arg = argv;
	if (argc == 0) {
		// reset to full limits of search ranges
		latoomutalpha -> a_lo = M_a_lo;
		latoomutalpha -> a_hi = M_a_hi;
		latoomutalpha -> b_lo = M_b_lo;
		latoomutalpha -> b_hi = M_b_hi;
		latoomutalpha -> c_lo = M_c_lo;
		latoomutalpha -> c_hi = M_c_hi;
		latoomutalpha -> d_lo = M_d_lo;
		latoomutalpha -> d_hi = M_d_hi;
		return;
	}
	if (argc == 1) {
		// set the ranges based on percentage of full range
		double percent = atom_getfloat(arg);
		double a_spread = ((M_a_hi - M_a_lo) * percent) / 2;
		double b_spread = ((M_b_hi - M_b_lo) * percent) / 2;
		double c_spread = ((M_c_hi - M_c_lo) * percent) / 2;
		double d_spread = ((M_d_hi - M_d_lo) * percent) / 2;
		latoomutalpha -> a_lo = latoomutalpha -> a - a_spread;
		latoomutalpha -> a_hi = latoomutalpha -> a + a_spread;
		latoomutalpha -> b_lo = latoomutalpha -> b - b_spread;
		latoomutalpha -> b_hi = latoomutalpha -> b + b_spread;
		latoomutalpha -> c_lo = latoomutalpha -> c - c_spread;
		latoomutalpha -> c_hi = latoomutalpha -> c + c_spread;
		latoomutalpha -> d_lo = latoomutalpha -> d - d_spread;
		latoomutalpha -> d_hi = latoomutalpha -> d + d_spread;
		limiter(latoomutalpha);
		return;
	}
	if (argc != M_param_count * 2) {
		post("Invalid number of arguments for latoomutalpha constraints, requires 8 values, got %d", argc);
		return;
	}
	latoomutalpha -> a_lo = atom_getfloat(arg++);
	latoomutalpha -> a_hi = atom_getfloat(arg++);
	latoomutalpha -> b_lo = atom_getfloat(arg++);
	latoomutalpha -> b_hi = atom_getfloat(arg++);
	latoomutalpha -> c_lo = atom_getfloat(arg++);
	latoomutalpha -> c_hi = atom_getfloat(arg++);
	latoomutalpha -> d_lo = atom_getfloat(arg++);
	latoomutalpha -> d_hi = atom_getfloat(arg++);
	limiter(latoomutalpha);
}
Beispiel #15
0
Foam::tmp<Foam::volVectorField>
Foam::fv::faceLimitedGrad<Foam::scalar>::calcGrad
(
    const volScalarField& vsf,
    const word& name
) const
{
    const fvMesh& mesh = vsf.mesh();

    tmp<volVectorField> tGrad = basicGradScheme_().calcGrad(vsf, name);

    if (k_ < SMALL)
    {
        return tGrad;
    }

    volVectorField& g = tGrad();

    const labelUList& owner = mesh.owner();
    const labelUList& neighbour = mesh.neighbour();

    const volVectorField& C = mesh.C();
    const surfaceVectorField& Cf = mesh.Cf();

    // create limiter
    scalarField limiter(vsf.internalField().size(), 1.0);

    scalar rk = (1.0/k_ - 1.0);

    forAll(owner, facei)
    {
        label own = owner[facei];
        label nei = neighbour[facei];

        scalar vsfOwn = vsf[own];
        scalar vsfNei = vsf[nei];

        scalar maxFace = max(vsfOwn, vsfNei);
        scalar minFace = min(vsfOwn, vsfNei);
        scalar maxMinFace = rk*(maxFace - minFace);
        maxFace += maxMinFace;
        minFace -= maxMinFace;

        // owner side
        limitFace
        (
            limiter[own],
            maxFace - vsfOwn, minFace - vsfOwn,
            (Cf[facei] - C[own]) & g[own]
        );

        // neighbour side
        limitFace
        (
            limiter[nei],
            maxFace - vsfNei, minFace - vsfNei,
            (Cf[facei] - C[nei]) & g[nei]
        );
    }
Beispiel #16
0
/*
 * Second order TVD scheme (http://en.wikipedia.org/wiki/Total_variation_diminishing).
 */
inline real tvd2(const real c, const real u_2, const real u_1, const real u, const real u1)
{
	real r1 = (u  - u_1);
	real r2 = (u1 - u);
	//if (r2 == 0.0) {
		r1 += TVD2_EPS;
		r2 += TVD2_EPS;
	//}
	const real r = r1 / r2;
	r1 = (u_1 - u_2);
	r2 = (u   - u_1);
	//if (r2 == 0.0) {
		r1 += TVD2_EPS;
		r2 += TVD2_EPS;
	//}
	const real r_1 = r1 / r2;

	const real f12  = u   + limiter(r)   / 2.0 * (1.0 - c) * (u1 - u);
	const real f_12 = u_1 + limiter(r_1) / 2.0 * (1.0 - c) * (u  - u_1);

	return u - c * (f12 - f_12);
}
Beispiel #17
0
// TODO: Speed up for special case of 2 channels?
void mono_blend(void *buf, audio_format_t format, size_t channelCount, size_t frames, bool limit) {
    if (channelCount < 2) {
        return;
    }
    switch (format) {
    case AUDIO_FORMAT_PCM_16_BIT: {
        int16_t *out = (int16_t *)buf;
        for (size_t i = 0; i < frames; ++i) {
            const int16_t *in = out;
            int accum = 0;
            for (size_t j = 0; j < channelCount; ++j) {
                accum += *in++;
            }
            accum /= channelCount; // round to 0
            for (size_t j = 0; j < channelCount; ++j) {
                *out++ = accum;
            }
        }
    } break;
    case AUDIO_FORMAT_PCM_FLOAT: {
        float *out = (float *)buf;
        const float recipdiv = 1. / channelCount;
        for (size_t i = 0; i < frames; ++i) {
            const float *in = out;
            float accum = 0;
            for (size_t j = 0; j < channelCount; ++j) {
                accum += *in++;
            }
            if (limit && channelCount == 2) {
                accum = limiter(accum * M_SQRT1_2);
            } else {
                accum *= recipdiv;
            }
            for (size_t j = 0; j < channelCount; ++j) {
                *out++ = accum;
            }
        }
    } break;
    default:
        ALOGE("mono_blend: invalid format %d", format);
        break;
    }
}
// advance the operator that has been split off from dogpack framework
//
// nonzero return value would indicate error. The exact solution
// has no stability constraint, so this always returns 0.
//
int AppStateCart2::advanceSplitTimeStep(double dt)
{
  bool using_split_source = 
     plasmaParams.get_source_type_Emom() == SourceType::SPLIT;

  if(!using_split_source) return 0;

  dTensorBC4& q = fetch_q();
  dTensorBC4& aux = fetch_aux();
  const int mxelems = q.getsize(1);
  const int myelems = q.getsize(2);
  const int    mbc = q.getmbc();
  // apply positivity limiters to source term quadrature points
  PositivityLimiter limiter(q,PositivityPointType::SOURCE);
  limiter.apply();
  //dprintf("solving source term for dt = %e",dt);
  L2Project_extra(1,mxelems,1,myelems,
      q,aux,q,&solve_source_term,&dt);
  return 0;
}
void Aggregate::starter() {

    // If there is only one chunk then it is the first
    // download chunk so infomation must be gathered

    if(m_filesize==0) {
        // Researcher finds about the necessary information
        // about the download file; filesize, resumability
        Chunk* researcher = m_chunk[0];
        researcher->txn()->start();

        // Wait for researcher until downloading starts,
        // Now we get the proper information about the file
        // and further process can be started
        while( !researcher->txn()->isDownloading() &&
                !researcher->txn()->isComplete() &&
                !researcher->txn()->hasFailed() )
            boost::this_thread::sleep(boost::posix_time::millisec(100));

        if(researcher->txn()->hasFailed())
            Throw(ex::Error,"Starting transaction failed.");

        // Initialize m_filesize
        m_filesize = researcher->txn()->bytesTotal();

        // Create a limiter file
        File limiter(chunkName(m_filesize));
        limiter.write();

    } else {
        // Start all the Chunks
        // They should be started at last
        for(auto it = m_chunk.begin();it != m_chunk.end(); it++)
            (*it)->txn()->start();
    }

}
Beispiel #20
0
int AttachGalley(OBJECT hd, OBJECT *inners, OBJECT *suspend_pt)
{ OBJECT hd_index;		/* the index of hd in the enclosing galley   */
  OBJECT hd_inners;		/* inner galleys of hd, if unsized           */
  OBJECT dest;			/* the target @Galley hd empties into        */
  OBJECT dest_index;		/* the index of dest                         */
  OBJECT target;		/* the target indefinite containing dest     */
  OBJECT target_index;		/* the index of target                       */
  OBJECT target_galley;		/* the body of target, made into a galley    */
  OBJECT tg_inners;		/* inner galleys of target_galley            */
  BOOLEAN need_precedes = FALSE;/* true if destination lies before galley    */
  OBJECT recs;			/* list of recursive definite objects        */
  OBJECT link, y = nilobj;	/* for scanning through the components of hd */
  CONSTRAINT c;			/* temporary variable holding a constraint   */
  OBJECT env, n1, tmp, zlink, z, sym;	/* placeholders and temporaries	     */
  BOOLEAN was_sized;		/* true if sized(hd) initially               */
  int dim;			/* the galley direction                      */
  FULL_LENGTH perp_back, perp_fwd;
  OBJECT why, junk;

  debug2(DGA, D, "[ AttachGalley(Galley %s into %s)",
	SymName(actual(hd)), SymName(whereto(hd)));
  ifdebug(DGA, DD, DebugGalley(hd, nilobj, 4));
  assert( Up(hd) != hd, "AttachGalley: no index!" );
  Parent(hd_index, Up(hd));
  assert( type(hd_index) == UNATTACHED, "AttachGalley: not UNATTACHED!" );
  hd_inners = tg_inners = nilobj;
  was_sized = sized(hd);
  dim = gall_dir(hd);

  for(;;)
  {
    /*************************************************************************/
    /*                                                                       */
    /*  Search for a destination for hd.  If hd is unsized, search for       */
    /*  inner galleys preceding it first of all, then for receptive objects  */
    /*  following it, possibly in inner galleys.  If no luck, exit.          */
    /*  If hd is sized, search only for receptive objects in the current     */
    /*  galley below the current spot, and fail if cannot find any.          */
    /*                                                                       */
    /*************************************************************************/

    sym = whereto(hd);
    if( sized(hd) )
    {
      /* sized galley case: search on from current spot */
      target_index = SearchGalley(Up(hd_index), sym, TRUE, FALSE, TRUE, TRUE);
      if( target_index == nilobj )
      {	
	/* search failed to find any new target, so kill the galley */
	for( link = Down(hd); link != hd; link = NextDown(link) )
	{ Child(y, link);
	  if( type(y) == SPLIT )  Child(y, DownDim(y, dim));
	  if( is_definite(type(y)) )  break;
	}
	if( link != hd )
	  Error(19, 1, "galley %s deleted from here (no target)",
	    WARN, &fpos(y), SymName(actual(hd)));
	if( hd_inners != nilobj )  DisposeObject(hd_inners), hd_inners=nilobj;
	if( tg_inners != nilobj )  DisposeObject(tg_inners), tg_inners=nilobj;
	KillGalley(hd, FALSE);
	*inners = nilobj;
	debug0(DGA, D, "] AttachGalley returning ATTACH_KILLED");
	return ATTACH_KILLED;
      }
      else if( actual(actual(target_index)) == InputSym )
      {
	/* search found input object, so suspend on that */
	DeleteNode(hd_index);
	Link(target_index, hd);
	*inners = nilobj;
	debug0(DGA, D, "] AttachGalley returning ATTACH_INPUT");
	return ATTACH_INPUT;
      }

    }
    else /* unsized galley, either backwards or normal */
    {
      if( foll_or_prec(hd) == GALL_PREC )
      {	target_index= SearchGalley(Up(hd_index), sym, FALSE, TRUE,TRUE,FALSE);
	need_precedes = FALSE;
      }
      else
      {	target_index = SearchGalley(Up(hd_index), sym, FALSE,TRUE,FALSE,FALSE);
	need_precedes = (target_index != nilobj);
	if( target_index == nilobj )
	  target_index = SearchGalley(Up(hd_index), sym, TRUE,TRUE,TRUE,FALSE);
      }

      /* if no luck, exit without error */
      if( target_index == nilobj )
      {	*inners = nilobj;
	debug0(DGA, D, "] AttachGalley returning ATTACH_NOTARGET");
	return ATTACH_NOTARGET;
      }
    }
    assert( type(target_index) == RECEPTIVE, "AttachGalley: target_index!" );
    target = actual(target_index);
    assert( type(target) == CLOSURE, "AttachGalley: target!" );

    /* set target_galley to the expanded value of target */
    debug1(DYY, D, "[ EnterErrorBlock(FALSE) (expanding target %s)",
      SymName(actual(target)));
    EnterErrorBlock(FALSE);
    New(target_galley, HEAD);
    force_gall(target_galley) = FALSE;
    enclose_obj(target_galley) = limiter(target_galley) = nilobj;
    ClearHeaders(target_galley);
    opt_components(target_galley) = opt_constraints(target_galley) = nilobj;
    gall_dir(target_galley) = external_hor(target) ? COLM : ROWM;
    FposCopy(fpos(target_galley), fpos(target));
    actual(target_galley) = actual(target);
    whereto(target_galley) = ready_galls(target_galley) = nilobj;
    foll_or_prec(target_galley) = GALL_FOLL;
    must_expand(target_galley) = FALSE;
    sized(target_galley) = FALSE;

    /* get perpendicular constraint (none if horizontal galley) */
    if( dim == ROWM )
    {
      Constrained(target, &c, 1-dim, &junk);
      if( !constrained(c) )
        Error(19, 2, "receptive symbol %s has unconstrained width",
	  FATAL, &fpos(target), SymName(actual(target)));
      debug2(DSC, DD, "Constrained( %s, 1-dim ) = %s",
	EchoObject(target), EchoConstraint(&c));
      if( !FitsConstraint(0, 0, c) )
      { debug0(DGA, D, "  reject: target_galley horizontal constraint is -1");
	y = nilobj;
        goto REJECT;
      }
    }
    else /* actually unused */
      SetConstraint(c, MAX_FULL_LENGTH, MAX_FULL_LENGTH, MAX_FULL_LENGTH);

    debug1(DGA, DDD, "  expanding %s", EchoObject(target));
    tmp = CopyObject(target, no_fpos);
    Link(target_galley, tmp);
    env = DetachEnv(tmp);
    debug4(DGM, D, "  external_ver(%s) = %s, external_hor(%s) = %s",
      SymName(actual(target)), bool(external_ver(target)),
      SymName(actual(target)), bool(external_hor(target)));
    SizeGalley(target_galley, env,
	external_ver(target) || external_hor(target),
	threaded(target), non_blocking(target_index),
	trigger_externs(target_index), &save_style(target),
	&c, whereto(hd), &dest_index, &recs, &tg_inners,
	enclose_obj(hd) != nilobj ? CopyObject(enclose_obj(hd), no_fpos):nilobj);
    debug1(DGA, DD, "  SizeGalley tg_inners: %s", DebugInnersNames(tg_inners));
    if( recs != nilobj )  ExpandRecursives(recs);
    dest = actual(dest_index);
    if( underline(dest) == UNDER_UNDEF )  underline(dest) = UNDER_OFF;

    /* verify that hd satisfies any horizontal constraint on dest */
    if( dim == ROWM )
    {
      debug1(DGA, DDD, "  checking hor fit of hd in %s",SymName(actual(dest)));
      Constrained(dest, &c, 1-dim, &junk);
      debug3(DSC, DD, "Constrained( %s, %s ) = %s",
	EchoObject(dest), dimen(1-dim), EchoConstraint(&c));
      assert( constrained(c), "AttachGalley: dest unconstrained!" );
      if( !FitsConstraint(0, 0, c) )
      { debug0(DGA, D, "  reject: hd horizontal constraint is -1");
	y = nilobj;
        goto REJECT;
      }
    }

    /* manifest and size the galley if not done yet */
    if( !sized(hd) )
    {
      debug2(DYY, D, "[ EnterErrorBlock(TRUE) (sizing galley %s into %s)",
	SymName(actual(hd)), SymName(whereto(hd)));
      EnterErrorBlock(TRUE);
      n1 = nilobj;
      Child(y, Down(hd));
      env = DetachEnv(y);
      /*** threaded() only defined in ROWM case
      SizeGalley(hd, env, TRUE, threaded(dest), non_blocking(target_index),
	TRUE, &save_style(dest), &c, nilobj, &n1, &recs, &hd_inners);
      *** */
      SizeGalley(hd, env, TRUE, dim == ROWM ? threaded(dest) : FALSE,
	non_blocking(target_index), TRUE, &save_style(dest), &c, nilobj,
	&n1, &recs, &hd_inners, nilobj);
      debug1(DGA,DD,"  SizeGalley hd_inners: %s", DebugInnersNames(hd_inners));
      if( recs != nilobj )  ExpandRecursives(recs);
      if( need_precedes )		/* need an ordering constraint */
      {	OBJECT index1, index2;
        New(index1, PRECEDES);
	New(index2, FOLLOWS);
	blocked(index2) = FALSE;
	tmp = MakeWord(WORD, STR_EMPTY, no_fpos);
	Link(index1, tmp);  Link(index2, tmp);
	Link(Up(hd_index), index1);
	Link(Down(hd), index2);
	debug0(DGA, D, "  inserting PRECEDES and FOLLOWS");
      }
      LeaveErrorBlock(TRUE);
      debug0(DYY, D, "] LeaveErrorBlock(TRUE) (finished sizing galley)");
    }

    if( dim == ROWM )
    { if( !FitsConstraint(back(hd, 1-dim), fwd(hd, 1-dim), c) )
      { debug3(DGA, D, "  reject: hd %s,%s does not fit target_galley %s",
	  EchoLength(back(hd, 1-dim)), EchoLength(fwd(hd, 1-dim)),
	  EchoConstraint(&c));
        Error(19, 3, "too little horizontal space for galley %s at %s",
	  WARN, &fpos(hd), SymName(actual(hd)), SymName(actual(dest)));
        goto REJECT;
      }
    }

    /* check status of first component of hd */
    debug0(DGA, DDD, "  now ready to attach; hd =");
    ifdebug(DGA, DDD, DebugObject(hd));
    for( link = Down(hd);  link != hd;  link = NextDown(link) )
    {
      Child(y, link);
      debug1(DGA, DDD, "  examining %s", EchoIndex(y));
      if( type(y) == SPLIT )  Child(y, DownDim(y, dim));
      switch( type(y) )
      {

	case EXPAND_IND:
	case SCALE_IND:
	case COVER_IND:
	case GALL_PREC:
	case GALL_FOLL:
	case GALL_FOLL_OR_PREC:
	case GALL_TARG:
	case CROSS_PREC:
	case CROSS_FOLL:
	case CROSS_FOLL_OR_PREC:
	case CROSS_TARG:
	case PAGE_LABEL_IND:
	    
	  break;


	case PRECEDES:
	case UNATTACHED:
	    
	  if( was_sized )
	  { /* SizeGalley was not called, so hd_inners was not set by it */
	    if( hd_inners == nilobj )  New(hd_inners, ACAT);
	    Link(hd_inners, y);
	  }
	  break;


	case RECEPTIVE:

	  goto SUSPEND;


	case RECEIVING:
	    
	  goto SUSPEND;


	case FOLLOWS:
	    
	  Child(tmp, Down(y));
	  if( Up(tmp) == LastUp(tmp) )
	  { link = pred(link, CHILD);
	    debug0(DGA, DD, "  disposing FOLLOWS");
	    DisposeChild(NextDown(link));
	    break;
	  }
	  Parent(tmp, Up(tmp));
	  assert(type(tmp) == PRECEDES, "Attach: PRECEDES!");
	  switch( CheckComponentOrder(tmp, target_index) )
	  {
	    case CLEAR:		DeleteNode(tmp);
				link = pred(link, CHILD);
				DisposeChild(NextDown(link));
				break;

	    case PROMOTE:	break;

	    case BLOCK:		debug0(DGA, DD, "CheckContraint: BLOCK");
				goto SUSPEND;

	    case CLOSE:		debug0(DGA, D, "  reject: CheckContraint");
				goto REJECT;
	  }
	  break;


	case GAP_OBJ:

	  underline(y) = underline(dest);
	  if( !join(gap(y)) )  seen_nojoin(hd) = TRUE;
	  break;


	case BEGIN_HEADER:
	case END_HEADER:
	case SET_HEADER:
	case CLEAR_HEADER:

	  /* do nothing until actually promoted out of here */
	  underline(y) = underline(dest);
	  break;


	case CLOSURE:
	case CROSS:
	case FORCE_CROSS:
	case NULL_CLOS:
	case PAGE_LABEL:

	  underline(y) = underline(dest);
	  break;


	case WORD:
	case QWORD:
	case ONE_COL:
	case ONE_ROW:
	case WIDE:
	case HIGH:
	case HSHIFT:
	case VSHIFT:
	case HMIRROR:
	case VMIRROR:
	case HSCALE:
	case VSCALE:
	case HCOVER:
	case VCOVER:
	case HCONTRACT:
	case VCONTRACT:
	case HLIMITED:
	case VLIMITED:
	case HEXPAND:
	case VEXPAND:
	case START_HVSPAN:
	case START_HSPAN:
	case START_VSPAN:
	case HSPAN:
	case VSPAN:
	case ROTATE:
	case BACKGROUND:
	case SCALE:
	case KERN_SHRINK:
	case INCGRAPHIC:
	case SINCGRAPHIC:
	case PLAIN_GRAPHIC:
	case GRAPHIC:
	case LINK_SOURCE:
	case LINK_DEST:
	case LINK_DEST_NULL:
	case LINK_URL:
	case ACAT:
	case HCAT:
	case VCAT:
	case ROW_THR:
	case COL_THR:
	    

	  underline(y) = underline(dest);
	  if( dim == ROWM )
	  {
	    /* make sure y is not joined to a target below (vertical only) */
	    for( zlink = NextDown(link); zlink != hd; zlink = NextDown(zlink) )
	    { Child(z, zlink);
	      switch( type(z) )
	      {
	        case RECEPTIVE:
		
		  if( non_blocking(z) )
		  { zlink = PrevDown(zlink);
		    DeleteNode(z);
		  }
		  else
		  { y = z;
		    goto SUSPEND;
		  }
		  break;


	        case RECEIVING:
		
		  if( non_blocking(z) )
		  { zlink = PrevDown(zlink);
		    while( Down(z) != z )
		    { Child(tmp, Down(y));
		      if( opt_components(tmp) != nilobj )
		      { DisposeObject(opt_components(tmp));
		        opt_components(tmp) = nilobj;
		        debug3(DOG, D, "AttachGalley(%s) de-optimizing %s %s",
			  SymName(actual(hd)), SymName(actual(tmp)), "(join)");
		      }
		      DetachGalley(tmp);
		      KillGalley(tmp, FALSE);
		    }
		    DeleteNode(z);
		  }
		  else
		  { y = z;
		    goto SUSPEND;
		  }
		  break;


	        case GAP_OBJ:
		
		  if( !join(gap(z)) )  zlink = PrevDown(hd);
		  break;


	        default:	break;
	      }
	    }

	    /* if HCAT, try vertical hyphenation (vertical galleys only) */
	    if( type(y) == HCAT )  VerticalHyphenate(y);
	  }


	  /* check availability of parallel space for the first component */
	  why = nilobj;
	  Constrained(dest, &c, dim, &why);
	  debug3(DGF, DD, "  dest parallel Constrained(%s, %s) = %s",
	    EchoObject(dest), dimen(dim), EchoConstraint(&c));
	  if( !FitsConstraint(back(y, dim), fwd(y, dim), c) )
	  { BOOLEAN scaled;

	    /* if forcing galley doesn't fit, try scaling first component */
	    scaled = FALSE;
	    if( force_gall(hd) && size(y, dim) > 0 )
	    { int scale_factor;
	      scale_factor = ScaleToConstraint(back(y,dim), fwd(y,dim), &c);
	      if( scale_factor > 0.5 * SF )
	      {	char num1[20], num2[20];
		sprintf(num1, "%.1fc", (float) size(y, dim) / CM);
		sprintf(num2, "%.1fc", (float) bfc(c) / CM);
		if( dim == ROWM )
		  Error(19, 4, "%s object too high for %s space; %s inserted",
		    WARN, &fpos(y), num1, num2, KW_SCALE);
		else
		  Error(19, 5, "%s object too wide for %s space; %s inserted",
		    WARN, &fpos(y), num1, num2, KW_SCALE);
		y = InterposeScale(y, scale_factor, dim);
		scaled = TRUE;
	      }
	    }

	    /* otherwise we must reject, and warn the user */
	    if( !scaled )
	    { char num1[20], num2[20];
	      debug3(DGA, D, "  reject: vsize %s,%s in %s; y=",
		EchoLength(back(y, dim)), EchoLength(fwd(y, dim)),
		EchoConstraint(&c));
	      ifdebug(DGA, D, DebugObject(y));
	      if( size(y, dim) > 0 )
	      { sprintf(num1, "%.1fc", (float) size(y, dim) / CM);
	        sprintf(num2, "%.1fc", (float) bfc(c) / CM);
	        if( dim == ROWM )
		  Error(19, 12, "%s object too high for %s space; will try elsewhere",
		    WARN, &fpos(y), num1, num2);
	        else
		  Error(19, 13, "%s object too wide for %s space; will try elsewhere",
		    WARN, &fpos(y), num1, num2);
	      }
	      goto REJECT;
	    }

	  }

	  /* check availability of perpendicular space for first component */
	  if( dim == ROWM )
	  { perp_back = back(hd, 1-dim);  perp_fwd = fwd(hd, 1-dim);
	  }
	  else
	  { perp_back = back(y, 1-dim);  perp_fwd = fwd(y, 1-dim);
	  }
	  Constrained(dest, &c, 1-dim, &junk);
	  debug3(DGF, DD, "  dest perpendicular Constrained(%s, %s) = %s",
	    EchoObject(dest), dimen(1-dim), EchoConstraint(&c));
	  if( !FitsConstraint(perp_back, perp_fwd, c) )
	  { BOOLEAN scaled;

	    /* if forcing galley doesn't fit, try scaling first component */
	    scaled = FALSE;
	    if( force_gall(hd) && perp_back + perp_fwd > 0 )
	    { int scale_factor;
	      scale_factor = ScaleToConstraint(perp_back, perp_fwd, &c);
	      if( scale_factor > 0.5 * SF )
	      {	char num1[20], num2[20];
		sprintf(num1, "%.1fc", (float) (perp_back + perp_fwd) / CM);
		sprintf(num2, "%.1fc", (float) bfc(c) / CM);
		if( 1-dim == ROWM )
		  Error(19, 6, "%s object too high for %s space; %s inserted",
		    WARN, &fpos(y), num1, num2, KW_SCALE);
		else
		  Error(19, 7, "%s object too wide for %s space; %s inserted",
		    WARN, &fpos(y), num1, num2, KW_SCALE);
		y = InterposeScale(y, scale_factor, 1-dim);
		scaled = TRUE;
	      }
	    }

	    /* otherwise we must reject, and warn the user */
	    if( !scaled )
	    {
	      debug3(DGA, D, "  reject: vsize %s,%s in %s; y=",
		EchoLength(perp_back), EchoLength(perp_fwd),
		EchoConstraint(&c));
	      ifdebug(DGA, D, DebugObject(y));
	      goto REJECT;
	    }

	  }

	  /* dest seems OK, so perform its size adjustments */
	  debug0(DSA, D, "calling AdjustSize from AttachGalley (a)");
	  AdjustSize(dest, back(y, dim), fwd(y, dim), dim);
	  debug0(DSA, D, "calling AdjustSize from AttachGalley (b)");
	  AdjustSize(dest, perp_back, perp_fwd, 1-dim);


	  /* now check parallel space for target_galley in target */
	  Constrained(target, &c, dim, &why);
	  debug3(DGF, DD, "  target parallel Constrained(%s, %s) = %s",
	    EchoObject(target), dimen(dim), EchoConstraint(&c));
	  Child(z, LastDown(target_galley));  /* works in all cases? */
	  assert( !is_index(type(z)), "AttachGalley: is_index(z)!" );
	  assert( back(z, dim)>=0 && fwd(z, dim)>=0, "AttachGalley: z size!" );
	  if( !FitsConstraint(back(z, dim), fwd(z, dim), c) )
	  { BOOLEAN scaled;

	    debug2(DGA, D, "  why     = %d %s", (int) why, EchoObject(why));
	    debug2(DGA, D, "  limiter = %d %s", (int) limiter(hd),
	      EchoObject(limiter(hd)));

	    /* if forcing galley doesn't fit, try scaling z */
	    scaled = FALSE;
	    if( force_gall(hd) && size(z, dim) > 0 && limiter(hd) != why )
	    { int scale_factor;
	      scale_factor = ScaleToConstraint(back(z,dim), fwd(z,dim), &c);
	      if( scale_factor > 0.5 * SF )
	      {	char num1[20], num2[20];
		sprintf(num1, "%.1fc", (float) size(z, dim) / CM);
		sprintf(num2, "%.1fc", (float) bfc(c) / CM);
		if( dim == ROWM )
		  Error(19, 8, "%s object too high for %s space; %s inserted",
		    WARN, &fpos(y), num1, num2, KW_SCALE);
		else
		  Error(19, 9, "%s object too wide for %s space; %s inserted",
		    WARN, &fpos(y), num1, num2, KW_SCALE);
		z = InterposeWideOrHigh(z, dim);
		z = InterposeScale(z, scale_factor, dim);
		scaled = TRUE;
	      }
	    }

	    if( !scaled )
	    { char num1[20], num2[20];
	      limiter(hd) = why;
	      debug3(DGA, D, "  set limiter(%s) = %d %s", SymName(actual(hd)),
		(int) limiter(hd), EchoObject(limiter(hd)));
	      debug3(DGA, D, "  reject: size was %s,%s in %s; y =",
		EchoLength(back(z, dim)), EchoLength(fwd(z, dim)),
		EchoConstraint(&c));
	      ifdebug(DGA, D, DebugObject(y));
	      if( size(z, dim) > 0 )
	      { sprintf(num1, "%.1fc", (float) size(z, dim) / CM);
	        sprintf(num2, "%.1fc", (float) bfc(c) / CM);
	        if( dim == ROWM )
		  Error(19, 14, "%s object too high for %s space; will try elsewhere",
		    WARN, &fpos(y), num1, num2);
	        else
		  Error(19, 15, "%s object too wide for %s space; will try elsewhere",
		    WARN, &fpos(y), num1, num2);
	      }
	      goto REJECT;
	    }
	  }
	  limiter(hd) = why;
	  debug3(DGA, D, "  set limiter(%s) = %d %s", SymName(actual(hd)),
	    (int) limiter(hd), EchoObject(limiter(hd)));

	  /* now check perpendicular space for target_galley in target */
	  Constrained(target, &c, 1-dim, &junk);
	  debug3(DGF, DD, "  target perpendicular Constrained(%s, %s) = %s",
	    EchoObject(target), dimen(1-dim), EchoConstraint(&c));
	  Child(z, LastDown(target_galley));  /* works in all cases? */
	  assert( !is_index(type(z)), "AttachGalley: is_index(z)!" );
	  assert( back(z, 1-dim)>=0 && fwd(z, 1-dim)>=0,
	    "AttachGalley: z size (perpendicular)!" );
	  if( !FitsConstraint(back(z, 1-dim), fwd(z, 1-dim), c) )
	  { BOOLEAN scaled;

	    /* if forcing galley doesn't fit, try scaling z */
	    scaled = FALSE;
	    if( force_gall(hd) && size(z, 1-dim) > 0 )
	    { int scale_factor;
	      scale_factor = ScaleToConstraint(back(z,1-dim), fwd(z,1-dim), &c);
	      if( scale_factor > 0.5 * SF )
	      {	char num1[20], num2[20];
		sprintf(num1, "%.1fc", (float) size(z, 1-dim) / CM);
		sprintf(num2, "%.1fc", (float) bfc(c) / CM);
		if( 1-dim == ROWM )
		  Error(19, 10, "%s object too high for %s space; %s inserted",
		    WARN, &fpos(y), num1, num2, KW_SCALE);
		else
		  Error(19, 11, "%s object too wide for %s space; %s inserted",
		    WARN, &fpos(y), num1, num2, KW_SCALE);
		z = InterposeWideOrHigh(z, 1-dim);
		z = InterposeScale(z, scale_factor, 1-dim);
		scaled = TRUE;
	      }
	    }

	    if( !scaled )
	    {
	      debug3(DGA, D, "  reject: size was %s,%s in %s; y =",
		EchoLength(back(z, 1-dim)), EchoLength(fwd(z, 1-dim)),
		EchoConstraint(&c));
	      ifdebug(DGA, D, DebugObject(y));
	      goto REJECT;
	    }
	  }

	  /* target seems OK, so adjust sizes and accept */
	  if( external_hor(target) )
	  {
	    /* don't adjust any sizes, none to adjust */
	    debug0(DSA, D, "not calling AdjustSize from AttachGalley (c)");
	  }
	  else if( external_ver(target) )
	  {
	    /* adjust perp size only, to galley size */
	    debug0(DSA, D, "calling AdjustSize from AttachGalley (d)");
	    AdjustSize(target, back(target_galley, 1-dim),
	      fwd(target_galley, 1-dim), 1-dim);
	  }
	  else
	  {
	    /* adjust both directions, using z (last component) */
	    Child(z, LastDown(target_galley));
	    debug0(DSA, D, "AttachGalley AdjustSize using z =");
	    ifdebug(DSA, D, DebugObject(z));
	    debug0(DSA, D, "calling AdjustSize from AttachGalley (e)");
	    AdjustSize(target, back(z, dim), fwd(z, dim), dim);
	    debug0(DSA, D, "calling AdjustSize from AttachGalley (f)");
	    AdjustSize(target, back(z, 1-dim), fwd(z, 1-dim), 1-dim);
	  }

	  goto ACCEPT;


	default:
	    
	  assert1(FALSE, "AttachGalley:", Image(type(y)));
	  break;

      } /* end switch */
    } /* end for */

    /* null galley: promote whole galley without expanding the target */
    debug0(DGA, D, "  null galley");
    if( tg_inners != nilobj )  DisposeObject(tg_inners), tg_inners = nilobj;
    DisposeObject(target_galley);
    LeaveErrorBlock(FALSE);
    debug0(DYY, D, "] LeaveErrorBlock(FALSE) (null galley)");

    /* kill off any null objects within the galley, then transfer it */
    /* don't use Promote() since it does extra unwanted things here  */
    for( link = Down(hd);  link != hd;  link = NextDown(link) )
    { Child(y, link);
      switch( type(y) )
      {

	case GAP_OBJ:
	case CLOSURE:
	case CROSS:
	case FORCE_CROSS:
	case NULL_CLOS:
	case PAGE_LABEL:
	
	  link = PrevDown(link);
	  debug1(DGA, D, "  null galley, disposing %s", Image(type(y)));
	  DisposeChild(NextDown(link));
	  break;

	
	default:
	
	  break;
      }
    }
    TransferLinks(NextDown(hd), hd, Up(target_index));

    /* attach hd temporarily to target_index */
    MoveLink(Up(hd), target_index, PARENT);
    assert( type(hd_index) == UNATTACHED, "AttachGalley: type(hd_index)!" );
    DeleteNode(hd_index);

    /* return; only hd_inners needs to be flushed now */
    *inners = hd_inners;
    debug0(DGA, D, "] AttachGalley returning ATTACH_NULL");
    return ATTACH_NULL;


    REJECT:
	
      /* reject first component */
      /* debug1(DGA, D, "  reject %s", EchoObject(y)); */
      debug0(DGA, D, "  reject first component");
      LeaveErrorBlock(TRUE);
      debug0(DYY, D, "] LeaveErrorBlock(TRUE) (REJECT)");
      if( tg_inners != nilobj )  DisposeObject(tg_inners), tg_inners = nilobj;
      DisposeObject(target_galley);
      if( foll_or_prec(hd) == GALL_PREC && !sized(hd) )
      {
	/* move to just before the failed target */
	MoveLink(Up(hd_index), Up(target_index), PARENT);
      }
      else
      {
	/* move to just after the failed target */
	MoveLink(Up(hd_index), NextDown(Up(target_index)), PARENT);
      }
      continue;


    SUSPEND:
	
      /* suspend at first component */
      debug1(DGA, D, "  suspend %s", EchoIndex(y));
      blocked(y) = TRUE;
      LeaveErrorBlock(FALSE);
      debug0(DYY, D, "] LeaveErrorBlock(FALSE) (SUSPEND)");
      if( tg_inners != nilobj )  DisposeObject(tg_inners), tg_inners = nilobj;
      DisposeObject(target_galley);
      MoveLink(Up(hd_index), Up(target_index), PARENT);
      if( was_sized )
      { /* nothing new to flush if suspending and already sized */
	if( hd_inners != nilobj )  DisposeObject(hd_inners), hd_inners=nilobj;
	*inners = nilobj;
      }
      else
      { /* flush newly discovered inners if not sized before */
	*inners = hd_inners;
      }
      debug0(DGA, D, "] AttachGalley returning ATTACH_SUSPEND");
      *suspend_pt = y;
      return ATTACH_SUSPEND;


    ACCEPT:
	
      /* accept first component; now committed to the attach */
      debug3(DGA, D, "  accept %s %s %s", Image(type(y)), EchoObject(y),
	EchoFilePos(&fpos(y)));
      LeaveErrorBlock(TRUE);
      debug0(DYY, D, "] LeaveErrorBlock(TRUE) (ACCEPT)");

      /* attach hd to dest */
      MoveLink(Up(hd), dest_index, PARENT);
      assert( type(hd_index) == UNATTACHED, "AttachGalley: type(hd_index)!" );
      DeleteNode(hd_index);

      /* move first component of hd into dest */
      /* nb Interpose must be done after all AdjustSize calls */
      if( dim == ROWM && !external_ver(dest) )
	Interpose(dest, VCAT, hd, y);
      else if( dim == COLM && !external_hor(dest) )
      { Interpose(dest, ACAT, y, y);
	Parent(junk, Up(dest));
	assert( type(junk) == ACAT, "AttachGalley: type(junk) != ACAT!" );
	StyleCopy(save_style(junk), save_style(dest));
	adjust_cat(junk) = padjust(save_style(junk));
      }
      debug1(DGS, D, "calling Promote(hd, %s) from AttachGalley/ACCEPT",
	link == hd ? "hd" : "NextDown(link)");
      Promote(hd, link == hd ? hd : NextDown(link), dest_index, TRUE);

      /* move target_galley into target */
      /* nb Interpose must be done after all AdjustSize calls */
      if( !(external_ver(target) || external_hor(target)) )
      {	Child(z, LastDown(target_galley));
	Interpose(target, VCAT, z, z);
      }
      debug0(DGS, D, "calling Promote(target_galley) from AttachGalley/ACCEPT");
      Promote(target_galley, target_galley, target_index, TRUE);
      DeleteNode(target_galley);
      assert(Down(target_index)==target_index, "AttachGalley: target_ind");
      if( blocked(target_index) )  blocked(dest_index) = TRUE;
      DeleteNode(target_index);

      /* return; both tg_inners and hd_inners need to be flushed now;        */
      /* if was_sized, hd_inners contains the inners of the first component; */
      /* otherwise it contains the inners of all components, from SizeGalley */
      if( tg_inners == nilobj ) *inners = hd_inners;
      else if( hd_inners == nilobj ) *inners = tg_inners;
      else
      {	TransferLinks(Down(hd_inners), hd_inners, tg_inners);
	DeleteNode(hd_inners);
	*inners = tg_inners;
      }
      debug0(DGA, D, "] AttachGalley returning ATTACH_ACCEPT");
      ifdebug(DGA, D,
	if( dim == COLM && !external_hor(dest) )
	{ OBJECT z;
	  Parent(z, Up(dest));
	  debug2(DGA, D, "  COLM dest_encl on exit = %s %s",
	    Image(type(z)), EchoObject(z));
	}
      )
      return ATTACH_ACCEPT;

  } /* end for */
Beispiel #21
0
void buildFakeAngTree(const Char_t* outtag,
                      const Float_t timereso,     // ns
                      const UInt_t  simevts=1,
                      const Float_t thetaOpt=400, // deg
                      const Float_t phiOpt=400,   // deg
                      const Float_t coneOpt=400,  // deg
                      const UInt_t  rseed=23192,
                      const Float_t norm=100.0,   // mV
                      const Float_t noise=20.0,   // mV
                      const Char_t* outdir="/data/users/cjreed/work/simEvts",
                      const Char_t* infn="/w2/arianna/jtatar/nt.sigtemps.root",
                      const Char_t* geofn="/data/users/cjreed/work/"
                                          "BounceStudy/Stn10/"
                                          "CampSiteGeometry.root") {
   // if any of the angles (thetaOpt, phiOpt, coneOpt) > 360, a random
   // value will be used instead
   //
   // expect angles in the Templates tree to be in degrees
   //
   // expect the waveforms in the Templates tree to have amplitude 1
   
   TRandom3 rnd(rseed);
   
   
   geof = TFile::Open(geofn);
   gg = dynamic_cast<TGeoManager*>(geof->Get("CampSite2013"));
   site = dynamic_cast<const TSnGeoStnSite*>(gg->GetTopVolume());
   
   
   TVector3 pos[NSnConstants::kNchans], nvec[NSnConstants::kNchans];
   for (UChar_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      site->SetLPDAPosition(ch, pos[ch]);
      site->SetLPDANormalVec(ch, nvec[ch]);
      Printf("pos ch%d:",ch);
      pos[ch].Print();
      Printf("normal ch%d:",ch);
      nvec[ch].Print();
   }
   
   TArrayD zeros(6);
   
   
   inf = TFile::Open(infn);
   nnt = dynamic_cast<TTree*>(inf->Get("Templates"));
   
   TString infns(infn);
   TString indir;
   Int_t fl(0);
   if (infns.Contains('/')) {
      fl = infns.Last('/') + 1;
      indir = infns(0, fl-1);
   }
   TString plaininfn = infns(fl, infns.Length()-fl);
   TString outfn = Form("%s/FakeEvts.%s.%s", outdir, outtag,
                        plaininfn.Data());
   outf = TFile::Open(outfn.Data(),"recreate");
   outf->cd();
   TParameter<Float_t> trp("TimeResolution", timereso);
   trp.Write();
   TParameter<Float_t> nmp("Normalization", norm);
   nmp.Write();
   TParameter<Float_t> nop("NoiseRMS", noise);
   nop.Write();
   TParameter<UInt_t> rsp("RandomSeed", rseed);
   rsp.Write();
   
   
   TSnCalWvData* wave = new TSnCalWvData;
   Float_t eang(0), hang(0), hpf(0), limiter(0), coneang(0);
   Bool_t bice(kFALSE);
   nnt->SetBranchAddress("wave.",&wave);
   nnt->SetBranchAddress("EAng",&eang);
   nnt->SetBranchAddress("HAng",&hang);
   nnt->SetBranchAddress("hpf",&hpf);
   nnt->SetBranchAddress("limiter",&limiter);
   nnt->SetBranchAddress("coneAng",&coneang);
   nnt->SetBranchAddress("bIce",&bice);
   // to look up waveform for EAng, HAng
   nnt->BuildIndex("EAng + (1000*HAng)","coneAng");
   // find the max angles
   Printf("finding allowed angles...");
   std::set<Float_t> Eangs, Hangs, Cangs;
   const Long64_t nnents = nnt->GetEntries();
   for (Long64_t i=0; i<nnents; ++i) {
      nnt->GetEntry(i);
      Eangs.insert(eang);
      Hangs.insert(hang);
      Cangs.insert(coneang);
   }
#ifdef DEBUG
   std::set<Float_t>::const_iterator ang, end = Eangs.end();
   Printf("EAngs:");
   for (ang=Eangs.begin(); ang!=end; ++ang) {
      Printf("%g",*ang);
   }
   Printf("HAngs:");
   for (ang=Hangs.begin(), end=Hangs.end(); ang!=end; ++ang) {
      Printf("%g",*ang);
   }
   Printf("ConeAngs:");
   for (ang=Cangs.begin(), end=Cangs.end(); ang!=end; ++ang) {
      Printf("%g",*ang);
   }
#endif
   
   Float_t theta(0), phi(0), cone(0);
   Float_t EAng[NSnConstants::kNchans], 
           HAng[NSnConstants::kNchans];
   Float_t CAng(0);
   TSnCalWvData* evdat = new TSnCalWvData;
   TSnEventMetadata* meta = new TSnEventMetadata;
   TSnEventHeader* hdr = new TSnEventHeader;
   //ot = nnt->CloneTree(0);
   //ot->SetName("SimTemplEvts");
   ot = new TTree("SimTemplEvts","simulated events from templates",1);
   ot->SetDirectory(outf);
   ot->Branch("EventMetadata.",&meta);
   ot->Branch("EventHeader.",&hdr);
   ot->Branch("EAng",&(EAng[0]),Form("EAng[%hhu]/F",NSnConstants::kNchans));
   ot->Branch("HAng",&(HAng[0]),Form("HAng[%hhu]/F",NSnConstants::kNchans));
   ot->Branch("CAng",&CAng,"CAng/F");
   ot->Branch("theta",&theta,"theta/F");
   ot->Branch("phi",&phi,"phi/F");
   ot->Branch("NuData.",&evdat);
   // some useful aliases
   TString an;
   for (UChar_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      // to use as a cut for a particular channel:
      an = Form("Ch%d",ch);
      ot->SetAlias(an.Data(),
                   Form("(Iteration$>=(%hhu*%hhu)) && (Iteration$<(%hhu*%hhu))",
                        NSnConstants::kNsamps, ch,
                        NSnConstants::kNsamps,
                        static_cast<UChar_t>(ch+1)));
      // to use as a variable showing the sample number [0,127] for any chan
      an = Form("SmpCh%d",ch);
      ot->SetAlias(an.Data(),
                   Form("Iteration$-%u", static_cast<UInt_t>(ch)
                        *static_cast<UInt_t>(NSnConstants::kNsamps)));
      // e.g. Draw("RawData.fData:SmpCh2","EventHeader.fNum==21 && Ch2","l")
   }

   Printf("generating events...");
   TStopwatch timer;
   timer.Start();
   
   for (UInt_t i=0; i<simevts; ++i) {
      
      if ( (i%1000)==0 ) {
         fprintf(stderr,"Processing %u/%u ...            \r",i,simevts);
      }
      
      // choose angles
      theta = (thetaOpt>360.) ? TMath::ACos( rnd.Uniform(-1.0, 0.0) ) 
                              : thetaOpt * TMath::DegToRad();
      phi   = (phiOpt>360.) ? rnd.Uniform(0.0, TMath::TwoPi())
                            : phiOpt * TMath::DegToRad();
      cone  = (coneOpt>360.) 
         ? rnd.Uniform(*(Cangs.begin()), *(Cangs.rbegin()))
         : coneOpt; // leave this one in degrees (as in the tree)
      CAng = findNearestAllowedAngle(Cangs, cone);
      
#ifdef DEBUG
      Printf("--- theta=%g, phi=%g, cone=%g",
             theta*TMath::RadToDeg(), phi*TMath::RadToDeg(), cone);
#endif
      
      // calculate channel shifts
      TArrayD pwdt = NSnChanCorl::GetPlaneWaveOffsets(theta,
                                                      phi,
                                                      zeros,
                                                      pos,
                                                      kNgTopFirn);
      TVector3 dir;
      dir.SetMagThetaPhi(1.0, theta, phi);
      
#ifdef DEBUG
      TObjArray graphs;
      graphs.SetOwner(kTRUE);
      TCanvas* c1 = new TCanvas("c1","c1",800,700);
      c1->Divide(2,2);
#endif
      
      for (UChar_t ch=0; ch<NSnConstants::kNchans; ++ch) {
         
         // look up the EAng, fhang for this antenna
         Float_t feang(0), fhang(0);
         findEangHang(nvec[ch], dir, feang, fhang);
         feang  = TMath::Abs(TVector2::Phi_mpi_pi(feang));
         fhang  = TMath::Abs(TVector2::Phi_mpi_pi(fhang));
         feang *= TMath::RadToDeg();
         fhang *= TMath::RadToDeg();
         // find closest allowed angle
         EAng[ch] = findNearestAllowedAngle(Eangs, feang);
         HAng[ch] = findNearestAllowedAngle(Hangs, fhang);
         const Long64_t ni = 
            nnt->GetEntryNumberWithIndex(EAng[ch] + (1000*HAng[ch]), CAng);
#ifdef DEBUG
         Printf("EAng=%g (%g), HAng=%g (%g), CAng=%g, ni=%lld",
                EAng[ch],feang,HAng[ch],fhang,CAng,ni);
#endif
         if (ni>-1) {
            nnt->GetEntry(ni);
#ifdef DEBUG
            c1->cd(ch+1);
            TGraph* och = wave->NewGraphForChan(0, kTRUE);
            const Int_t ochnp = och->GetN();
            Double_t* ochy = och->GetY();
            for (Int_t k=0; k<ochnp; ++k, ++ochy) {
               *ochy *= norm;
            }
            graphs.Add(och);
            och->SetLineColor(kBlack);
            och->SetMarkerColor(kBlack);
            och->SetMarkerStyle(7);
            och->Draw("apl");
#endif
            
            // first calculate the shift between chans due to the angle
            // ch0 is always unshifted; other chans shifted w.r.t. ch0
            // jitter the shift by the specified timing resolution
            const Double_t shift = 
               rnd.Gaus( (ch==0) ? 0.0
                            : -pwdt.At( TSnRecoChanOffsets::IndexFor(ch, 0) ),
                         timereso);
            // get a graph of the waveform
            // data only in channel 0 of the template
            TGraph* gch = wave->NewGraphForChan(0, kTRUE);
            // "fit" the graph with an spline interpolation
            TSpline3* gsp = new TSpline3("stmp", gch);
            // evaluate the spline at the new sample positions
            // (shifted, but NOT wrapped)
            // and save that into the event data waveform
            Float_t* d = evdat->GetData(ch);
            const Float_t tstep = 1.0 / NSnConstants::kSampRate;
            const Float_t tlast = static_cast<Float_t>(NSnConstants::kNsamps-1)
               / NSnConstants::kSampRate;
            Float_t xloc = shift;
            for (UChar_t s=0; s<NSnConstants::kNsamps; ++s, ++d, xloc+=tstep) {
               if ( (xloc<0.0) || (xloc>=tlast) ) {
                  *d = 0.0;
               } else {
                  *d = gsp->Eval( xloc );
               }
            }
#ifdef DEBUG
            Printf("ch%hhu: shift=%g, dt=%g", ch, shift,
                   (ch==0) ? 0.0
                   : pwdt.At( TSnRecoChanOffsets::IndexFor(ch, 0) ));
            
            TGraph* fch = evdat->NewGraphForChan(ch, kTRUE);
            Double_t* y = gch->GetY();
            Double_t* fy = fch->GetY();
            for (UChar_t s=0; s<NSnConstants::kNsamps; ++s, ++y, ++fy) {
               *y *= norm;
               *fy *= norm;
            }
            
            gch->SetLineColor(kRed+1);
            gch->SetMarkerColor(kRed+1);
            gch->SetMarkerStyle(7);
            gch->Draw("pl");
            
            delete gsp;
            gsp = new TSpline3("stmp",gch);
            gsp->SetLineColor(kAzure-6);
            gsp->SetMarkerColor(kAzure-6);
            gsp->SetMarkerStyle(7);
            gsp->Draw("pl same");
            
            graphs.Add(fch);
            fch->SetLineColor(kOrange+7);
            fch->SetMarkerColor(kOrange+7);
            fch->SetMarkerStyle(7);
            fch->Draw("pl");
#endif


            d = evdat->GetData(ch);
            // finally add noise to the waveform
            for (UChar_t s=0; s<NSnConstants::kNsamps; ++s, ++d) {
               *d = rnd.Gaus( (*d) * norm, noise );
            }
            
#ifdef DEBUG
            TGraph* nch = evdat->NewGraphForChan(ch, kTRUE);
            graphs.Add(nch);
            nch->SetLineColor(kGreen+2);
            nch->SetMarkerColor(kGreen+2);
            nch->SetMarkerStyle(7);
            nch->Draw("pl");
#endif
            
            // cleanup
#ifdef DEBUG
            graphs.Add(gch);
            graphs.Add(gsp);
#else
            delete gch;
            delete gsp;
#endif
         }

      } // end channel loop

#ifdef DEBUG
      TObject* o(0);
      while ( (o=c1->WaitPrimitive())!=0 ) {
         gSystem->ProcessEvents();
      }
      delete c1;
#endif
         
         // save this event
         ot->Fill();
         
   } // end event loop

   fprintf(stderr,"\n");

   timer.Stop();
   Printf("Finished generating events in:");
   timer.Print();
   
   outf->Write();
   
   Printf("Wrote [%s]",outf->GetName());
   
   delete outf; outf=0; // close file
}
Beispiel #22
0
static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
{
	// Get the filter from the frame
	mlt_filter this = mlt_frame_pop_audio( frame );

	// Get the properties from the filter
	mlt_properties filter_props = MLT_FILTER_PROPERTIES( this );

	// Get the frame's filter instance properties
	mlt_properties instance_props = mlt_frame_unique_properties( frame, MLT_FILTER_SERVICE( this ) );

	// Get the parameters
	double gain = mlt_properties_get_double( instance_props, "gain" );
	double max_gain = mlt_properties_get_double( instance_props, "max_gain" );
	double limiter_level = 0.5; /* -6 dBFS */
	int normalise =  mlt_properties_get_int( instance_props, "normalise" );
	double amplitude =  mlt_properties_get_double( instance_props, "amplitude" );
	int i, j;
	double sample;
	int16_t peak;

	if ( mlt_properties_get( instance_props, "limiter" ) != NULL )
		limiter_level = mlt_properties_get_double( instance_props, "limiter" );
	
	// Get the producer's audio
	*format = mlt_audio_s16;
	mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
//	fprintf( stderr, "filter_volume: frequency %d\n", *frequency );

	// Determine numeric limits
	int bytes_per_samp = (samp_width - 1) / 8 + 1;
	int samplemax = (1 << (bytes_per_samp * 8 - 1)) - 1;
	int samplemin = -samplemax - 1;

	mlt_service_lock( MLT_FILTER_SERVICE( this ) );

	if ( normalise )
	{
		int window = mlt_properties_get_int( filter_props, "window" );
		double *smooth_buffer = mlt_properties_get_data( filter_props, "smooth_buffer", NULL );

		if ( window > 0 && smooth_buffer != NULL )
		{
			int smooth_index = mlt_properties_get_int( filter_props, "_smooth_index" );
			
			// Compute the signal power and put into smoothing buffer
			smooth_buffer[ smooth_index ] = signal_max_power( *buffer, *channels, *samples, &peak );
//			fprintf( stderr, "filter_volume: raw power %f ", smooth_buffer[ smooth_index ] );
			if ( smooth_buffer[ smooth_index ] > EPSILON )
			{
				mlt_properties_set_int( filter_props, "_smooth_index", ( smooth_index + 1 ) % window );

				// Smooth the data and compute the gain
//				fprintf( stderr, "smoothed %f over %d frames\n", get_smoothed_data( smooth_buffer, window ), window );
				gain *= amplitude / get_smoothed_data( smooth_buffer, window );
			}
		}
		else
		{
			gain *= amplitude / signal_max_power( (int16_t*) *buffer, *channels, *samples, &peak );
		}
	}
	
//	if ( gain > 1.0 && normalise )
//		fprintf(stderr, "filter_volume: limiter level %f gain %f\n", limiter_level, gain );

	if ( max_gain > 0 && gain > max_gain )
		gain = max_gain;

	// Initialise filter's previous gain value to prevent an inadvertant jump from 0
	mlt_position last_position = mlt_properties_get_position( filter_props, "_last_position" );
	mlt_position current_position = mlt_frame_get_position( frame );
	if ( mlt_properties_get( filter_props, "_previous_gain" ) == NULL
	     || current_position != last_position + 1 )
		mlt_properties_set_double( filter_props, "_previous_gain", gain );

	// Start the gain out at the previous
	double previous_gain = mlt_properties_get_double( filter_props, "_previous_gain" );

	// Determine ramp increment
	double gain_step = ( gain - previous_gain ) / *samples;
//	fprintf( stderr, "filter_volume: previous gain %f current gain %f step %f\n", previous_gain, gain, gain_step );

	// Save the current gain for the next iteration
	mlt_properties_set_double( filter_props, "_previous_gain", gain );
	mlt_properties_set_position( filter_props, "_last_position", current_position );

	mlt_service_unlock( MLT_FILTER_SERVICE( this ) );

	// Ramp from the previous gain to the current
	gain = previous_gain;

	int16_t *p = (int16_t*) *buffer;

	// Apply the gain
	for ( i = 0; i < *samples; i++ )
	{
		for ( j = 0; j < *channels; j++ )
		{
			sample = *p * gain;
			*p = ROUND( sample );
		
			if ( gain > 1.0 )
			{
				/* use limiter function instead of clipping */
				if ( normalise )
					*p = ROUND( samplemax * limiter( sample / (double) samplemax, limiter_level ) );
				
				/* perform clipping */
				else if ( sample > samplemax )
					*p = samplemax;
				else if ( sample < samplemin )
					*p = samplemin;
			}
			p++;
		}
		gain += gain_step;
	}
	
	return 0;
}
void Foam::MULES::explicitSolve
(
    const RhoType& rho,
    volScalarField& psi,
    const surfaceScalarField& phi,
    surfaceScalarField& phiPsi,
    const SpType& Sp,
    const SuType& Su,
    const scalar psiMax,
    const scalar psiMin
)
{
    Info<< "MULES: Solving for " << psi.name() << endl;

    const fvMesh& mesh = psi.mesh();
    psi.correctBoundaryConditions();

    surfaceScalarField phiBD(upwind<scalar>(psi.mesh(), phi).flux(psi));

    surfaceScalarField& phiCorr = phiPsi;
    phiCorr -= phiBD;

    scalarField allLambda(mesh.nFaces(), 1.0);

    slicedSurfaceScalarField lambda
    (
        IOobject
        (
            "lambda",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE,
            false
        ),
        mesh,
        dimless,
        allLambda,
        false   // Use slices for the couples
    );

    limiter
    (
        allLambda,
        rho,
        psi,
        phiBD,
        phiCorr,
        Sp,
        Su,
        psiMax,
        psiMin,
        3
    );

    phiPsi = phiBD + lambda*phiCorr;

    scalarField& psiIf = psi;
    const scalarField& psi0 = psi.oldTime();
    const scalar deltaT = mesh.time().deltaTValue();

    psiIf = 0.0;
    fvc::surfaceIntegrate(psiIf, phiPsi);

    if (mesh.moving())
    {
        psiIf =
        (
            mesh.Vsc0()().field()*rho.oldTime().field()
           *psi0/(deltaT*mesh.Vsc()().field())
          + Su.field()
          - psiIf
        )/(rho.field()/deltaT - Sp.field());
    }
    else
    {
        psiIf =
        (
            rho.oldTime().field()*psi0/deltaT
          + Su.field()
          - psiIf
        )/(rho.field()/deltaT - Sp.field());
    }

    psi.correctBoundaryConditions();
}
void Foam::MULES::implicitSolve
(
    const RhoType& rho,
    volScalarField& psi,
    const surfaceScalarField& phi,
    surfaceScalarField& phiPsi,
    const SpType& Sp,
    const SuType& Su,
    const scalar psiMax,
    const scalar psiMin
)
{
    const fvMesh& mesh = psi.mesh();

    const dictionary& MULEScontrols = mesh.solverDict(psi.name());

    label maxIter
    (
        readLabel(MULEScontrols.lookup("maxIter"))
    );

    label nLimiterIter
    (
        readLabel(MULEScontrols.lookup("nLimiterIter"))
    );

    scalar maxUnboundedness
    (
        readScalar(MULEScontrols.lookup("maxUnboundedness"))
    );

    scalar CoCoeff
    (
        readScalar(MULEScontrols.lookup("CoCoeff"))
    );

    scalarField allCoLambda(mesh.nFaces());

    {
        tmp<surfaceScalarField> Cof =
            mesh.time().deltaT()*mesh.surfaceInterpolation::deltaCoeffs()
           *mag(phi)/mesh.magSf();

        slicedSurfaceScalarField CoLambda
        (
            IOobject
            (
                "CoLambda",
                mesh.time().timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE,
                false
            ),
            mesh,
            dimless,
            allCoLambda,
            false   // Use slices for the couples
        );

        CoLambda == 1.0/max(CoCoeff*Cof, scalar(1));
    }

    scalarField allLambda(allCoLambda);
    //scalarField allLambda(mesh.nFaces(), 1.0);

    slicedSurfaceScalarField lambda
    (
        IOobject
        (
            "lambda",
            mesh.time().timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::NO_WRITE,
            false
        ),
        mesh,
        dimless,
        allLambda,
        false   // Use slices for the couples
    );

    linear<scalar> CDs(mesh);
    upwind<scalar> UDs(mesh, phi);
    //fv::uncorrectedSnGrad<scalar> snGrads(mesh);

    fvScalarMatrix psiConvectionDiffusion
    (
        fvm::ddt(rho, psi)
      + fv::gaussConvectionScheme<scalar>(mesh, phi, UDs).fvmDiv(phi, psi)
        //- fv::gaussLaplacianScheme<scalar, scalar>(mesh, CDs, snGrads)
        //.fvmLaplacian(Dpsif, psi)
      - fvm::Sp(Sp, psi)
      - Su
    );

    surfaceScalarField phiBD(psiConvectionDiffusion.flux());

    surfaceScalarField& phiCorr = phiPsi;
    phiCorr -= phiBD;

    for (label i=0; i<maxIter; i++)
    {
        if (i != 0 && i < 4)
        {
            allLambda = allCoLambda;
        }

        limiter
        (
            allLambda,
            rho,
            psi,
            phiBD,
            phiCorr,
            Sp,
            Su,
            psiMax,
            psiMin,
            nLimiterIter
        );

        solve
        (
            psiConvectionDiffusion + fvc::div(lambda*phiCorr),
            MULEScontrols
        );

        scalar maxPsiM1 = gMax(psi.internalField()) - 1.0;
        scalar minPsi = gMin(psi.internalField());

        scalar unboundedness = max(max(maxPsiM1, 0.0), -min(minPsi, 0.0));

        if (unboundedness < maxUnboundedness)
        {
            break;
        }
        else
        {
            Info<< "MULES: max(" << psi.name() << " - 1) = " << maxPsiM1
                << " min(" << psi.name() << ") = " << minPsi << endl;

            phiBD = psiConvectionDiffusion.flux();

            /*
            word gammaScheme("div(phi,gamma)");
            word gammarScheme("div(phirb,gamma)");

            const surfaceScalarField& phir =
                mesh.lookupObject<surfaceScalarField>("phir");

            phiCorr =
                fvc::flux
                (
                    phi,
                    psi,
                    gammaScheme
                )
              + fvc::flux
                (
                    -fvc::flux(-phir, scalar(1) - psi, gammarScheme),
                    psi,
                    gammarScheme
                )
                - phiBD;
            */
        }
    }

    phiPsi = psiConvectionDiffusion.flux() + lambda*phiCorr;
}
Beispiel #25
0
static void constrain(strange1_struct *strange1, t_symbol *s, int argc, t_atom *argv) {
	int i;
	t_atom *arg = argv;
	if (argc == 0) {
		// reset to full limits of search ranges
		strange1 -> a0_lo = M_a0_lo;
		strange1 -> a0_hi = M_a0_hi;
		strange1 -> a1_lo = M_a1_lo;
		strange1 -> a1_hi = M_a1_hi;
		strange1 -> a2_lo = M_a2_lo;
		strange1 -> a2_hi = M_a2_hi;
		strange1 -> a3_lo = M_a3_lo;
		strange1 -> a3_hi = M_a3_hi;
		strange1 -> a4_lo = M_a4_lo;
		strange1 -> a4_hi = M_a4_hi;
		strange1 -> a5_lo = M_a5_lo;
		strange1 -> a5_hi = M_a5_hi;
		strange1 -> b0_lo = M_b0_lo;
		strange1 -> b0_hi = M_b0_hi;
		strange1 -> b1_lo = M_b1_lo;
		strange1 -> b1_hi = M_b1_hi;
		strange1 -> b2_lo = M_b2_lo;
		strange1 -> b2_hi = M_b2_hi;
		strange1 -> b3_lo = M_b3_lo;
		strange1 -> b3_hi = M_b3_hi;
		strange1 -> b4_lo = M_b4_lo;
		strange1 -> b4_hi = M_b4_hi;
		strange1 -> b5_lo = M_b5_lo;
		strange1 -> b5_hi = M_b5_hi;
		return;
	}
	if (argc == 1) {
		// set the ranges based on percentage of full range
		double percent = atom_getfloat(arg);
		double a0_spread = ((M_a0_hi - M_a0_lo) * percent) / 2;
		double a1_spread = ((M_a1_hi - M_a1_lo) * percent) / 2;
		double a2_spread = ((M_a2_hi - M_a2_lo) * percent) / 2;
		double a3_spread = ((M_a3_hi - M_a3_lo) * percent) / 2;
		double a4_spread = ((M_a4_hi - M_a4_lo) * percent) / 2;
		double a5_spread = ((M_a5_hi - M_a5_lo) * percent) / 2;
		double b0_spread = ((M_b0_hi - M_b0_lo) * percent) / 2;
		double b1_spread = ((M_b1_hi - M_b1_lo) * percent) / 2;
		double b2_spread = ((M_b2_hi - M_b2_lo) * percent) / 2;
		double b3_spread = ((M_b3_hi - M_b3_lo) * percent) / 2;
		double b4_spread = ((M_b4_hi - M_b4_lo) * percent) / 2;
		double b5_spread = ((M_b5_hi - M_b5_lo) * percent) / 2;
		strange1 -> a0_lo = strange1 -> a0 - a0_spread;
		strange1 -> a0_hi = strange1 -> a0 + a0_spread;
		strange1 -> a1_lo = strange1 -> a1 - a1_spread;
		strange1 -> a1_hi = strange1 -> a1 + a1_spread;
		strange1 -> a2_lo = strange1 -> a2 - a2_spread;
		strange1 -> a2_hi = strange1 -> a2 + a2_spread;
		strange1 -> a3_lo = strange1 -> a3 - a3_spread;
		strange1 -> a3_hi = strange1 -> a3 + a3_spread;
		strange1 -> a4_lo = strange1 -> a4 - a4_spread;
		strange1 -> a4_hi = strange1 -> a4 + a4_spread;
		strange1 -> a5_lo = strange1 -> a5 - a5_spread;
		strange1 -> a5_hi = strange1 -> a5 + a5_spread;
		strange1 -> b0_lo = strange1 -> b0 - b0_spread;
		strange1 -> b0_hi = strange1 -> b0 + b0_spread;
		strange1 -> b1_lo = strange1 -> b1 - b1_spread;
		strange1 -> b1_hi = strange1 -> b1 + b1_spread;
		strange1 -> b2_lo = strange1 -> b2 - b2_spread;
		strange1 -> b2_hi = strange1 -> b2 + b2_spread;
		strange1 -> b3_lo = strange1 -> b3 - b3_spread;
		strange1 -> b3_hi = strange1 -> b3 + b3_spread;
		strange1 -> b4_lo = strange1 -> b4 - b4_spread;
		strange1 -> b4_hi = strange1 -> b4 + b4_spread;
		strange1 -> b5_lo = strange1 -> b5 - b5_spread;
		strange1 -> b5_hi = strange1 -> b5 + b5_spread;
		limiter(strange1);
		return;
	}
	if (argc != M_param_count * 2) {
		post("Invalid number of arguments for strange1 constraints, requires 24 values, got %d", argc);
		return;
	}
	strange1 -> a0_lo = atom_getfloat(arg++);
	strange1 -> a0_hi = atom_getfloat(arg++);
	strange1 -> a1_lo = atom_getfloat(arg++);
	strange1 -> a1_hi = atom_getfloat(arg++);
	strange1 -> a2_lo = atom_getfloat(arg++);
	strange1 -> a2_hi = atom_getfloat(arg++);
	strange1 -> a3_lo = atom_getfloat(arg++);
	strange1 -> a3_hi = atom_getfloat(arg++);
	strange1 -> a4_lo = atom_getfloat(arg++);
	strange1 -> a4_hi = atom_getfloat(arg++);
	strange1 -> a5_lo = atom_getfloat(arg++);
	strange1 -> a5_hi = atom_getfloat(arg++);
	strange1 -> b0_lo = atom_getfloat(arg++);
	strange1 -> b0_hi = atom_getfloat(arg++);
	strange1 -> b1_lo = atom_getfloat(arg++);
	strange1 -> b1_hi = atom_getfloat(arg++);
	strange1 -> b2_lo = atom_getfloat(arg++);
	strange1 -> b2_hi = atom_getfloat(arg++);
	strange1 -> b3_lo = atom_getfloat(arg++);
	strange1 -> b3_hi = atom_getfloat(arg++);
	strange1 -> b4_lo = atom_getfloat(arg++);
	strange1 -> b4_hi = atom_getfloat(arg++);
	strange1 -> b5_lo = atom_getfloat(arg++);
	strange1 -> b5_hi = atom_getfloat(arg++);
	limiter(strange1);
}
int main(void)
{
  ArSerialConnection con;
  ArRobot robot;
  int ret;
  std::string str;
  ArActionLimiterForwards limiter("speed limiter near", 225, 600, 250);
  ArActionLimiterForwards limiterFar("speed limiter far", 225, 1100, 400);
  ArActionTableSensorLimiter tableLimiter;
  ArActionLimiterBackwards backwardsLimiter;
  ArActionConstantVelocity stop("stop", 0);
  ArSonarDevice sonar;
  ArACTS_1_2 acts;
  ArPTZ *ptz;
  ptz = new ArVCC4(&robot, true);
  ArGripper gripper(&robot);
  
  Acquire acq(&acts, &gripper);
  DriveTo driveTo(&acts, &gripper, ptz);
  DropOff dropOff(&acts, &gripper, ptz);
  PickUp pickUp(&acts, &gripper, ptz);
  

  TakeBlockToWall takeBlock(&robot, &gripper, ptz, &acq, &driveTo, &pickUp,
			    &dropOff, &tableLimiter);

  if (!acts.openPort(&robot))
  {
    printf("Could not connect to acts, exiting\n");
    exit(0);    
  }
  Aria::init();
  
  robot.addRangeDevice(&sonar);
  //con.setBaud(38400);
  if ((ret = con.open()) != 0)
  {
    str = con.getOpenMessage(ret);
    printf("Open failed: %s\n", str.c_str());
    Aria::shutdown();
    return 1;
  }

  robot.setDeviceConnection(&con);
  if (!robot.blockingConnect())
  {
    printf("Could not connect to robot... exiting\n");
    Aria::shutdown();
    return 1;
  }

  ptz->init();
  ArUtil::sleep(8000);
  printf("### 2222\n");
  ptz->panTilt(0, -40);
  printf("### whee\n");
  ArUtil::sleep(8000);
  robot.setAbsoluteMaxTransVel(400);

  robot.setStateReflectionRefreshTime(250);
  robot.comInt(ArCommands::ENABLE, 1);
  robot.comInt(ArCommands::SOUNDTOG, 0);

  ArUtil::sleep(200);
  robot.addAction(&tableLimiter, 100);
  robot.addAction(&limiter, 99);
  robot.addAction(&limiterFar, 98);
  robot.addAction(&backwardsLimiter, 97);
  robot.addAction(&acq, 77);
  robot.addAction(&driveTo, 76);
  robot.addAction(&pickUp, 75);
  robot.addAction(&dropOff, 74);
  robot.addAction(&stop, 30);

  robot.run(true);
  
  Aria::shutdown();
  return 0;
}
Beispiel #27
0
int main(int argc, char **argv)
{
	if (argc != 2)
	{
		std::cerr << "Usage: " << argv[0] << " <game directory>" << std::endl;
		return -1;
	}
	// Create window
	glfwInit();
	if (!glfwOpenWindow(1024, 768, 8, 8, 8, 8, 24, 8, GLFW_WINDOW))
	{
		glfwTerminate();
		std::cerr << "Could not create render window." << std::endl;
		return -1;
	}
	glfwGetMousePos(&oldx, &oldy);
	glfwSetMousePosCallback(mouseInput);
	glfwSetMouseButtonCallback(mouseButtonInput);
	glfwSetKeyCallback(keyboardInput);
	glfwSetCharCallback(charInput);
	glfwDisable(GLFW_MOUSE_CURSOR);
	// Create engine
	peak::Engine engine;
	engine.setDirectory(argv[1]);
	// Initialize graphics
	graphics.setEngine(&engine);
	if (!graphics.init(1024, 768))
	{
		glfwTerminate();
		std::cerr << "Could not initialize graphics." << std::endl;
		return -1;
	}
	/*peak::graphics::CameraSceneNode *camera = new peak::graphics::CameraSceneNode(&graphics,
		"pipelines/deferred.pipeline.xml");
	camera->setParent(graphics.getRootSceneNode());
	camera->setPosition(peak::Vector3F(0, 0, 10));
	camera->setRotation(peak::Vector3F(0, 10, 0));
	graphics.setDefaultCamera(camera);*/
	// Create game
	peak::XMLGame *game = new peak::XMLGame();
	network.registerComponents(game);
	graphics.registerComponents(game);
	physics.registerComponents(game);
	engine.setGame(game);
	if (!game->load())
	{
		std::cerr << "Could not load the game." << std::endl;
		return -1;
	}
	/*// Initialize networking
	peak::WorldComponent *worldcomponent = 0;
	bool isserver = false;
	bool isclient = false;
	peak::network::ClientWorldComponent *client = 0;
	peak::network::ServerWorldComponent *server = new peak::network::ServerWorldComponent(0);
	if (server->init(new peak::Buffer()))
	{
		worldcomponent = server;
		isserver = true;
	}
	else
	{
		delete server;
		client = new peak::network::ClientWorldComponent(0);
		if (!client->init("localhost", 27272))
		{
			delete client;
			glfwTerminate();
			std::cerr << "Could not initialize networking." << std::endl;
			return -1;
		}
		worldcomponent = client;
		isclient = true;
	}
	peak::XMLWorld *world = new peak::XMLWorld(&engine,
		engine.getDirectory() + "/Data/Worlds/Test.xml");
	worldcomponent->setWorld(world);
	world->addComponent(worldcomponent);
	if (!world->load())
	{
		delete world;
		std::cerr << "Could not create world." << std::endl;
		return -1;
	}
	if (isclient)
		client->setReady();*/
	// Create initial world
	peak::World *world = game->createInitialWorld();
	if (!world)
	{
		std::cerr << "Could not create world." << std::endl;
		return -1;
	}
	engine.addWorld(world);
	world->start();
	/*if (isserver)
	{
		peak::Entity *entity = game->getEntityFactory("Player")->createEntity(world,
			(1 << peak::EEF_Server) | (1 << peak::EEF_Local));
		world->addEntity(entity);
	}*/
	// Wait for engine to stop
	unsigned int frames = 0;
	uint64_t lasttime = peak::OS::getSystemTime();
	peak::FrameLimiter limiter(20000);
	while (true)
	{
		engine.update();
		if (!engine.isRunning())
			break;
		if (!graphics.render())
			break;
		glfwSwapBuffers();
		if (glfwGetWindowParam(GLFW_OPENED) != GL_TRUE)
			break;
		// Update frame counter
		frames++;
		if (frames == 10)
		{
			uint64_t time = peak::OS::getSystemTime();
			unsigned int dt = time - lasttime;
			float fps = 1000000.0f / ((float)(time - lasttime) / 10);
			lasttime = time;
			frames = 0;
			char title[64];
			snprintf(title, 64, "PeakEngine - %d fps (%d ms)", (int)fps, dt / 1000);
			glfwSetWindowTitle(title);
		}
		// Only render at 50 fps
		limiter.wait();
	}
	// Destroy the engine
	engine.stop(true);
	if (!game->shutdown())
	{
		std::cerr << "Could not destroy the game." << std::endl;
	}
	delete game;
	// Close graphics
	graphics.shutdown();
	glfwEnable(GLFW_MOUSE_CURSOR);
	glfwTerminate();
	return 0;
}
int main(int argc, char **argv)
{
    Aria::init();
    ArArgumentParser parser(&argc, argv);
    parser.loadDefaultArguments();
    ArRobot robot;
    ArRobotConnector robotConnector(&parser, &robot);
    if(!robotConnector.connectRobot())
    {
      ArLog::log(ArLog::Terse, "teleopActionsExample: Could not connect to the robot.");
      if(parser.checkHelpAndWarnUnparsed())
      {
          Aria::logOptions();
          Aria::exit(1);
      }
    }
    if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
    {
      Aria::logOptions();
      Aria::exit(1);
    }
    ArLog::log(ArLog::Normal, "teleopActionsExample: Connected.");

  
  // limiter for close obstacles
  ArActionLimiterForwards limiter("speed limiter near", 300, 600, 250);
  // limiter for far away obstacles
  ArActionLimiterForwards limiterFar("speed limiter far", 300, 1100, 400);
  // limiter that checks IR sensors (like Peoplebot has)
  ArActionLimiterTableSensor tableLimiter;
  // limiter so we don't bump things backwards
  ArActionLimiterBackwards backwardsLimiter;
  // the joydrive action
  ArActionJoydrive joydriveAct;
  // the keydrive action
  ArActionKeydrive keydriveAct;
  
  // sonar device, used by the limiter actions.
  ArSonarDevice sonar;



  printf("This program will allow you to use a joystick or keyboard to control the robot.\nYou can use the arrow keys to drive, and the spacebar to stop.\nFor joystick control press the trigger button and then drive.\nPress escape to exit.\n");

  // if we don't have a joystick, let 'em know
  if (!joydriveAct.joystickInited())
    printf("Do not have a joystick, only the arrow keys on the keyboard will work.\n");
  
  // add the sonar to the robot
  robot.addRangeDevice(&sonar);


  // set the robots maximum velocity (sonar don't work at all well if you're
  // going faster)
  robot.setAbsoluteMaxTransVel(400);

  // enable the motor
  robot.enableMotors();

  // Add the actions, with the limiters as highest priority, then the teleop.
  // actions.  This will keep the teleop. actions from being able to drive too 
  // fast and hit something
  robot.addAction(&tableLimiter, 100);
  robot.addAction(&limiter, 95);
  robot.addAction(&limiterFar, 90);
  robot.addAction(&backwardsLimiter, 85);
  robot.addAction(&joydriveAct, 50);
  robot.addAction(&keydriveAct, 45);

  // Configure the joydrive action so it will let the lower priority actions
  // (i.e. keydriveAct) request motion if the joystick button is
  // not pressed.
  joydriveAct.setStopIfNoButtonPressed(false);

  
  // run the robot, true means that the run will exit if connection lost
  robot.run(true);
  
  Aria::exit(0);
}
int main(int argc, char **argv)
{
  Aria::init();

  // parse our args and make sure they were all accounted for
  ArSimpleConnector connector(&argc, argv);

  ArRobot robot;

  // the laser. ArActionTriangleDriveTo will use this laser object since it is
  // named "laser" when added to the ArRobot.
  ArSick sick;

  if (!connector.parseArgs() || argc > 1)
  {
    connector.logOptions();
    exit(1);
  }
  
  // a key handler so we can do our key handling
  ArKeyHandler keyHandler;
  // let the global aria stuff know about it
  Aria::setKeyHandler(&keyHandler);
  // toss it on the robot
  robot.attachKeyHandler(&keyHandler);

  // add the laser to the robot
  robot.addRangeDevice(&sick);

  ArSonarDevice sonar;
  robot.addRangeDevice(&sonar);
  
  ArActionTriangleDriveTo triangleDriveTo;
  ArFunctorC<ArActionTriangleDriveTo> lineGoCB(&triangleDriveTo, 
				      &ArActionTriangleDriveTo::activate);
  keyHandler.addKeyHandler('g', &lineGoCB);
  keyHandler.addKeyHandler('G', &lineGoCB);
  ArFunctorC<ArActionTriangleDriveTo> lineStopCB(&triangleDriveTo, 
					&ArActionTriangleDriveTo::deactivate);
  keyHandler.addKeyHandler('s', &lineStopCB);
  keyHandler.addKeyHandler('S', &lineStopCB);

  ArActionLimiterForwards limiter("limiter", 150, 0, 0, 1.3);
  robot.addAction(&limiter, 70);
  ArActionLimiterBackwards limiterBackwards;
  robot.addAction(&limiterBackwards, 69);

  robot.addAction(&triangleDriveTo, 60);

  ArActionKeydrive keydrive;
  robot.addAction(&keydrive, 55);


  ArActionStop stopAction;
  robot.addAction(&stopAction, 50);
  
  // try to connect, if we fail exit
  if (!connector.connectRobot(&robot))
  {
    printf("Could not connect to robot... exiting\n");
    Aria::shutdown();
    return 1;
  }

  robot.comInt(ArCommands::SONAR, 1);
  robot.comInt(ArCommands::ENABLE, 1);
  
  // start the robot running, true so that if we lose connection the run stops
  robot.runAsync(true);

  // now set up the laser
  connector.setupLaser(&sick);

  sick.runAsync();

  if (!sick.blockingConnect())
  {
    printf("Could not connect to SICK laser... exiting\n");
    Aria::shutdown();
    return 1;
  }

  printf("If you press the 'g' key it'll go find a triangle, if you press 's' it'll stop.\n");

  robot.waitForRunExit();
  return 0;
}
Beispiel #30
0
int main(void)
{
  ArSerialConnection con;
  ArRobot robot;
  int ret;
  std::string str;
  ArActionLimiterForwards limiter("speed limiter near", 300, 600, 250);
  ArActionLimiterForwards limiterFar("speed limiter far", 300, 1100, 400);
  ArActionLimiterBackwards backwardsLimiter;
  ArActionConstantVelocity stop("stop", 0);
  ArActionConstantVelocity backup("backup", -200);
  ArSonarDevice sonar;
  ArACTS_1_2 acts;
  ArSonyPTZ sony(&robot);
  ArGripper gripper(&robot, ArGripper::GENIO);
  
  Acquire acq(&acts, &gripper);
  DriveTo driveTo(&acts, &gripper, &sony);
  PickUp pickUp(&acts, &gripper, &sony);

  TakeBlockToWall takeBlock(&robot, &gripper, &sony, &acq, &driveTo, &pickUp,
			    &backup);

  Aria::init();

   if (!acts.openPort(&robot))
   {
     printf("Could not connect to acts\n");
     exit(1);
   }
  
  robot.addRangeDevice(&sonar);
  //con.setBaud(38400);
  if ((ret = con.open()) != 0)
  {
    str = con.getOpenMessage(ret);
    printf("Open failed: %s\n", str.c_str());
    Aria::shutdown();
    return 1;
  }

  robot.setDeviceConnection(&con);
  if (!robot.blockingConnect())
  {
    printf("Could not connect to robot... exiting\n");
    Aria::shutdown();
    return 1;
  }

  sony.init();
  ArUtil::sleep(1000);
  //robot.setAbsoluteMaxTransVel(400);

  robot.setStateReflectionRefreshTime(250);
  robot.comInt(ArCommands::ENABLE, 1);
  robot.comInt(ArCommands::SOUNDTOG, 0);

  ArUtil::sleep(200);
  robot.addAction(&limiter, 100);
  robot.addAction(&limiterFar, 99);
  robot.addAction(&backwardsLimiter, 98);
  robot.addAction(&acq, 77);
  robot.addAction(&driveTo, 76);
  robot.addAction(&pickUp, 75);
  robot.addAction(&backup, 50);
  robot.addAction(&stop, 30);

  robot.run(true);
  
  Aria::shutdown();
  return 0;
}