Ejemplo n.º 1
0
void BasinPlotter::calculateData() {
	
	// get program core
	Core *core = Core::getInstance();
	
	// get network
	ModularNeuralNetwork *network = getCurrentNetwork();
	if(network == 0) {
		Core::log("BasinPlotter: Could not find a neural network to work with! Aborting.", true);
		return;
	}
	
	QList<NeuralNetworkElement*> networkElements;
	network->getNetworkElements(networkElements);
	QList<DoubleValue*> networkValues =
						DynamicsPlotterUtil::getNetworkValues(networkElements);

	// Get parameters for varied elements
	QString variedX = mVariedX->get();
	QString variedY = mVariedY->get();
	if(variedX.isEmpty() || variedY.isEmpty()) {
		reportProblem("BasinPlotter: No elements to vary.");
		return;
	}
	

	DoubleValue *variedValX = DynamicsPlotterUtil::getElementValue(
		variedX, networkElements, &mNeuronsWithActivationsToTransfer);
	DoubleValue *variedValY = DynamicsPlotterUtil::getElementValue(
		variedY, networkElements, &mNeuronsWithActivationsToTransfer);
	
	if(variedValX == 0 || variedValY == 0) {
		reportProblem("BasinPlotter: NULL pointer for varied element. Aborting.");
		return;
	}
	
	QList<double> variedRangeX = 
				DynamicsPlotterUtil::getDoublesFromString(mVariedRangeX->get());
	QList<double> variedRangeY = 
				DynamicsPlotterUtil::getDoublesFromString(mVariedRangeY->get());
				
	if(variedRangeX.size() != 2 || variedRangeY.size() != 2) {
		reportProblem("BasinPlotter: Not a valid range given.");
		return;
	}
		

	int resolutionX = mResolutionX->get();
	int resolutionY = mResolutionY->get();
	
	//avoid division by zero!
	if(resolutionX < 2 || resolutionY < 2) {
		reportProblem("BasinPlotter: Invalid resolution given.");
		return;
	}


	// projected elements
	int nrProjections = 0;
	QString projectionsX = mProjectionsX->get();
	QString projectionsY = mProjectionsY->get();
	QList< QList<DoubleValue*> > projectionValuesX;
	QList< QList<DoubleValue*> > projectionValuesY;
	QList<double> projectionRangesX;
	QList<double> projectionRangesY;

	if(projectionsX != "0" && projectionsY != "0") {

		QList<QStringList> projectionListX = 
				DynamicsPlotterUtil::parseElementString(projectionsX);
		QList<QStringList> projectionListY =
				DynamicsPlotterUtil::parseElementString(projectionsY);

		projectionValuesX =
				DynamicsPlotterUtil::getElementValues(projectionListX, networkElements);
		projectionValuesY =
				DynamicsPlotterUtil::getElementValues(projectionListY, networkElements);

		if(projectionValuesX.isEmpty() || projectionValuesY.isEmpty()) {
			reportProblem("BasinPlotter: Could not find specified elements to project onto.");
			return;
		}

		if(projectionValuesX.size() != projectionValuesY.size()) {
			reportProblem("BasinPlotter: Mismatching number of projected elements for the two axes.");
			return;
		}

		projectionRangesX =
				DynamicsPlotterUtil::getDoublesFromString(mProjectionRangesX->get());
		projectionRangesY =
				DynamicsPlotterUtil::getDoublesFromString(mProjectionRangesY->get());

		if(projectionRangesX.size() != 2*projectionValuesX.size() ||
		   projectionRangesY.size() != 2*projectionValuesY.size()) {
			reportProblem("BasinPlotter: Given ranges for projection don't match number of elements.");
			return;
		}

		nrProjections = projectionValuesX.size();

	}
	

	// save original values for clean-up
	QList<double> variedValuesOrig;
	variedValuesOrig.append(QList<double>() << variedValX->get()
											<< variedValY->get());

	bool resetNetworkActivation = mResetNetworkActivation->get();
	storeCurrentNetworkActivities();
	
	/* store network configuration (bias terms, synapse weights,
			observable parameters of TFs, AFs, SFs. */
	bool restoreNetConfiguration = mRestoreNetworkConfiguration->get();
	storeNetworkConfiguration();
	
	//This is important when the physical simulator is activated!
	bool resetSimulation = mResetSimulator->get();
	triggerReset();
	

	// PREPARE data matrix
	double xStart = variedRangeX.first();
	double xEnd = variedRangeX.last();
	double xStepSize = (xEnd - xStart) / (double) (resolutionX - 1);
	int roundDigits = mRoundDigits->get();
	double xVal;
	QList<double> xValues;
		
	double yStart = variedRangeY.first();
	double yEnd = variedRangeY.last();
	double yStepSize = (yEnd - yStart) / (double) (resolutionY - 1);
	double yVal;
	QList<double> yValues;
	
	{
		//Thread safety of matrix.
		QMutexLocker guard(mDynamicsPlotManager->getMatrixLocker());
		
		mData->clear();
		mData->resize(resolutionX + 1, resolutionY + 1, 3 + nrProjections);
		mData->fill(0);

		// calculate values and draw axes
		for(int x = 1; x <= resolutionX; ++x) {
			xVal = xStart + (x - 1) * xStepSize;
			mData->set(Math::round(xVal, 5), x, 0, 0);
			mData->set(Math::round(xVal, 5), x, 0, 1);
			mData->set(Math::round(xVal, 5), x, 0, 2);
			
			if(roundDigits >= 0) {
				xVal = Math::round(xVal, roundDigits);
			}
			xValues.append(xVal);
		}
		
		for(int y = 1; y <= resolutionY; ++y) {
			yVal = yStart + (y - 1) * yStepSize;
			mData->set(Math::round(yVal, 5), 0, y, 0);
			mData->set(Math::round(yVal, 5), 0, y, 1);
			mData->set(Math::round(yVal, 5), 0, y, 2);
			
			if(roundDigits >= 0) {
				yVal = Math::round(yVal, roundDigits);
			}
			yValues.append(yVal);
		}

		// same for additional projections
		for(int currProj = 0; currProj < nrProjections; ++currProj) {
			double pStartX = projectionRangesX.at(currProj * 2);
			double pEndX = projectionRangesX.at(currProj * 2 + 1);
			double pStepX = (pEndX - pStartX) / (double) (resolutionX - 1);
			for(int x = 1; x <= resolutionX; ++x) {
				mData->set(Math::round((pStartX + (x - 1) * pStepX), 5), x, 0, 3 + currProj);
			}
			double pStartY = projectionRangesY.at(currProj * 2);
			double pEndY = projectionRangesY.at(currProj * 2 + 1);
			double pStepY = (pEndY - pStartY) / (double) (resolutionY - 1);
			for(int y = 1; y <= resolutionY; ++y) {
				mData->set(Math::round((pStartY + (y - 1) * pStepY), 5), 0, y, 3 + currProj);
			}
		}
	}

	// MAIN LOOP over x parameter points
		
	int stepsRun = mStepsToRun->get();
	int stepsCheck = mStepsToCheck->get();
	double accuracy = mAccuracy->get();
	
	QList< QList<double> > attractors;
		
	for(int x = 1; x <= resolutionX && mActiveValue->get(); ++x) {
			
		mProgressPercentage->set((double)(100 * x / resolutionX));

		// INNER LOOP over y parameter points
		for(int y = 1; y <= resolutionY && mActiveValue->get(); ++y) {
			
			if(resetSimulation) {
				triggerReset();
			}
			
			if(restoreNetConfiguration) {
				restoreNetworkConfiguration();
			}
			
			if(resetNetworkActivation) {
				restoreCurrentNetworkActivites();
			}
			
			// set x parameter
			variedValX->set(xValues.at(x - 1));
			// set y parameter
			variedValY->set(yValues.at(y - 1));
			
			if(!notifyNetworkParametersChanged(network)) {
				return;
			}

			for(int runStep = 0; runStep < stepsRun && mActiveValue->get(); ++runStep) {
				// let the network run for 1 timestep
				triggerNetworkStep();
			}
			
			QList< QList<double> > networkStates;
			QList<double> networkState;
			QList< QPair<double,double> > variedPositions;

			QList< QPair< QList<double>, QList<double> > > projectionPositions;

			bool foundMatch = false;
			int attrPeriod = 0;

			for(int checkStep = 0; checkStep <= stepsCheck && !foundMatch && mActiveValue->get(); ++checkStep) {
				triggerNetworkStep();
				
				// get current network state
				networkState = DynamicsPlotterUtil::getNetworkState(networkValues);
				
				// abort on empty state
				if(networkState.isEmpty()) {
					reportProblem("BasinPlotter: Encountered empty network state.");
					return;
				}
				
				// compare states to find attractors
				for(int period = 1; period <= checkStep && !foundMatch; ++period) {
					foundMatch = DynamicsPlotterUtil::compareNetworkStates(
							networkStates.at(checkStep-period),
							networkState,
							accuracy);
					attrPeriod = period;
				}
				
				// save current state as last one
				networkStates.append(networkState);

				variedPositions.append(QPair<double,double>(variedValX->get(), variedValY->get()));

				if(nrProjections > 0) {
					QPair< QList<double>, QList<double> > currentPositions;
					currentPositions.first = DynamicsPlotterUtil::getMeanValues(projectionValuesX);
					currentPositions.second = DynamicsPlotterUtil::getMeanValues(projectionValuesY);
					projectionPositions.append(currentPositions);
				}

			}
			
			// at this point, either an attractor has been found
			if(foundMatch && mActiveValue->get()) {
				
				// check for past attractors
				bool attrMatch = false;
				int attrNo = 1;
				while(attrNo <= attractors.size() && !attrMatch) {
					for(int state = 1; state <= attrPeriod && !attrMatch; ++state) {
						attrMatch = DynamicsPlotterUtil::compareNetworkStates(
								attractors.at(attrNo-1),
								networkStates.at(networkStates.size()-state),
									// was: size()-1-state
								accuracy);
					}
					attrNo++;
				}
				
				
				//Thread safety of matrix.
				QMutexLocker guard(mDynamicsPlotManager->getMatrixLocker());
				
				// write matrix
				mData->set(attrNo, x, y, 0);
				mData->set(attrPeriod, x, y, 1);

				// calculate and plot attractor position
				int nrPositions = variedPositions.size();
				for(int periodPos = 1; periodPos <= attrPeriod; ++periodPos) {
					int currPosition = nrPositions - periodPos;

					double currValX = variedPositions.at(currPosition).first;
					double currValY = variedPositions.at(currPosition).second;
				
					int attrPosX = ceil((currValX - xStart) / xStepSize + 1);
					int attrPosY = ceil((currValY - yStart) / yStepSize + 1);
				
					mData->set(attrNo, attrPosX, attrPosY, 2);

					for(int currProj = 0; currProj < nrProjections; ++currProj) {
						double xVal = projectionPositions.at(currPosition).first.at(currProj);
						double yVal = projectionPositions.at(currPosition).second.at(currProj);

						double pStartX = projectionRangesX.at(currProj * 2);
						double pEndX = projectionRangesX.at(currProj * 2 + 1);
						double pStepX = (pEndX - pStartX) / (double) (resolutionX - 1);
						double pStartY = projectionRangesY.at(currProj * 2);
						double pEndY = projectionRangesY.at(currProj * 2 + 1);
						double pStepY = (pEndY - pStartY) / (double) (resolutionY - 1);
						
						int xPos = floor((xVal - pStartX) / pStepX + 1);
						int yPos = floor((yVal - pStartY) / pStepY + 1);

						mData->set(attrNo, xPos, yPos, 3 + currProj);
					}
				}
				
				if(!attrMatch) {
					attractors.append(networkStates.last());
				}
			}
			
			// or not, but then there's nothing to do :D
			
			// runtime maintencance
			if(core->isShuttingDown()) {
				return;
			}
			core->executePendingTasks();
		}
	}
	
	// CLEAN UP
	variedValX->set(variedValuesOrig.at(0));
	variedValY->set(variedValuesOrig.at(1));
	notifyNetworkParametersChanged(network);

	triggerReset();
	restoreNetworkConfiguration();
	restoreCurrentNetworkActivites();

}
Ejemplo n.º 2
0
void TestSignals::testSignalSinus() {
	Core::resetCore();

	// Test SinusSignal

		// Create the TimeStepSizeValue
		DoubleValue *timeStepSizeValue = new DoubleValue(0.01); Core::getInstance()->getValueManager()->addValue(SimulationConstants::VALUE_TIME_STEP_SIZE, timeStepSizeValue);
		// Create the CurrentStepValue
		IntValue *currentStepValue = new IntValue(0);
		Core::getInstance()->getValueManager()->addValue(SimulationConstants::VALUE_EXECUTION_CURRENT_STEP, currentStepValue);
		// Create the NextStepEvent
		Event* nextStepEvent = Core::getInstance()->getEventManager()->createEvent(NerdConstants::EVENT_EXECUTION_NEXT_STEP);
		QVERIFY(nextStepEvent != 0);

	// Create the signal and initialize the core
	SignalSinus* mySignalSinus = new SignalSinus("MySinus", "/Signals");
	Core::getInstance()->init();

	// CurrentValue und IdleSteps Parameter should be there
	DoubleValue* currentValue = dynamic_cast<DoubleValue*>(mySignalSinus->getParameter("CurrentValue"));
	QVERIFY(currentValue != 0);
	IntValue* idleSteps = dynamic_cast<IntValue*>(mySignalSinus->getParameter("IdleSteps"));
	QVERIFY(idleSteps != 0);
	QVERIFY(currentValue->get() == 0.0);
	QVERIFY(idleSteps->get() == 0);

	// Current value should be 0.0
	QVERIFY(mySignalSinus->getCurrentValue() == 0.0);

	// Test getName()
	QVERIFY(mySignalSinus->getName() == "MySinus");

	// Period, Amplitude, Offset and AngularPhaseShift Paramaters should be there
	DoubleValue* period = dynamic_cast<DoubleValue*>(mySignalSinus->getParameter("Period"));
	QVERIFY(period != 0);
	QVERIFY(period->get() == 1.0);
	DoubleValue* amplitude = dynamic_cast<DoubleValue*>(mySignalSinus->getParameter("Amplitude"));
	QVERIFY(amplitude != 0);
	QVERIFY(amplitude->get() == 1.0);
	DoubleValue* offset = dynamic_cast<DoubleValue*>(mySignalSinus->getParameter("Offset"));
	QVERIFY(offset != 0);
	QVERIFY(offset->get() == 0.0);
	DoubleValue* phase = dynamic_cast<DoubleValue*>(mySignalSinus->getParameter("Phase"));
	QVERIFY(phase != 0);
	QVERIFY(phase->get() == 0.0);

	// Test computation
	double desiredValue;

	currentStepValue->set(1);
	nextStepEvent->trigger();
	desiredValue = Math::sin(1.0 / 100.0 * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));

	currentStepValue->set(30);
	nextStepEvent->trigger();
	desiredValue = Math::sin(30.0 / 100.0 * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));

	timeStepSizeValue->set(0.02);
	nextStepEvent->trigger();
	desiredValue = Math::sin(2.0 * 30.0 / 100.0 * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));

	idleSteps->set(10);
	nextStepEvent->trigger();
	desiredValue = Math::sin(2.0 * 20.0 / 100.0 * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));

	period->set(1.5);
	nextStepEvent->trigger();
	desiredValue = Math::sin((30 - 10) / (1.5 / 0.02) * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));

	amplitude->set(3.3);
	nextStepEvent->trigger();
	desiredValue = 3.3 * Math::sin((30 - 10) / (1.5 / 0.02) * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));

	offset->set(0.7);
	nextStepEvent->trigger();
	desiredValue = 0.7 + 3.3 * Math::sin((30 - 10) / (1.5 / 0.02) * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));

	phase->set(0.12);
	nextStepEvent->trigger();
	desiredValue = 0.7 + 3.3 * Math::sin(0.12 + (30 - 10) / (1.5 / 0.02) * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));

	// Test addDestinationValue mechanism
	DoubleValue *destValue1 = new DoubleValue(0.0);
	DoubleValue *destValue2 = new DoubleValue(0.0);
	DoubleValue *destValue3 = new DoubleValue(0.0);
	mySignalSinus->addDestinationValue(destValue1);
	mySignalSinus->addDestinationValue(destValue2);
	mySignalSinus->addDestinationValue(destValue3);
	period->set(1.0);
	amplitude->set(1.0);
	offset->set(0.0);
	phase->set(0.0);
	idleSteps->set(0);
	timeStepSizeValue->set(0.01);
	currentStepValue->set(1);
	nextStepEvent->trigger();
	desiredValue = Math::sin(1.0 / 100.0 * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));
	QCOMPARE(destValue1->get(), mySignalSinus->getCurrentValue());
	QCOMPARE(destValue2->get(), mySignalSinus->getCurrentValue());
	QCOMPARE(destValue3->get(), mySignalSinus->getCurrentValue());

	// Test removeDestinationValue mechanism
	mySignalSinus->removeDestinationValue(destValue3);
	currentStepValue->set(2);
	nextStepEvent->trigger();
	desiredValue = Math::sin(2.0 / 100.0 * 2 * Math::PI);
	QVERIFY(Math::compareDoubles(mySignalSinus->getCurrentValue(), desiredValue, 10));
	QCOMPARE(destValue1->get(), mySignalSinus->getCurrentValue());
	QCOMPARE(destValue2->get(), mySignalSinus->getCurrentValue());
	QVERIFY(destValue3->get() != mySignalSinus->getCurrentValue());

	delete destValue1;
	delete destValue2;
	delete destValue3;

	Core::resetCore();
}
Ejemplo n.º 3
0
void LyapunovExponent::calculateData() {
	
	// get program core
	Core *core = Core::getInstance();
	
	// get network
	ModularNeuralNetwork *network = getCurrentNetwork();
	QList<NeuralNetworkElement*> networkElements;
	network->getNetworkElements(networkElements);
	QList<DoubleValue*> networkValues =
		DynamicsPlotterUtil::getNetworkValues(networkElements);

	// Get parameters for varied element
	QString variedElement = mVariedElement->get();
	if(variedElement.isEmpty()) {
		reportProblem("LyapunovExponent: No element to vary.");
		return;
	}

	DoubleValue *variedValue = 
			DynamicsPlotterUtil::getElementValue(variedElement, networkElements);
	
	if(variedValue == 0) {
		reportProblem("LyapunovExponent: Invalid value or specifier.");
		return;
	}
	
	QList<double> variedRange = 
				DynamicsPlotterUtil::getDoublesFromString(mVariedRange->get());
				
	if(variedRange.size() != 2) {
		reportProblem("LyapunovExponent: Invalid parameter range.");
		return;
	}

		
	int resolutionX = mResolutionX->get();
	int resolutionY = mResolutionY->get();
	
	//avoid division by zero!
	if(resolutionX < 2 || resolutionY < 2) {
		reportProblem("LyapunovExponent: Invalid resolution given.");
		return;
	}

	
	// Let costraint resolver run properly (order matters!)
	storeNetworkConfiguration();
	storeCurrentNetworkActivities();
	triggerReset();
	restoreCurrentNetworkActivites();
	restoreNetworkConfiguration();
	notifyNetworkParametersChanged(network);

	// save original value
	double originalValue = variedValue->get();

	
	double valStep = (variedRange.at(1) - variedRange.at(0)) / (double) (resolutionX - 1);
	QList<double> variedValues;
	
	// prepare data matrix
	{
		//Thread safety of matrix.
		QMutexLocker guard(mDynamicsPlotManager->getMatrixLocker());

		mData->clear();
		mData->resize(resolutionX + 1, resolutionY + 1, 1);
		mData->fill(0);

		

		for(int x = 1; x <= resolutionX; ++x) {
			double val = variedRange.at(0) + (x-1) * valStep;
			variedValues.append(val);
			
			mData->set(val, x, 0, 0);
		}
	}
	
	int stepsPrePlot = mStepsPrePlot->get();
	int stepsToPlot = mStepsToPlot->get();

	bool drawNL = mDrawNL->get();

	QList<double> ynum;
	double eps = pow(10,-9);
	for(int x = 0; x < variedValues.size(); ++x) {

		// set initial conditions of this run/trajectory
		variedValue->set(variedValues.at(x));
		notifyNetworkParametersChanged(network);
		
		// calculate activation after X PrePlot-Steps
		for(int s = 0; s < stepsPrePlot && mActiveValue->get(); ++s) {
			triggerNetworkStep();
		}
		
		// list for states			
		QList< QList<double> > networkStates;

		for(int s = 0; s < stepsToPlot && mActiveValue->get(); ++s) {

			triggerNetworkStep();
			
			// get current state of the network
			QList<double> networkState = 
					DynamicsPlotterUtil::getNetworkState(networkValues);
			
			// save to list
			networkStates.append(networkState);
		}

		double ljanum = 0;
		int c = 0;
		for(int i = 0; i < networkStates.size() - 1; ++i) {
			double dy = 10000000, df = 100000000;
			bool found = false;

			for(int j = 0; j < networkStates.size() - 1; ++j) {

				double d = DynamicsPlotterUtil::getDistance(
								networkStates.at(i), networkStates.at(j));

				if(d < dy && d > eps) {
					dy = d;
					df = DynamicsPlotterUtil::getDistance(
								networkStates.at(i + 1), networkStates.at(j + 1));
					found = true;
				}
				
			}
			
			if(found && dy != 0 && df != 0) {
				ljanum += log(df / dy);
				c++;
			}

		}

		// save current hightest exponent
		ynum.append(ljanum / c);

		// find smallest and biggest exponent
		double ymin = ynum.first(); double ymax = ynum.first();
		for(int i = 1; i < ynum.size(); ++i) {
			double y = ynum.at(i);
			if(y < ymin) {
				ymin = y;
			}
			if(y > ymax) {
				ymax = y;
			}
		}
		double ystep = (ymax - ymin) / (double)(resolutionY - 1);
		if(ystep == 0) {
			reportProblem("LyapunovExponent: No suitable data found.");
			ymin = 1;
			ymax = 1;
		}

		{
			//Thread safety of matrix.
			QMutexLocker guard(mDynamicsPlotManager->getMatrixLocker());
			
			// clear data matrix
			mData->fill(0);

			// rescale
			for(int y = 1; y <= resolutionY; ++y) {
				double v = ymin + (y-1) * ystep;
				mData->set(Math::round(v, 5), 0, y, 0);
			}
			
			// fill rescaled matrix again
			for(int x = 1; x <= ynum.size(); ++x) {
				double v = min(max(ymin, ynum.at(x - 1)), ymax);
				int y = ceil(((v - ymin) / ystep) + 1);
				mData->set(1, x, y, 0);
			}

			// find null position (if any)
			int ny = ceil(((-ymin)/ystep)+1);
			// and draw red line indicating y=0
			if(drawNL && ny < resolutionY && ny > 0) {
				for(int x = 0; x < resolutionX; ++x) {
					if(mData->get(x, ny, 0) == 0) {
						mData->set(2, x, ny, 0);
					}
				}
			}
		}

		// runtime maintencance
		if(core->isShuttingDown()) {
			return;
		}
		core->executePendingTasks();
	
	}
	
	// re-set original parameter value
	variedValue->set(originalValue);
	// CLEAN UP
	notifyNetworkParametersChanged(network);
	triggerReset();
	restoreNetworkConfiguration();
	restoreCurrentNetworkActivites();

}
void TestValueTransferController::testEquilibrium() {
	Core::resetCore();
	
	ValueTransferController *vtf = new ValueTransferController("TFController");
	
	StringValue *nameOfSource = dynamic_cast<StringValue*>(vtf->getParameter("SourceValueName"));
	StringValue *nameOfTarget = dynamic_cast<StringValue*>(vtf->getParameter("TargetValueName"));
	InterfaceValue *controller = dynamic_cast<InterfaceValue*>(vtf->getParameter("Control"));
	InterfaceValue *sensor = dynamic_cast<InterfaceValue*>(vtf->getParameter("Sensor"));
	IntValue *mode = dynamic_cast<IntValue*>(vtf->getParameter("TransferMode"));
	DoubleValue *rate = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferRate"));
	DoubleValue *cost = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferCost"));
	
	QVERIFY(nameOfSource != 0);
	QVERIFY(nameOfTarget != 0);
	
	
	NormalizedDoubleValue *source = new NormalizedDoubleValue(0.0, 0.0, 1.0, -1.0, 1.0);
	NormalizedDoubleValue *target = new NormalizedDoubleValue(0.0, 0.0, 1.0, -1.0, 1.0);
	
	
	ValueManager *vm = Core::getInstance()->getValueManager();
	vm->addValue("/MySource", source);
	vm->addValue("/TheTarget", target);
	
	
	nameOfSource->set("/MySource"); 
	nameOfTarget->set("/TheTarget");
	
	
	vtf->setup();
	
	QVERIFY(vtf->getSource() == source);
	QVERIFY(vtf->getTarget() == target);
	
	
	//do the actual transfers
	
	//******************************************
	//Equilibrium Model (target only)
	
	source->set(0.0);
	target->set(0.0);
	controller->set(0.5);
	mode->set(2); //equilibrium target only
	rate->set(0.2);
	cost->set(0.4);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);
	QCOMPARE(source->get(), 0.0);
	QCOMPARE(target->get(), 0.0);
	
	
	source->set(1);
	target->set(0.0);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.2);
	QCOMPARE(source->get(), 1.0);
	QCOMPARE(target->get(), 0.2);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.16);
	QCOMPARE(source->get(), 1.0);
	QCOMPARE(target->get(), 0.36);
	
	
	source->set(0.5);
	target->set(0.7);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.04);
	QCOMPARE(source->get(), 0.5);
	QCOMPARE(target->get(), 0.66);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.032);
	QCOMPARE(source->get(), 0.5);
	QCOMPARE(target->get(), 0.628);
	
	
	//******************************************
	//Equilibrium Model (change both)
	
	source->set(0.0);
	target->set(0.0);
	controller->set(0.5);
	mode->set(3); //equlibrium mutual
	cost->set(0.4);
	rate->set(0.2);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);
	QCOMPARE(source->get(), 0.0);
	QCOMPARE(target->get(), 0.0);
	
	
	source->set(1);
	target->set(0.0);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.6);
	QCOMPARE(source->get(), 0.6);
	QCOMPARE(target->get(), 0.2);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.24);
	QCOMPARE(source->get(), 0.44);
	QCOMPARE(target->get(), 0.28);
	
	
	source->set(0.1);
	target->set(0.7);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.36);
	QCOMPARE(source->get(), 0.34);
	QCOMPARE(target->get(), 0.58);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.144);
	QCOMPARE(source->get(), 0.436);
	QCOMPARE(target->get(), 0.532);
	
	//rate/cost sum > 1 (error is fully corrected in a single step)
	cost->set(2.4);
	rate->set(0.8);
	source->set(0.1);
	target->set(0.7);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.6);
	QCOMPARE(source->get(), 0.55);
	QCOMPARE(target->get(), 0.55);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);
	QCOMPARE(source->get(), 0.55);
	QCOMPARE(target->get(), 0.55);
}
/**
 * Submits jobs for all individuals, where no fitness-results were returned. The evaluation-jobs are resubmitted maximum "NumberOfResubmits" times (including the initial submit).
 */
void ClusterNetworkInSimEvaluationMethod::performNeccessaryReSubmits() {
	TRACE("EvolutionManager::performNeccessaryReSubmits");

	//TODO Merge this method with the other submit method!!!!!

	int currentTry = 0;
	QList<int> openEvaluations;
	while(mOpenEvaluations.size() != 0 && currentTry < mNumberOfRetries->get() 
			&& !Core::getInstance()->isShuttingDown()) 
	{
		openEvaluations.clear();
		reSubmitJobs();
	
		QList<QList<Individual*> > groups = mEvaluationGroupsBuilder->getEvaluationGroups();
		mStatusMessageValue->set("Start loading fitness results.");
		for(int i = 0; i < mOpenEvaluations.size() && !Core::getInstance()->isShuttingDown(); i++) {
			QMap<QString, double> fitnessResults;
			QString filePath = mEvalCurrentDirectory;
			if(!filePath.endsWith("/")) {
				filePath.append("/");
			}
			filePath.append(QString::number(mOpenEvaluations.at(i)))
				.append("/")
				.append(mFitnessFileName);
			QFile file(filePath);
		
			bool fileOpend = file.open(QIODevice::ReadOnly | QIODevice::Text);
			if(!fileOpend) {
				file.close();
				Core::log(QString("ClusterNetworkInSimEvaluationMethod: Could not load file ")
						.append(filePath), true);
				if(currentTry == mNumberOfRetries->get() - 1) {
					mStatusMessageValue->set(QString("Could not load fitness file for "
						"evaluation group %1! Skipping individual!").arg(mOpenEvaluations.at(i)));
				} else {
					openEvaluations.push_back(mOpenEvaluations.at(i));
				}
				//relieve the system to recover ressources (like file handles)
				QCoreApplication::instance()->thread()->wait(100);
				continue;
			}
		
			QTextStream input(&file);
			while (!input.atEnd()) {
				QString line = input.readLine();
				line = line.trimmed();
		
				if(line.startsWith("#")) {
					continue;
				}
				int sepIndex = line.indexOf("=");
				if(sepIndex == -1) {
					continue;
				}
				QString name = line.left(sepIndex);
				QString valueContent = line.right(line.length() - sepIndex - 1);
				fitnessResults[name] = valueContent.toDouble();
			}
			file.close();
	
			QMap<QString, double>::iterator index;
			for (index = fitnessResults.begin(); index != fitnessResults.end(); ++index) {
				mNextIndividual->trigger();
				bool found = false;
				for(int k = 0; k < mOwnerWorld->getPopulations().size(); k++) {
					Population *population  = 
							mOwnerWorld->getPopulations().at(k); 
					FitnessFunction *fitness =
							population->getFitnessFunction(index.key());
					if(fitness == 0) {
						continue;
					}
					Individual *individual = groups.at(i).at(k);
					if(!population->getIndividuals().contains(individual)){
						Core::log("ClusterNetworkInSimEvaluationMethod: Error while "
							"reading evaluation results. Individual is not part of the "
							"population!");
						continue;
					}
					individual->setFitness(fitness, index.value());
					
					FitnessFunction *fitnessFunction = population->getFitnessFunction(fitness->getName());

					if(fitnessFunction != 0) {
						Core::log("ClusterNetworkInSimEvaluationMethod: FitnessFunction was not found.");
						continue;
					}

					DoubleValue *fitnessValue = dynamic_cast<DoubleValue*>(
									fitnessFunction->getParameter("Fitness/Fitness"));

					if(fitnessValue == 0) {
						Core::log("ClusterNetworkInSimEvaluationMethod: Fitness Value of FF not found!");
						continue;
					}

					fitnessValue->set(index.value());
					found = true;
				}
				if(!found) {
					Core::log("ClusterNetworkInSimEvaluationMethod: Found a fitness "
						"results that doesn't belong to any population of the current "
						"evolution.");
				}
				mIndividualCompleted->trigger();
			}
		}		

		mOpenEvaluations = openEvaluations;
		currentTry++;
	}
}
void TestValueTransferController::testBothProportional() {
	Core::resetCore();
	
	ValueTransferController *vtf = new ValueTransferController("TFController");

	StringValue *nameOfSource = dynamic_cast<StringValue*>(vtf->getParameter("SourceValueName"));
	StringValue *nameOfTarget = dynamic_cast<StringValue*>(vtf->getParameter("TargetValueName"));
	InterfaceValue *controller = dynamic_cast<InterfaceValue*>(vtf->getParameter("Control"));
	InterfaceValue *sensor = dynamic_cast<InterfaceValue*>(vtf->getParameter("Sensor"));
	IntValue *mode = dynamic_cast<IntValue*>(vtf->getParameter("TransferMode"));
	DoubleValue *rate = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferRate"));
	DoubleValue *cost = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferCost"));
	
	QVERIFY(nameOfSource != 0);
	QVERIFY(nameOfTarget != 0);
	

	NormalizedDoubleValue *source = new NormalizedDoubleValue(0.0, 0.0, 1.0, -1.0, 1.0);
	NormalizedDoubleValue *target = new NormalizedDoubleValue(0.0, 0.0, 1.0, -1.0, 1.0);
	

	ValueManager *vm = Core::getInstance()->getValueManager();
	vm->addValue("/MySource", source);
	vm->addValue("/TheTarget", target);
	

	nameOfSource->set("/MySource"); 
	nameOfTarget->set("/TheTarget");
	

	vtf->setup();
	
	QVERIFY(vtf->getSource() == source);
	QVERIFY(vtf->getTarget() == target);
	

	//do the actual transfers
	
	//******************************************
	//BothProportional Model
	
	source->set(0.0);
	target->set(0.0);
	controller->set(0.5);
	mode->set(1);
	rate->set(-1.0);
	cost->set(-0.5);
	

	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);
	QCOMPARE(source->get(), 0.0);
	QCOMPARE(target->get(), 0.0);
	
	source->set(0.8);
	target->set(0.0);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 0.8); 
	QCOMPARE(target->get(), 0.0);
	

	source->set(0.0);
	target->set(0.8);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 0.0); 
	QCOMPARE(target->get(), 0.8);
	
	source->set(0.8);
	target->set(0.8);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.5);  
	QCOMPARE(source->get(), 0.55); 
	QCOMPARE(target->get(), 0.3);
	
	source->set(0.8);
	target->set(0.4);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.4);  
	QCOMPARE(source->get(), 0.6); 
	QCOMPARE(target->get(), 0.0);
	
	source->set(0.125);
	target->set(0.9);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.25);  
	QCOMPARE(source->get(), 0.0); 
	QCOMPARE(target->get(), 0.65);
	
	source->set(0.125);
	target->set(0.9);
	controller->set(1.0);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.25);  
	QCOMPARE(source->get(), 0.0); 
	QCOMPARE(target->get(), 0.65);
	
	source->set(0.125);
	target->set(0.9);
	controller->set(-1.0);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 0.125); 
	QCOMPARE(target->get(), 0.9);
	
	
	//positive changes
	//***************************************************
	cost->set(0.5);
	rate->set(1.0);
	source->set(0.1);
	target->set(1.0);
	controller->set(0.5);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 0.1); 
	QCOMPARE(target->get(), 1.0);
	
	source->set(1.0);
	target->set(0.2);
	controller->set(0.5);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 1.0); 
	QCOMPARE(target->get(), 0.2);
	
	source->set(0.1);
	target->set(0.2);
	controller->set(0.5);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.5);
	QCOMPARE(source->get(), 0.35);
	QCOMPARE(target->get(), 0.7);
	
	source->set(0.1);
	target->set(0.75);
	controller->set(0.5);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.25);
	QCOMPARE(source->get(), 0.225);
	QCOMPARE(target->get(), 1.0);
	
	source->set(0.975);
	target->set(0.2);
	controller->set(0.1);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.05);
	QCOMPARE(source->get(), 1.0);
	QCOMPARE(target->get(), 0.25);
	
	
	//opposite change directions
	//***************************************************
	cost->set(-0.5);
	rate->set(1.0);
	source->set(0.0);
	target->set(0.2);
	controller->set(0.5);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 0.0); 
	QCOMPARE(target->get(), 0.2);
	
	source->set(0.9);
	target->set(1.0);
	controller->set(0.5);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 0.9); 
	QCOMPARE(target->get(), 1.0);
	
	source->set(0.9);
	target->set(0.2);
	controller->set(0.5);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.5);  
	QCOMPARE(source->get(), 0.65); 
	QCOMPARE(target->get(), 0.7);
	
	source->set(0.125);
	target->set(0.2);
	controller->set(0.5);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.25);  
	QCOMPARE(source->get(), 0.0); 
	QCOMPARE(target->get(), 0.45);
	
	source->set(0.9);
	target->set(0.9);
	controller->set(0.5);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.1);  
	QCOMPARE(source->get(), 0.85); 
	QCOMPARE(target->get(), 1.0);
	
}
//chris
void TestValueTransferController::testConstructor() {
	Core::resetCore();
	
	ValueTransferController *vtf = new ValueTransferController("TFController");
	
	QCOMPARE(vtf->getParameters().size(), 12);
	
	StringValue *nameOfSource = dynamic_cast<StringValue*>(vtf->getParameter("SourceValueName"));
	StringValue *nameOfTarget = dynamic_cast<StringValue*>(vtf->getParameter("TargetValueName"));
	StringValue *customControllerName = dynamic_cast<StringValue*>(vtf->getParameter("CustomControllerName"));
	StringValue *customSensorName = dynamic_cast<StringValue*>(vtf->getParameter("CustomSensorName"));
	InterfaceValue *controller = dynamic_cast<InterfaceValue*>(vtf->getParameter("Control"));
	InterfaceValue *sensor = dynamic_cast<InterfaceValue*>(vtf->getParameter("Sensor"));
	IntValue *mode = dynamic_cast<IntValue*>(vtf->getParameter("TransferMode"));
	DoubleValue *rate = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferRate"));
	DoubleValue *cost = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferCost"));
	
	QVERIFY(nameOfSource != 0);
	QVERIFY(nameOfTarget != 0);
	QVERIFY(customControllerName != 0);
	QVERIFY(customSensorName != 0);
	QVERIFY(controller != 0);
	QVERIFY(sensor != 0);
	QVERIFY(mode != 0);
	QVERIFY(rate != 0);
	QVERIFY(cost != 0);
	
	QCOMPARE(vtf->getOutputValues().size(), 1);
	QVERIFY(vtf->getOutputValues().contains(sensor));
	QCOMPARE(vtf->getInputValues().size(), 1);
	QVERIFY(vtf->getInputValues().contains(controller));
	
	QVERIFY(controller->getName() == "TFController/Control");
	QVERIFY(sensor->getName() == "TFController/Transfer");
	
	QCOMPARE(controller->getMin(), -1.0);
	QCOMPARE(controller->getMax(), 1.0);
	QCOMPARE(sensor->getMin(), -1.0);
	QCOMPARE(sensor->getMax(), 1.0);
	
	//change the custom names 
	customControllerName->set("NewName");
	QVERIFY(controller->getName() == "TFController/NewName");
	customSensorName->set("NewSensorName");
	QVERIFY(sensor->getName() == "TFController/NewSensorName");
	
	
	//change some values
	nameOfSource->set("MySource");
	nameOfTarget->set("MyTarget");
	mode->set(10);
	rate->set(0.12345);
	cost->set(-5.123);
	
	
	//*************************************************************************************
	//copy constructor
	
	ValueTransferController *copy = dynamic_cast<ValueTransferController*>(vtf->createCopy());
	
	QVERIFY(copy != 0);
	
	copy->setName("MyCopy");
	
	StringValue *nameOfSourceC = dynamic_cast<StringValue*>(copy->getParameter("SourceValueName"));
	StringValue *nameOfTargetC = dynamic_cast<StringValue*>(copy->getParameter("TargetValueName"));
	StringValue *customControllerNameC = dynamic_cast<StringValue*>(copy->getParameter("CustomControllerName"));
	StringValue *customSensorNameC = dynamic_cast<StringValue*>(copy->getParameter("CustomSensorName"));
	InterfaceValue *controllerC = dynamic_cast<InterfaceValue*>(copy->getParameter("Control"));
	InterfaceValue *sensorC = dynamic_cast<InterfaceValue*>(copy->getParameter("Sensor"));
	IntValue *modeC = dynamic_cast<IntValue*>(copy->getParameter("TransferMode"));
	DoubleValue *rateC = dynamic_cast<DoubleValue*>(copy->getParameter("TransferRate"));
	DoubleValue *costC = dynamic_cast<DoubleValue*>(copy->getParameter("TransferCost"));
	
	QVERIFY(nameOfSourceC != 0);
	QVERIFY(nameOfTargetC != 0);
	QVERIFY(customControllerNameC != 0);
	QVERIFY(customSensorNameC != 0);
	QVERIFY(controllerC != 0);
	QVERIFY(sensorC != 0);
	QVERIFY(modeC != 0);
	QVERIFY(rateC != 0);
	QVERIFY(costC != 0);
	
	QVERIFY(vtf->getSource() == 0);
	QVERIFY(vtf->getTarget() == 0);
	
	QCOMPARE(copy->getOutputValues().size(), 1);
	QVERIFY(copy->getOutputValues().contains(sensorC));
	QCOMPARE(copy->getInputValues().size(), 1);
	QVERIFY(copy->getInputValues().contains(controllerC));
	
	QVERIFY(sensor != sensorC);
	QVERIFY(controller != controllerC);
	
	QVERIFY(controllerC->getName() == "MyCopy/NewName");
	QVERIFY(sensorC->getName() == "MyCopy/NewSensorName");
	
	QCOMPARE(modeC->get(), 10);
	QCOMPARE(rateC->get(), 0.12345);
	QCOMPARE(costC->get(), -5.123);
	QVERIFY(nameOfSourceC->get() == "MySource");
	QVERIFY(nameOfTargetC->get() == "MyTarget");
	QVERIFY(customControllerNameC->get() == "NewName");
	QVERIFY(customSensorNameC->get() == "NewSensorName");
	
}
void TestValueTransferController::testAutomaticSimpleTransfer() {
	Core::resetCore();
	
	ValueTransferController *vtf = new ValueTransferController("TFController", true);
	
	QCOMPARE(vtf->getParameters().size(), 6);
	
	StringValue *nameOfSource = dynamic_cast<StringValue*>(vtf->getParameter("SourceValueName"));
	StringValue *nameOfTarget = dynamic_cast<StringValue*>(vtf->getParameter("TargetValueName"));
	StringValue *customControllerName = dynamic_cast<StringValue*>(vtf->getParameter("CustomControllerName"));
	StringValue *customSensorName = dynamic_cast<StringValue*>(vtf->getParameter("CustomSensorName"));
	InterfaceValue *controller = dynamic_cast<InterfaceValue*>(vtf->getParameter("Control"));
	InterfaceValue *sensor = dynamic_cast<InterfaceValue*>(vtf->getParameter("Sensor"));
	IntValue *mode = dynamic_cast<IntValue*>(vtf->getParameter("TransferMode"));
	DoubleValue *rate = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferRate"));
	DoubleValue *cost = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferCost"));
	
	QVERIFY(nameOfSource != 0); //!
	QVERIFY(nameOfTarget != 0); //!
	QVERIFY(customControllerName == 0);
	QVERIFY(customSensorName == 0);
	QVERIFY(controller == 0);
	QVERIFY(sensor == 0);
	QVERIFY(mode != 0); //!
	QVERIFY(rate != 0); //!
	QVERIFY(cost != 0); //!
	
	NormalizedDoubleValue *target = new NormalizedDoubleValue(0.0, 0.0, 1.0, -1.0, 1.0);
	
	ValueManager *vm = Core::getInstance()->getValueManager();
	vm->addValue("/TheTarget", target);
	
	QVERIFY(vtf->getSource() == 0);
	QVERIFY(vtf->getTarget() == 0);
	
	//no valid source and target given, so setup() succeeds, but the controller will not work.
	vtf->setup();
	
	QVERIFY(vtf->getSource() != 0);
	QVERIFY(vtf->getTarget() == 0);
	QVERIFY(vtf->transferActivations() == false);
	
	nameOfTarget->set("/TheTarget");
	
	vtf->setup();
	
	QVERIFY(vtf->getSource() != 0);
	QVERIFY(vtf->getTarget() == target);
	
	//do the automatic transfer
	
	target->set(0.5);
	mode->set(0);
	rate->set(-0.01);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(target->get(), 0.49);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(target->get(), 0.48);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(target->get(), 0.47);
	
	rate->set(-0.1);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(target->get(), 0.37);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(target->get(), 0.27);
	
	rate->set(0.05);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(target->get(), 0.32);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(target->get(), 0.37);
}
//Chris 
void TestValueTransferController::testSimpleTransfer() {
	Core::resetCore();

	ValueTransferController *vtf = new ValueTransferController("TFController");
	
	StringValue *nameOfSource = dynamic_cast<StringValue*>(vtf->getParameter("SourceValueName"));
	StringValue *nameOfTarget = dynamic_cast<StringValue*>(vtf->getParameter("TargetValueName"));
	InterfaceValue *controller = dynamic_cast<InterfaceValue*>(vtf->getParameter("Control"));
	InterfaceValue *sensor = dynamic_cast<InterfaceValue*>(vtf->getParameter("Sensor"));
	IntValue *mode = dynamic_cast<IntValue*>(vtf->getParameter("TransferMode"));
	DoubleValue *rate = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferRate"));
	DoubleValue *cost = dynamic_cast<DoubleValue*>(vtf->getParameter("TransferCost"));
	
	NormalizedDoubleValue *source = new NormalizedDoubleValue(0.0, 0.0, 1.0, -1.0, 1.0);
	NormalizedDoubleValue *target = new NormalizedDoubleValue(0.0, 0.0, 1.0, -1.0, 1.0);
	
	ValueManager *vm = Core::getInstance()->getValueManager();
	vm->addValue("/MySource", source);
	vm->addValue("/TheTarget", target);
	
	nameOfSource->set("NonexistingName");
	
	QVERIFY(vtf->getSource() == 0);
	QVERIFY(vtf->getTarget() == 0);
	
	//no valid source and target given, so setup() succeeds, but the controller will not work.
	vtf->setup();
	
	QVERIFY(vtf->getSource() == 0);
	QVERIFY(vtf->getTarget() == 0);
	QVERIFY(vtf->transferActivations() == false);
	
	nameOfSource->set("");
	vtf->setup();
	
	QVERIFY(vtf->getSource() != 0); //uses the internal, infinite source.
	QVERIFY(vtf->getSource() != source);
	QVERIFY(vtf->getTarget() == 0);
	
	
	nameOfSource->set("/MySource"); 
	vtf->setup();
	
	QVERIFY(vtf->getSource() == source); //uses the specified source
	QVERIFY(vtf->getTarget() == 0);
	QVERIFY(vtf->transferActivations() == false);
	
	nameOfTarget->set("/TheTarget");
	
	vtf->setup();
	
	QVERIFY(vtf->getSource() == source);
	QVERIFY(vtf->getTarget() == target);
	
	
	//do the actual transfers
	
	//******************************************
	//Simple model (positive)
	source->set(0.0);
	target->set(0.0);
	controller->set(0.5);
	mode->set(0);
	rate->set(1.0);
	cost->set(0.1);
	
	QCOMPARE(source->get(), 0.0);
	QCOMPARE(target->get(), 0.0);
	
	QVERIFY(vtf->transferActivations() == true);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);
	QCOMPARE(source->get(), 0.0);
	QCOMPARE(target->get(), 0.0);
	
	source->set(0.7);
	target->set(0.0);
	controller->set(0.0); //half strong source->target
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), 0.0, 0.00001)); //0.5 * maximalTransferRate
	QCOMPARE(source->get(), 0.7); //0.05 transfer + 0.01 cost
	QCOMPARE(target->get(), 0.0);
	
	source->set(0.7);
	target->set(0.0);
	controller->set(0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.5);  
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), 0.454545, 0.0001)); //0.5 * maximalTransferRate (Range [-1.1, 1.1])
	QCOMPARE(source->get(), 0.1); //0.05 transfer + 0.01 cost
	QCOMPARE(target->get(), 0.5);
	
	source->set(0.5);
	target->set(0.0);
	controller->set(0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.4);  
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), 0.36363636, 0.0001));
	QCOMPARE(source->get(), 0.0); 
	QCOMPARE(target->get(), 0.4);
	
	source->set(0.6);
	target->set(0.0);
	controller->set(0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.5);  
	QCOMPARE(source->get(), 0.0); 
	QCOMPARE(target->get(), 0.5);
	
	source->set(0.9);
	target->set(0.1);
	controller->set(0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.5);  
	QCOMPARE(source->get(), 0.3); 
	QCOMPARE(target->get(), 0.6);
	
	source->set(0.8);
	target->set(0.8);
	controller->set(0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.2);  
	QCOMPARE(source->get(), 0.5);
	QCOMPARE(target->get(), 1.0);
	
	source->set(0.8);
	target->set(1.0);
	controller->set(0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 0.8); //does not consume energy, because no transfer takes place.
	QCOMPARE(target->get(), 1.0);
	
	source->set(0.8);
	target->set(0.95);
	controller->set(0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.05);  
	QCOMPARE(source->get(), 0.65);
	QCOMPARE(target->get(), 1.0);
	
	source->set(0.1);
	target->set(0.5);
	controller->set(0.1); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 0.1); //does not consume energy, because no transfer takes plae
	QCOMPARE(target->get(), 0.5);
	
	source->set(0.15);
	target->set(0.5);
	controller->set(0.1); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.05);  
	QCOMPARE(source->get(), 0.0);
	QCOMPARE(target->get(), 0.55);
	
	
	//******************************************
	//Simple model (negative) target->source
	source->set(0.0);
	target->set(0.0);
	controller->set(-0.5);
	mode->set(0);
	rate->set(1.0);
	cost->set(0.1);
	
	QCOMPARE(source->get(), 0.0);
	QCOMPARE(target->get(), 0.0);
	
	QVERIFY(vtf->transferActivations() == true);
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);
	QCOMPARE(source->get(), 0.0);
	QCOMPARE(target->get(), 0.0);
	
	source->set(0.0);
	target->set(0.7);
	controller->set(0.0); //half strong source->target
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), 0.0, 0.0001)); //0.5 * maximalTransferRate
	QCOMPARE(source->get(), 0.0); //0.05 transfer + 0.01 cost
	QCOMPARE(target->get(), 0.7);
	
	source->set(0.0);
	target->set(0.7);
	controller->set(-0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.5);  
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), -0.454545, 0.0001)); //0.5 * maximalTransferRate
	QCOMPARE(source->get(), 0.5); //0.05 transfer + 0.01 cost
	QCOMPARE(target->get(), 0.1);
	
	source->set(0.0);
	target->set(0.5);
	controller->set(-0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.4);  
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), -0.36363636, 0.0001));
	QCOMPARE(source->get(), 0.4); 
	QCOMPARE(target->get(), 0.0);
	
	source->set(0.0);
	target->set(0.6);
	controller->set(-0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.5);  
	QCOMPARE(source->get(), 0.5); 
	QCOMPARE(target->get(), 0.0);
	
	source->set(0.1);
	target->set(0.9);
	controller->set(-0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.5);  
	QCOMPARE(source->get(), 0.6); 
	QCOMPARE(target->get(), 0.3);
	
	source->set(0.8);
	target->set(0.8);
	controller->set(-0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.2);  
	QCOMPARE(source->get(), 1.0);
	QCOMPARE(target->get(), 0.5);
	
	source->set(1.0);
	target->set(0.8);
	controller->set(-0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 1.0);
	QCOMPARE(target->get(), 0.8); //no transfer took place => no energy used.
	
	source->set(0.95);
	target->set(0.8);
	controller->set(-0.5); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.05);  
	QCOMPARE(source->get(), 1.0);
	QCOMPARE(target->get(), 0.65);
	
	source->set(0.5);
	target->set(0.1);
	controller->set(-0.1); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.0);  
	QCOMPARE(source->get(), 0.5); 
	QCOMPARE(target->get(), 0.1); //no transfer took place => no energy used.
	
	source->set(0.5);
	target->set(0.15);
	controller->set(-0.1); 
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.05);  
	QCOMPARE(source->get(), 0.55);
	QCOMPARE(target->get(), 0.0);
	
	//******************************************
	//Some more arbitrary configurations
	
	source->setMin(-0.1);
	source->setMax(0.5);
	source->set(0.3);
	target->setMin(0.1);
	target->setMax(0.6);
	target->set(0.2);
	controller->set(-0.2);
	mode->set(0);
	rate->set(0.4); //0.08
	cost->set(0.01);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), -0.08);
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), -0.195122, 0.0001));
	QCOMPARE(source->get(), 0.38); //+0.08
	QCOMPARE(target->get(), 0.11); //-0.09 = -0.08 - 0.01 cost
	
	
	//not enough energy left in source.
	source->setMin(-0.1);
	source->setMax(0.5);
	source->set(0.0);
	target->setMin(0.1);
	target->setMax(0.6);
	target->set(0.5);
	controller->set(0.5);
	rate->set(0.4); 
	cost->set(0.05);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.05);
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), 0.111111, 0.0001));
	QCOMPARE(source->get(), -0.1); //
	QCOMPARE(target->get(), 0.55); //
	
	
	//not enough space left at target
	source->setMin(-0.1);
	source->setMax(0.5);
	source->set(0.5);
	target->setMin(0.1);
	target->setMax(0.6);
	target->set(0.5);
	controller->set(0.5);
	rate->set(0.4); 
	cost->set(0.05);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.1);
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), 0.22222, 0.0001));
	QCOMPARE(source->get(), 0.35); //-0.15 = -(0.1 + 0.05 cost)
	QCOMPARE(target->get(), 0.6); //+0.1 (maxed out)
	
	
	//should work fine
	source->setMin(-0.1);
	source->setMax(0.5);
	source->set(0.5);
	target->setMin(0.1);
	target->setMax(0.6);
	target->set(0.2);
	controller->set(0.75);
	rate->set(0.4); 
	cost->set(0.05);
	
	updateActuatorAndSensor(vtf);
	QCOMPARE(sensor->get(), 0.3);
	QVERIFY(Math::compareDoubles(sensor->getNormalized(), 0.666667, 0.0001));
	QCOMPARE(source->get(), 0.15); //
	QCOMPARE(target->get(), 0.5); //
}
Ejemplo n.º 10
0
void TestSphereBody::testSphereBody() {
	Core::resetCore();
	SphereBody *sphere = new SphereBody("Sphere");
	QCOMPARE(sphere->getParameters().size(), 14);
	QVERIFY(sphere->getName().compare("Sphere") == 0);
	QVERIFY(sphere->getInputValues().size() == 0);
	QVERIFY(sphere->getOutputValues().size() == 0);
	QCOMPARE(sphere->getParameters().size(), 14);
	QVERIFY(sphere->getParameter("CenterOfMass") != 0);
	QVERIFY(sphere->getParameter("Position") != 0);
	QVERIFY(sphere->getParameter("Orientation") != 0);
	QVERIFY(sphere->getParameter("DynamicFriction") != 0);
	QVERIFY(sphere->getParameter("StaticFriction") != 0);
	QVERIFY(sphere->getParameter("Elasticity") != 0);
	QVERIFY(sphere->getParameter("Dynamic") != 0);
	QVERIFY(sphere->getParameter("Name") != 0);
	QVERIFY(sphere->getParameter("Mass") != 0);
	QVERIFY(sphere->getParameter("Color") != 0);
	DoubleValue *radius = dynamic_cast<DoubleValue*>(sphere->getParameter("Radius"));
	QVERIFY(radius != 0);

	QCOMPARE(radius->get(), 0.0);
	QCOMPARE(sphere->getCollisionObjects().size(), 1);
	QCOMPARE(sphere->getGeometries().size(), 1);

	SphereGeom *sphereGeom = dynamic_cast<SphereGeom*>(sphere->getGeometries().at(0));	
	QVERIFY(sphereGeom != 0);
	QCOMPARE(sphereGeom->getRadius(), 0.0);
	
	CollisionObject *collisionObject = sphere->getCollisionObjects().at(0);
	QVERIFY(collisionObject->getHostBody() == sphere);
	QVERIFY(collisionObject->getOwner() == 0);
	SphereGeom *collisionObjectGeom = dynamic_cast<SphereGeom*>(collisionObject->getGeometry());
	QVERIFY(collisionObjectGeom != 0);
	QCOMPARE(collisionObjectGeom->getRadius(), 0.0);

	radius->set(1.0);
	QCOMPARE(collisionObjectGeom->getRadius(), 0.0);
	QCOMPARE(sphereGeom->getRadius(), 0.0);

	sphere->setup();
	QVERIFY(collisionObject->getHostBody() == sphere);
	QVERIFY(collisionObject->getOwner() == sphere);
	QCOMPARE(collisionObjectGeom->getRadius(), 1.0);
	QCOMPARE(sphereGeom->getRadius(), 1.0);
	
	SphereBody *sphere2 = new SphereBody("Sphere2", 5.14);
	DoubleValue *radius2 = dynamic_cast<DoubleValue*>(sphere2->getParameter("Radius"));
	QVERIFY(radius2 != 0);
	QCOMPARE(radius2->get(), 5.14);
	SphereGeom *sphereGeom2 = dynamic_cast<SphereGeom*>(sphere2->getCollisionObjects().at(0)->getGeometry());

	QCOMPARE(sphereGeom2->getRadius(), 5.14);
	QCOMPARE(sphere2->getParameters().size(), 14);
	sphere2->getParameter("Position")->setValueFromString("(1.11, 2.2, 3.9)");
	Vector3DValue *position = dynamic_cast<Vector3DValue*>(sphere2->getParameter("Position"));
	QVERIFY(position != 0);
	QCOMPARE(position->getX(), 1.11);
	QCOMPARE(position->getY(), 2.2);
	QCOMPARE(position->getZ(), 3.9);	

	SphereBody *copy = dynamic_cast<SphereBody*>(sphere2->createCopy());	
	QVERIFY(copy != 0);
	QCOMPARE(copy->getParameters().size(), 14);
	QVERIFY(copy->getCollisionObjects().size() == 1);
	QVERIFY(copy->getGeometries().size() == 1);

	Vector3DValue *copyPosition = dynamic_cast<Vector3DValue*>(copy->getParameter("Position"));
	QVERIFY(copyPosition != 0);
	QCOMPARE(copyPosition->getX(), 1.11);
	QCOMPARE(copyPosition->getY(), 2.2);
	QCOMPARE(copyPosition->getZ(), 3.9);
	
	SphereGeom *copyGeometry = dynamic_cast<SphereGeom*>(copy->getCollisionObjects().at(0)->getGeometry());
	QVERIFY(copyGeometry != 0);
	QCOMPARE(copyGeometry->getRadius(), 5.14);

	CollisionObject *copyCollisionObject = copy->getCollisionObjects().at(0);
	QVERIFY(copyCollisionObject->getHostBody() == copy);
	QVERIFY(copyCollisionObject->getOwner() == 0);	

	copy->setup();
	QVERIFY(copyCollisionObject->getHostBody() == copy);
	QVERIFY(copyCollisionObject->getOwner() == copy);

	radius2->set(-10.0);
	sphere2->setup();
	QVERIFY(sphereGeom2->getRadius() > 0.0);

	delete copy;
	delete sphere2;
	delete sphere;
}