← Back to team overview

yade-dev team mailing list archive

[svn] r1587 - in trunk: extra extra/usct gui/py pkg/common pkg/common/Engine/DeusExMachina pkg/common/Engine/StandAloneEngine scripts scripts/test

 

Author: eudoxos
Date: 2008-12-01 20:47:18 +0100 (Mon, 01 Dec 2008)
New Revision: 1587

Added:
   trunk/pkg/common/Engine/DeusExMachina/Se3Interpolator.cpp
   trunk/pkg/common/Engine/DeusExMachina/Se3Interpolator.hpp
   trunk/scripts/test/
   trunk/scripts/test/Se3Interpolator.py
Modified:
   trunk/extra/Brefcom.cpp
   trunk/extra/usct/UniaxialStrainControlledTest.cpp
   trunk/extra/usct/UniaxialStrainControlledTest.hpp
   trunk/gui/py/PythonUI_rc.py
   trunk/pkg/common/Engine/StandAloneEngine/PeriodicEngines.hpp
   trunk/pkg/common/Engine/StandAloneEngine/ResetPositionEngine.cpp
   trunk/pkg/common/SConscript
Log:
1. Added Se3Interpolator engine, with scripts/test/Se3Interpolator.py
2. Added from math import * to PythonUI_rc.py so that math functions are readily accessible everywhere
3. Implemented stopStrain in UniaxialStrainControlledTest
4. other small fixes


Modified: trunk/extra/Brefcom.cpp
===================================================================
--- trunk/extra/Brefcom.cpp	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/extra/Brefcom.cpp	2008-12-01 19:47:18 UTC (rev 1587)
@@ -156,6 +156,7 @@
 
 		epsN=contGeom->epsN();
 		epsT=contGeom->epsT();
+		//if(I->getId1()==0 && (Omega::instance().getCurrentIteration()%10==0)) LOG_INFO("##"<<I->getId1()<<"+"<<I->getId2()<<": "<<" dist2-1="<<(contGeom->pos1-contGeom->pos2).Length()-1.<<", d0="<<contGeom->d0<<", epsN="<<epsN<<", |epsT|="<<epsT.Length());
 
 		#ifdef BREFCOM_MATERIAL_MODEL
 			BREFCOM_MATERIAL_MODEL

Modified: trunk/extra/usct/UniaxialStrainControlledTest.cpp
===================================================================
--- trunk/extra/usct/UniaxialStrainControlledTest.cpp	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/extra/usct/UniaxialStrainControlledTest.cpp	2008-12-01 19:47:18 UTC (rev 1587)
@@ -84,8 +84,19 @@
 	if(posIds.size()==0 || negIds.size()==0) return;
 	// linearly increase strain to the desired value
 	if(abs(currentStrainRate)<abs(strainRate))currentStrainRate+=strainRate*.005; else currentStrainRate=strainRate;
-	// how much do we move; in the symmetric case, half of the strain is applied at each end;
-	Real dAX=(asymmetry==0?.5:1)*currentStrainRate*originalLength*Omega::instance().getTimeStep();
+	// how much do we move (in total, symmetry handled below)
+	Real dAX=currentStrainRate*originalLength*Omega::instance().getTimeStep();
+	if(!isnan(stopStrain)){
+		Real axialLength=axisCoord(posIds[0])-axisCoord(negIds[0]);
+		Real newStrain=(axialLength+dAX)/originalLength-1;
+		if((newStrain*stopStrain>0) && abs(newStrain)>=stopStrain){ // same sign of newStrain and stopStrain && over the limit from below in abs values
+			dAX=originalLength*(stopStrain+1)-axialLength;
+			LOG_INFO("Reached stopStrain "<<stopStrain<<", deactivating self and stopping in "<<idleIterations+1<<" iterations.");
+			this->active=false;
+			rootBody->stopAtIteration=Omega::instance().getCurrentIteration()+1+idleIterations;
+		}
+	}
+	if(asymmetry==0) dAX*=.5; // apply half on both sides if straining symetrically
 	for(size_t i=0; i<negIds.size(); i++){
 		if(asymmetry==0 || asymmetry==-1 /* for +1, don't move*/) negCoords[i]-=dAX;
 		axisCoord(negIds[i])=negCoords[i]; // update current position
@@ -102,9 +113,6 @@
 	// reverse if we're over the limit strain
 	if(notYetReversed && limitStrain!=0 && ((currentStrainRate>0 && strain>limitStrain) || (currentStrainRate<0 && strain<limitStrain))) { currentStrainRate*=-1; notYetReversed=false; LOG_INFO("Reversed strain rate to "<<currentStrainRate); }
 
-	// if(strain==stopAtStrain){LOG_INFO("Prescibed strain "<<stopAtStrain<<" reached, pausing."); }
-	if(!isnan(stopAtStrain) && ((strain*stopAtStrain>0) && abs(strain)>abs(stopAtStrain))) { strain=stopAtStrain;	rootBody->stopAtIteration=Omega::instance().getCurrentIteration()+2; LOG_INFO("Prescribed strain "<<stopAtStrain<<" reached, will stop in 2 iterations"); }
-
 	if(Omega::instance().getCurrentIteration()%10==0 ) {
 		computeAxialForce(rootBody);
 		#if 0
@@ -297,12 +305,6 @@
 
 	rootBody->engines.push_back(shared_ptr<BrefcomDamageColorizer>(new BrefcomDamageColorizer));
 
-	shared_ptr<PositionOrientationRecorder> por(new PositionOrientationRecorder);
-	por->outputFile="/tmp/usct-traction";
-	por->interval=300;
-	por->saveRgb=true;
-	rootBody->engines.push_back(por);
-
 }
 
 

Modified: trunk/extra/usct/UniaxialStrainControlledTest.hpp
===================================================================
--- trunk/extra/usct/UniaxialStrainControlledTest.hpp	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/extra/usct/UniaxialStrainControlledTest.hpp	2008-12-01 19:47:18 UTC (rev 1587)
@@ -80,9 +80,10 @@
 		Real& axisCoord(body_id_t id){ return Body::byId(id)->physicalParameters->se3.position[axis]; };
 		void init();
 	public:
+		virtual bool isActivated(){return active;}
 		Real strainRate,currentStrainRate;
 		//! strain at which we will pause simulation; inactive (nan) by default; must be reached from below (in absolute value)
-		Real stopAtStrain;
+		Real stopStrain;
 		//! distance of reference bodies in the direction of axis before straining started
 		Real originalLength;
 		vector<Real> originalWidths;
@@ -100,6 +101,10 @@
 		bool blockDisplacements;
 		//! Whether rotations of boundary bodies are blocked.
 		bool blockRotations;
+		//! Are we activated?
+		bool active;
+		//! Number of iterations that will pass without straining activity after stopStrain has been reached (default: 0)
+		long idleIterations;
 
 		/** bodies on which straining will be applied (on the positive and negative side of axis) */
 		vector<body_id_t> posIds, negIds;
@@ -126,11 +131,13 @@
 		Real strain, avgStress;
 
 		virtual void applyCondition(MetaBody* rootBody);
-		UniaxialStrainer(){axis=2; asymmetry=0; currentStrainRate=0; originalLength=-1; limitStrain=0; notYetReversed=true; crossSectionArea=-1; needsInit=true; /* sensorsPusher=shared_ptr<UniaxialStrainSensorPusher>(); */ recordFile="/tmp/usct.data"; strain=avgStress=/*avgTransStrain=*/0; blockRotations=false; blockDisplacements=false;  stopAtStrain=numeric_limits<Real>::quiet_NaN();};
+		UniaxialStrainer(){axis=2; asymmetry=0; currentStrainRate=0; originalLength=-1; limitStrain=0; notYetReversed=true; crossSectionArea=-1; needsInit=true; /* sensorsPusher=shared_ptr<UniaxialStrainSensorPusher>(); */ recordFile="/tmp/usct.data"; strain=avgStress=/*avgTransStrain=*/0; blockRotations=false; blockDisplacements=false;  stopStrain=numeric_limits<Real>::quiet_NaN(); active=true; idleIterations=0; };
 		virtual ~UniaxialStrainer(){};
 		REGISTER_ATTRIBUTES_WITH_BASE(DeusExMachina,
 				(strainRate) 
-				(stopAtStrain) 
+				(stopStrain) 
+				(active)
+				(idleIterations)
 				(currentStrainRate) 
 				(axis) 
 				(asymmetry) 

Modified: trunk/gui/py/PythonUI_rc.py
===================================================================
--- trunk/gui/py/PythonUI_rc.py	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/gui/py/PythonUI_rc.py	2008-12-01 19:47:18 UTC (rev 1587)
@@ -7,6 +7,7 @@
 sys.excepthook=sys.__excepthook__ # apport on ubuntu overrides this, we don't need it
 # sys.path.insert(0,runtime.prefix+'/lib/yade'+runtime.suffix+'/extra')
 
+from math import *
 from yade.wrapper import *
 from yade import runtime
 from yade import utils

Added: trunk/pkg/common/Engine/DeusExMachina/Se3Interpolator.cpp
===================================================================
--- trunk/pkg/common/Engine/DeusExMachina/Se3Interpolator.cpp	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/pkg/common/Engine/DeusExMachina/Se3Interpolator.cpp	2008-12-01 19:47:18 UTC (rev 1587)
@@ -0,0 +1,37 @@
+
+#include"Se3Interpolator.hpp"
+#include<yade/pkg-common/PeriodicEngines.hpp>
+
+YADE_PLUGIN("Se3Interpolator")
+CREATE_LOGGER(Se3Interpolator);
+
+void Se3Interpolator::applyCondition(MetaBody* mb){
+	assert(subscribedBodies.size()==1);
+	const shared_ptr<Body>&b=Body::byId(subscribedBodies[0],mb);
+	Omega& O=Omega::instance();
+	if(!started){
+		started=true;
+		start=b->physicalParameters->se3;
+		if(rotRelative) goal.orientation=goal.orientation*start.orientation;
+		int numGoalEndpoints=0;
+		if(goalVirt>0){startVirt=O.getSimulationTime(); numGoalEndpoints++;}
+		if(goalReal>0){startReal=PeriodicEngine::getClock(); numGoalEndpoints++;}
+		if(goalIter>0){startIter=O.getCurrentIteration(); numGoalEndpoints++;}
+		assert(numGoalEndpoints==1);
+		LOG_DEBUG("Init'ed.");
+	}
+	Real t=-1; // t∈[0,1]
+	if(goalVirt>0) t=(O.getSimulationTime()-startVirt)/(goalVirt-startVirt);
+	if(goalReal>0) t=(PeriodicEngine::getClock()-startReal)/(goalReal-startReal);
+	if(goalIter>0) t=(O.getCurrentIteration()-startIter)/(goalIter-startIter);
+	assert(t>=0);
+	LOG_DEBUG("t="<<t);
+	t=min(t,1.);
+	b->physicalParameters->se3.position=start.position+t*(goal.position-start.position);
+	b->physicalParameters->se3.orientation=Quaternionr().Slerp(t,start.orientation,goal.orientation);
+	if(t>=1.){
+		done=true;
+		LOG_DEBUG("Goal reached.");
+		if(!goalHook.empty()){ PyGILState_STATE gstate; gstate=PyGILState_Ensure(); PyRun_SimpleString(goalHook.c_str()); PyGILState_Release(gstate); }
+	}
+}

Added: trunk/pkg/common/Engine/DeusExMachina/Se3Interpolator.hpp
===================================================================
--- trunk/pkg/common/Engine/DeusExMachina/Se3Interpolator.hpp	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/pkg/common/Engine/DeusExMachina/Se3Interpolator.hpp	2008-12-01 19:47:18 UTC (rev 1587)
@@ -0,0 +1,60 @@
+// 2008 © Václav Šmilauer <eudoxos@xxxxxxxx> 
+#pragma once
+
+#include<yade/core/DeusExMachina.hpp>
+#include<yade/core/PhysicalParameters.hpp>
+#include<yade/pkg-common/RigidBodyParameters.hpp>
+#include<Python.h>
+
+/* Engine interpolating between starting (current) and goal (given) se3, both position and orientation.
+ *
+ * The interpolation is linear, either in iteration space or (real/virtual) time space.
+ *
+ * A given python code can be executed when the ending se3 is reached and the engine deactivates itself.
+ *
+ * Note that eactly one body must be subscribed to this engine, since interpolating positions
+ * on multiple bodies is meaningless.
+ *
+ * Attributes that should be assigned:
+ * 	subscribedBodies (exactly one)
+ * 	goal (7-tuple of position and orientation)
+ * 	startVirt XOR startReal XOR startIter (at what time point to start)
+ * 	goalVirt XOR goalReal XOR goalIter (at what time point to reach desired se3)
+ * 	goalHook (optional: python command to be run when finished)
+ * 	rotRelative (optional: rotation part of goal is relative to the rotation at the beginning)
+ */
+class Se3Interpolator: public DeusExMachina {
+	public:
+		bool done,started;
+		Se3r start;
+		Se3r goal;
+		bool rotRelative;
+		Real goalVirt, goalReal; long goalIter;
+		long startVirt, startReal; long startIter;
+		string goalHook;
+		virtual bool isActivated(){return !done;}
+		Se3Interpolator(): done(false), started(false), rotRelative(false), goalVirt(0), goalReal(0), goalIter(0) {};
+		virtual ~Se3Interpolator(){};
+		virtual void applyCondition(MetaBody* mb);
+	protected:
+		REGISTER_ATTRIBUTES_WITH_BASE(DeusExMachina,
+			(done)
+			(started)
+			(start)
+			(goal)
+			(rotRelative)
+			(goalVirt)
+			(goalReal)
+			(goalIter)
+			(startVirt)
+			(startReal)
+			(startIter)
+			(goalHook)
+		);
+		REGISTER_CLASS_AND_BASE(Se3Interpolator,DeusExMachina);
+		DECLARE_LOGGER;
+};
+REGISTER_SERIALIZABLE(Se3Interpolator);
+	
+
+

Modified: trunk/pkg/common/Engine/StandAloneEngine/PeriodicEngines.hpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PeriodicEngines.hpp	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/pkg/common/Engine/StandAloneEngine/PeriodicEngines.hpp	2008-12-01 19:47:18 UTC (rev 1587)
@@ -11,9 +11,8 @@
  * the number of activations was already reached, no action will be called even if any of active period has elapsed.
  */
 class PeriodicEngine:  public StandAloneEngine {
-	protected:
-		static Real getClock(){ timeval tp; gettimeofday(&tp,NULL); return tp.tv_sec+tp.tv_usec/1e6; }
 	public:
+		static Real getClock(){ timeval tp; gettimeofday(&tp,NULL); return tp.tv_sec+tp.tv_usec/1e6; }
 		Real virtPeriod, virtLast, realPeriod, realLast; long iterPeriod,iterLast,nDo,nDone;
 		PeriodicEngine(): virtPeriod(0),virtLast(0),realPeriod(0),realLast(0),iterPeriod(0),iterLast(0),nDo(-1),nDone(0) { realLast=getClock(); }
 		virtual bool isActivated(){

Modified: trunk/pkg/common/Engine/StandAloneEngine/ResetPositionEngine.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/ResetPositionEngine.cpp	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/pkg/common/Engine/StandAloneEngine/ResetPositionEngine.cpp	2008-12-01 19:47:18 UTC (rev 1587)
@@ -8,7 +8,7 @@
 
 #include"ResetPositionEngine.hpp"
 #include<yade/core/MetaBody.hpp>
-#include<yade/pkg-common/ParticleParameters.hpp>#include<yade/pkg-common/ParticleParameters.hpp>
+#include<yade/pkg-common/ParticleParameters.hpp>
 #include<boost/foreach.hpp>
 
 CREATE_LOGGER(ResetPositionEngine);

Modified: trunk/pkg/common/SConscript
===================================================================
--- trunk/pkg/common/SConscript	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/pkg/common/SConscript	2008-12-01 19:47:18 UTC (rev 1587)
@@ -55,8 +55,8 @@
 		LIBS=env['LIBS']+['Force','ParticleParameters']),
 	env.SharedLibrary('GravityEngines',['Engine/DeusExMachina/GravityEngines.cpp'],
 		LIBS=env['LIBS']+['Force','ParticleParameters']),
-	env.SharedLibrary('JumpChangeSe3',['Engine/DeusExMachina/JumpChangeSe3.cpp'],
-		LIBS=env['LIBS']+['RigidBodyParameters']),
+	env.SharedLibrary('JumpChangeSe3',['Engine/DeusExMachina/JumpChangeSe3.cpp'], LIBS=env['LIBS']+['RigidBodyParameters']),
+	env.SharedLibrary('Se3Interpolator',['Engine/DeusExMachina/Se3Interpolator.cpp'], LIBS=env['LIBS']+['RigidBodyParameters']),
 	env.SharedLibrary('RotationEngine',['Engine/DeusExMachina/RotationEngine.cpp'],
 		LIBS=env['LIBS']+['ParticleParameters','RigidBodyParameters']),
 	env.SharedLibrary('TranslationEngine',['Engine/DeusExMachina/TranslationEngine.cpp'],

Added: trunk/scripts/test/Se3Interpolator.py
===================================================================
--- trunk/scripts/test/Se3Interpolator.py	2008-11-27 08:32:53 UTC (rev 1586)
+++ trunk/scripts/test/Se3Interpolator.py	2008-12-01 19:47:18 UTC (rev 1587)
@@ -0,0 +1,14 @@
+# default parameters or from table
+# encoding: utf-8
+O.bodies.append([
+	utils.sphere([0,0,0],radius=.5),
+])
+
+O.engines=[
+	DeusExMachina('Se3Interpolator',{'subscribedBodies':[0],'goal':[10,10,0,0,0,1,pi],'startIter':10,'goalIter':1010,'goalHook':'print "Finished moving the thing!"; O.pause()'}),
+]
+O.dt=1e-6
+print 'Initial se3:',O.bodies[0].phys['se3']
+#O.saveTmp('init'); O.run(); O.wait();
+#print 'Final   se3:',O.bodies[0].phys['se3']
+#quit()