* @param scanServerName the name of the scan server to use.
* @throws SalsaDeviceException
*/
public void startScan(IConfig2D config, String scanServerName) throws SalsaDeviceException {
if(config.getDimensionX().getActuatorsList().size() == 0) {
throw new SalsaDeviceException("Cannot start scan : no actuators were defined for dimension X.");
}
int timeOut;
try {
// Reads the initial value of the time out.
timeOut = scanServerProxy.get_timeout_millis();
try {
// Time out
scanServerProxy.set_timeout_millis(5000);
// Clean
command("Clean");
// ? Scan sequencing.
// setAttribute("scanSequencing", (short) 1));
// Partial mode for recording.
setAttribute("dataRecorderPartialMode", false);
// Run name.
String runName = config.getName();
IDirectory directory = config.getDirectory();
while(directory != null) {
runName = directory.getName() + "." + runName;
directory = directory.getDirectory();
}
setAttribute("runName", runName);
// Scan number.
setAttribute("scanNumber", config.getScanNumber());
// Timebases
List<ITimebase> timebasesList = config.getTimebaseList();
List<String> timebasesNameList = new ArrayList<String>(timebasesList.size());
for(ITimebase timebase : timebasesList) {
if(timebase.isEnabled()) {
timebasesNameList.add(timebase.getName());
}
}
String[] timebasesNameArray = timebasesNameList
.toArray(new String[timebasesNameList.size()]);
setAttribute("timebases", timebasesNameArray);
// Sensors
List<ISensor> sensorsList = config.getSensorsList();
List<String> sensorsNameList = new ArrayList<String>(sensorsList.size());
for(ISensor sensor : sensorsList) {
if(sensor.isEnabled()) {
sensorsNameList.add(sensor.getName());
}
}
String[] sensorsNameArray = sensorsNameList.toArray(new String[sensorsNameList
.size()]);
setAttribute("sensors", sensorsNameArray);
// Actuators X
List<IActuator> actuatorsXList;
List<String> actuatorsNamesXList;
String[] actuatorsNamesXArray;
IDimension2DX dimensionX = config.getDimensionX();
actuatorsXList = dimensionX.getActuatorsList();
actuatorsNamesXList = new ArrayList<String>(actuatorsXList.size());
for(IActuator actuator : actuatorsXList) {
if(actuator.isEnabled()) {
actuatorsNamesXList.add(actuator.getName());
}
}
actuatorsNamesXArray = actuatorsNamesXList.toArray(new String[actuatorsNamesXList
.size()]);
setAttribute("actuators", actuatorsNamesXArray);
// Actuators y
List<IActuator> actuatorsYList;
List<String> actuatorsNamesYList;
String[] actuatorsNamesYArray;
IDimension2DY dimensionY = config.getDimensionY();
actuatorsYList = dimensionY.getActuatorsList();
actuatorsNamesYList = new ArrayList<String>(actuatorsYList.size());
for(IActuator actuator : actuatorsYList) {
if(actuator.isEnabled()) {
actuatorsNamesYList.add(actuator.getName());
}
}
actuatorsNamesYArray = actuatorsNamesYList.toArray(new String[actuatorsNamesYList
.size()]);
setAttribute("actuators2", actuatorsNamesYArray);
// Dimensions X
// Tango exchanges trajectories as double arrays that contains the positions, in
// order,
// actuator after actuator, range after range, of the trajectories of all the
// actuators.
// There is one such array per dimension.
double[] allActuatorsPositionsXArray;
double initialValueX;
// Contains the positions in order, range after range, of the trajectories of an
// actuator.
List<Double> actuatorPositionsXList;
// Contains the positions in order, actuator after actuator, range after range, of
// the trajectories of all the actuators.
List<Double> allActuatorsPositionsXList;
// The list of integrations times.
List<Double> integrationsTimesXList;
double[] integrationsTimesXArray;
int integrationTimeIndexX;
// The list of speeds.
List<Double> speedXList = new ArrayList<Double>();
double[] speedXArray;
// The number of points, which is the total steps numbers + 1 per range.
int totalStepsNumberX;
// The actuators used for this dimension
List<IActuator> dimensionActuatorsXList;
// Tango API
dimensionActuatorsXList = dimensionX.getActuatorsList();
// The positions, sorted as Tango expect them.
allActuatorsPositionsXList = new ArrayList<Double>();
// The number of enabled actuators.
int enabledActuatorsXNumber = 0;
// The positions must be sorted by actuator, so we loop over the actuators.
for(IActuator actuator : dimensionActuatorsXList) {
if(actuator.isEnabled()) {
initialValueX = ActuatorConnector.getData(actuator);
actuatorPositionsXList = new ArrayList<Double>();
// For each actuators, the positions must be sorted by range.
for (ITrajectory2DX trajectory : findActuatorTrajectories(dimensionX,
actuator)) {
actuatorPositionsXList
.addAll(TrajectoryCalculator
.calculateLinearTrajectoriesPosition(trajectory,
initialValueX));
// The speeds must be sorted in the same order, so we read them here.
speedXList.add(trajectory.getSpeed());
}
allActuatorsPositionsXList.addAll(actuatorPositionsXList);
++enabledActuatorsXNumber;
}
}
// Integration Time and steps number.
integrationsTimesXList = new ArrayList<Double>(dimensionX.getRangesList().size());
int stepsNumberX;
totalStepsNumberX = 0;
for(IRange2DX range : dimensionX.getRangesList()) {
stepsNumberX = range.getStepsNumber();
for(integrationTimeIndexX = 0; integrationTimeIndexX < stepsNumberX + 1; ++integrationTimeIndexX) {
integrationsTimesXList.add(range.getIntegrationTime());
}
totalStepsNumberX += stepsNumberX + 1;
}
integrationsTimesXArray = toDoubleArray(integrationsTimesXList);
setAttribute("integrationTimes", integrationsTimesXArray);
setAttribute("pointNumber", totalStepsNumberX);
// Trajectories
// Builds the array from the list.
allActuatorsPositionsXArray = toDoubleArray(allActuatorsPositionsXList);
// Sends the array to Tango.
DeviceAttribute trajectoriesXAttribute = new DeviceAttribute("trajectories");
if(enabledActuatorsXNumber != 0) {
trajectoriesXAttribute.insert(allActuatorsPositionsXArray, totalStepsNumberX,
enabledActuatorsXNumber);
}
else {
trajectoriesXAttribute.insert(new double[] {}, 0 , 1);
}
scanServerProxy.write_attribute(trajectoriesXAttribute);
// Speed.
speedXArray = toDoubleArray(speedXList);
setAttribute("scanSpeed", speedXArray);
// Dimensions Y
// Tango exchanges trajectories as double arrays that contains the positions, in
// order,
// actuator after actuator, range after range, of the trajectories of all the
// actuators.
// There is one such array per dimension.
double[] allActuatorsPositionsYArray;
double initialValueY;
// Contains the positions in order, range after range, of the trajectories of an
// actuator.
List<Double> actuatorPositionsYList;
// Contains the positions in order, actuator after actuator, range after range, of
// the trajectories of all the actuators.
List<Double> allActuatorsPositionsYList;
// The number of points, which is the total steps numbers + 1 per range.
int totalStepsNumberY;
// The actuators used for this dimension
List<IActuator> dimensionActuatorsYList;
// Dimension
dimensionActuatorsYList = dimensionY.getActuatorsList();
// The positions, sorted as Tango expect them.
allActuatorsPositionsYList = new ArrayList<Double>();
// The number of enabled actuators.
int enabledActuatorsYNumber = 0;
// The positions must be sorted by actuator, so we loop over the actuators.
for(IActuator actuator : dimensionActuatorsYList) {
initialValueY = ActuatorConnector.getData(actuator);
actuatorPositionsYList = new ArrayList<Double>();
// For each actuators, the positions must be sorted by range.
for(ITrajectory2DY trajectory : findActuatorTrajectories(dimensionY, actuator)) {
actuatorPositionsYList.addAll(TrajectoryCalculator
.calculateLinearTrajectoriesPosition(trajectory, initialValueY));
}
allActuatorsPositionsYList.addAll(actuatorPositionsYList);
++enabledActuatorsYNumber;
}
// The number of points
totalStepsNumberY = 0;
for(IRange2DY range : dimensionY.getRangesList()) {
totalStepsNumberY += range.getStepsNumber() + 1;
}
setAttribute("pointNumber2", totalStepsNumberY);
// Builds the array from the list.
allActuatorsPositionsYArray = toDoubleArray(allActuatorsPositionsYList);
DeviceAttribute trajectoriesYAttribute = new DeviceAttribute("trajectories2");
if(enabledActuatorsYNumber > 0) {
// Sends the array to Tango.
trajectoriesYAttribute.insert(allActuatorsPositionsYArray, totalStepsNumberY, enabledActuatorsYNumber);
}
else {
trajectoriesYAttribute.insert(new double[] {}, 0 , 1);
}
scanServerProxy.write_attribute(trajectoriesYAttribute);
// Actuator delay.
double actuatorsDelay = config.getActuatorsDelay();
setAttribute("actuatorsDelay", actuatorsDelay);
// Zig zag.
boolean zigzag = config.isZigzag();
setAttribute("zigzag", zigzag);
// Enable actuator speed.
boolean enableScanSpeed = config.isEnableScanSpeed();
setAttribute("enableScanSpeed", enableScanSpeed);
// Post scan behaviour.
IPostScanBehaviour postScanBehaviour = config.getScanAddOn().getPostScanBehaviour();
Behaviour behaviour = postScanBehaviour.getBehaviour();
if(behaviour == null) {
behaviour = Behaviour.NOOP;
}
int behaviourType = behaviour.getType();
setAttribute("afterRunActionType", behaviourType);
if(behaviour.getArgumentCount() >= 1) {
int behaviourSensorIndex = postScanBehaviour.getSensor();
setAttribute("afterRunActionSensor", behaviourSensorIndex);
}
else if(behaviour.getArgumentCount() >= 2) {
int behaviourActuatorIndex = postScanBehaviour.getActuator();
setAttribute("afterRunActionActuator", behaviourActuatorIndex);
}
// Error strategies.
if(config.getScanAddOn() != null
&& config.getScanAddOn().getErrorStrategy() != null) {
IErrorStrategy errorStrat = config.getScanAddOn().getErrorStrategy();
IErrorStrategyItem[] categoriesESI = new IErrorStrategyItem[] {
errorStrat.getActuatorsErrorStrategy(),
errorStrat.getSensorsErrorStrategy(),
errorStrat.getTimebasesErrorStrategy(),
errorStrat.getHooksErrorStrategy() };
String[] categoriesStr = new String[] { "actuators", "sensors", "timebases",
"hooks" };
for(int i=0; i<categoriesStr.length; i++) {
String cat = categoriesStr[i];
IErrorStrategyItem esi = categoriesESI[i];
double errorStrategyTimeOut = esi.getTimeOut();
int errorStrategyRetryCount = esi.getRetryCount();
double errorStrategyRetryTimeOut = esi.getTimeBetweenRetries();
int errorStrategyType = esi.getStrategy().ordinal();
// Time out.
scanServerProxy.write_attribute(new DeviceAttribute(cat + "TimeOut",
errorStrategyTimeOut));
// Retry count.
scanServerProxy.write_attribute(new DeviceAttribute(cat + "RetryCount",
errorStrategyRetryCount));
// Retry time out.
scanServerProxy.write_attribute(new DeviceAttribute(cat + "RetryTimeOut",
errorStrategyRetryTimeOut));
// Error strategy.
scanServerProxy.write_attribute(new DeviceAttribute(cat + "ErrorStrategy",
errorStrategyType));
}
// Context validation error strategy.
scanServerProxy.write_attribute(new DeviceAttribute(
"contextValidationErrorStrategy", errorStrat
.getContextValidationStrategy().ordinal()));
scanServerProxy.write_attribute(new DeviceAttribute("contextValidation",
errorStrat.getContextValidationDevice()));
}
/* Hooks */
SetHooks(config.getScanAddOn(), scanServerProxy);
// Hardware continuous scan : no.
setAttribute("hwContinuous", false);
// On the fly mode (software continuous mode).
boolean onTheFly = config.isOnTheFly();
setAttribute("onTheFly", onTheFly);
// Fin configuration du scan.
// D�marrage du scan.
command("Start");
}
finally {
// Sets the time out back to the initial value.
scanServerProxy.set_timeout_millis(timeOut);
}
}
catch(DevFailed e) {
e.printStackTrace();
String message = e.getMessage();
if(e.errors != null && e.errors.length > 0) {
message += " : " + e.errors[0].desc;
}
throw new SalsaDeviceException(message, e);
}
}