yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #06083
[Branch ~yade-dev/yade/trunk] Rev 2531: 1. Add HdapsGravityEngine which reads acceleration from real accelerometer in thinkpads (toy engine)
------------------------------------------------------------
revno: 2531
committer: Václav Šmilauer <eu@xxxxxxxx>
branch nick: yade
timestamp: Fri 2010-11-05 15:13:01 +0100
message:
1. Add HdapsGravityEngine which reads acceleration from real accelerometer in thinkpads (toy engine)
2. Fix bug in qt4 interface where multi-number entries (Vector3r etc) might have some values zeroed due to wrong order of initial update and signal connects.
added:
scripts/test/hdaps.py
modified:
SConstruct
gui/qt4/SerializableEditor.py
pkg/common/GravityEngines.cpp
pkg/common/GravityEngines.hpp
--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk
Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription
=== modified file 'SConstruct'
--- SConstruct 2010-10-26 13:41:30 +0000
+++ SConstruct 2010-11-05 14:13:01 +0000
@@ -159,9 +159,9 @@
# do not propagate PATH from outside, to ensure identical builds on different machines
#env.Append(ENV={'PATH':['/usr/local/bin','/bin','/usr/bin']})
-# ccache needs $HOME to be set; colorgcc needs $TERM; distcc wants DISTCC_HOSTS
+# ccache needs $HOME to be set, also CCACHE_PREFIX if used; colorgcc needs $TERM; distcc wants DISTCC_HOSTS
# fakeroot needs FAKEROOTKEY and LD_PRELOAD
-propagatedEnvVars=['HOME','TERM','DISTCC_HOSTS','LD_PRELOAD','FAKEROOTKEY','LD_LIBRARY_PATH']
+propagatedEnvVars=['HOME','TERM','DISTCC_HOSTS','LD_PRELOAD','FAKEROOTKEY','LD_LIBRARY_PATH','CCACHE_PREFIX']
for v in propagatedEnvVars:
if os.environ.has_key(v): env.Append(ENV={v:os.environ[v]})
if env.has_key('PATH'): env.Append(ENV={'PATH':env['PATH']})
@@ -585,11 +585,11 @@
if env['mono']:
env['topLevelDir']=os.path.abspath(os.getcwd())
- env.SConscript('SConscript-mono',build_dir=buildDir,duplicate=0)
+ env.SConscript('SConscript-mono',variant_dir=buildDir,duplicate=0)
else:
- # read top-level SConscript file. It is used only so that build_dir is set. This file reads all necessary SConscripts
- env.SConscript(dirs=['.'],build_dir=buildDir,duplicate=0)
+ # read top-level SConscript file. It is used only so that variant_dir is set. This file reads all necessary SConscripts
+ env.SConscript(dirs=['.'],variant_dir=buildDir,duplicate=0)
#################################################################################
## remove plugins that are in the target dir but will not be installed now
=== modified file 'gui/qt4/SerializableEditor.py'
--- gui/qt4/SerializableEditor.py 2010-10-13 14:03:59 +0000
+++ gui/qt4/SerializableEditor.py 2010-11-05 14:13:01 +0000
@@ -214,8 +214,9 @@
w=QSpinBox()
w.setRange(int(-1e9),int(1e9)); w.setSingleStep(1);
self.grid.addWidget(w,row,col);
- w.valueChanged.connect(self.update)
- self.refresh()
+ self.refresh() # refresh before connecting signals!
+ for row,col in itertools.product(range(self.rows),range(self.cols)):
+ self.grid.itemAtPosition(row,col).widget().valueChanged.connect(self.update)
def refresh(self):
val=self.getter()
for row,col in itertools.product(range(self.rows),range(self.cols)):
=== modified file 'pkg/common/GravityEngines.cpp'
--- pkg/common/GravityEngines.cpp 2010-10-13 16:23:08 +0000
+++ pkg/common/GravityEngines.cpp 2010-11-05 14:13:01 +0000
@@ -6,10 +6,13 @@
* GNU General Public License v2 or later. See file LICENSE for details. *
*************************************************************************/
-#include"GravityEngines.hpp"
+#include<yade/pkg-common/GravityEngines.hpp>
+#include<yade/pkg-common/PeriodicEngines.hpp>
#include<yade/core/Scene.hpp>
+#include<boost/regex.hpp>
+//#include<stdio.h>
-YADE_PLUGIN((GravityEngine)(CentralGravityEngine)(AxialGravityEngine));
+YADE_PLUGIN((GravityEngine)(CentralGravityEngine)(AxialGravityEngine)(HdapsGravityEngine));
void GravityEngine::action(){
/* skip bodies that are within a clump;
@@ -55,3 +58,32 @@
scene->forces.addForce(b->getId(),acceleration*b->state->mass*toAxis);
}
}
+
+
+Vector2i HdapsGravityEngine::readSysfsFile(const string& name){
+ char buf[256];
+ ifstream f(name.c_str());
+ if(!f.is_open()) throw std::runtime_error(("HdapsGravityEngine: unable to open file "+name).c_str());
+ f.read(buf,256);f.close();
+ const boost::regex re("\\(([0-9+-]+),([0-9+-]+)\\).*");
+ boost::cmatch matches;
+ if(!boost::regex_match(buf,matches,re)) throw std::runtime_error(("HdapsGravityEngine: error parsing data from "+name).c_str());
+ //cerr<<matches[1]<<","<<matches[2]<<endl;
+ return Vector2i(lexical_cast<int>(matches[1]),lexical_cast<int>(matches[2]));
+
+}
+
+void HdapsGravityEngine::action(){
+ if(!calibrated) { calibrate=readSysfsFile(hdapsDir+"/calibrate"); calibrated=true; }
+ Real now=PeriodicEngine::getClock();
+ if(now-lastReading>1e-3*msecUpdate){
+ Vector2i a=readSysfsFile(hdapsDir+"/position");
+ lastReading=now;
+ a-=calibrate;
+ if(abs(a[0]-accel[0])>updateThreshold) accel[0]=a[0];
+ if(abs(a[1]-accel[1])>updateThreshold) accel[1]=a[1];
+ Quaternionr trsf(AngleAxisr(.5*accel[0]*M_PI/180.,-Vector3r::UnitY())*AngleAxisr(.5*accel[1]*M_PI/180.,-Vector3r::UnitX()));
+ gravity=trsf*zeroGravity;
+ }
+ GravityEngine::action();
+}
=== modified file 'pkg/common/GravityEngines.hpp'
--- pkg/common/GravityEngines.hpp 2010-10-13 16:23:08 +0000
+++ pkg/common/GravityEngines.hpp 2010-11-05 14:13:01 +0000
@@ -50,3 +50,20 @@
};
REGISTER_SERIALIZABLE(AxialGravityEngine);
+class HdapsGravityEngine: public GravityEngine{
+ public:
+ Vector2i readSysfsFile(const std::string& name);
+ virtual void action();
+ YADE_CLASS_BASE_DOC_ATTRS(HdapsGravityEngine,GravityEngine,"Read accelerometer in Thinkpad laptops (`HDAPS <http://en.wikipedia.org/wiki/Active_hard_drive_protection>`__ and accordingly set gravity within the simulation. This code draws from `hdaps-gl <https://sourceforge.net/project/showfiles.php?group_id=138242>`__ .",
+ ((string,hdapsDir,"/sys/devices/platform/hdaps",,"Hdaps directory; contains ``position`` (with accelerometer readings) and ``calibration`` (zero acceleration)."))
+ ((Real,msecUpdate,50,,"How often to update the reading."))
+ ((int,updateThreshold,4,,"Minimum difference of reading from the file before updating gravity, to avoid jitter."))
+ ((Real,lastReading,-1,Attr::hidden|Attr::noSave,"Time of the last reading."))
+ ((Vector2i,accel,Vector2i::Zero(),(Attr::noSave|Attr::readonly),"reading from the sysfs file"))
+ ((Vector2i,calibrate,Vector2i::Zero(),,"Zero position; if NaN, will be read from the *hdapsDir* / calibrate."))
+ ((bool,calibrated,false,,"Whether *calibrate* was already updated. Do not set to ``True`` by hand unless you also give a meaningful value for *calibrate*."))
+ ((Vector3r,zeroGravity,Vector3r(0,0,-1),,"Gravity if the accelerometer is in flat (zero) position."))
+ );
+};
+REGISTER_SERIALIZABLE(HdapsGravityEngine);
+
=== added file 'scripts/test/hdaps.py'
--- scripts/test/hdaps.py 1970-01-01 00:00:00 +0000
+++ scripts/test/hdaps.py 2010-11-05 14:13:01 +0000
@@ -0,0 +1,21 @@
+
+# With Thinkpad laptops, control the sphere's motion by tilting the
+# laptop.
+
+O.bodies.append(
+ utils.facetBox(center=(0,0,.1),extents=(.5,.5,.1),wallMask=31,color=(0,0,1))+
+ [utils.sphere((0,0,.1),.04,color=(1,1,1))]
+)
+
+O.engines=[
+ ForceResetter(),
+ InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
+ InteractionLoop([Ig2_Facet_Sphere_ScGeom()],[Ip2_FrictMat_FrictMat_FrictPhys()],[Law2_ScGeom_FrictPhys_CundallStrack()]),
+ HdapsGravityEngine(calibrate=(-495,-495),calibrated=True,zeroGravity=(0,0,-1)),
+ NewtonIntegrator(damping=.3),
+]
+O.dt=utils.PWaveTimeStep()
+
+import yade.qt
+yade.qt.View()
+O.run()