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 <[EMAIL PROTECTED]>
+#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()
_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help : https://help.launchpad.net/ListHelp