How to count steps a walker takes?
I need to count the number of steps a walker (the SuperWalker to be exact) makes. I, however, am new to breve and am having trouble getting it to work. I first set up a collision handler inside of the Creature class, but it didn't seem to work right:
in init-with: self handle-collisions with-type "Floor" with-method "make-step".
-and-
+ to make-step with floorObject (object):
print "___***I just hit the Floor!.".
It never outputs the message so make-step isn't being called. I also tried to make a subclass of Cube (what the legs are) and have it handle counting each collision, but I could never get past some syntax errors, even though the code was basically the same. Any ideas? Thanks!

Try the Creature's limbs, not the Creature itself
The collision callbacks are called for the individual limbs, not the multibody. This means you should make a custom subclass of "Link" which includes the collision handler. Then, instead of using Link objects for the legs, the creature should use your new class....
The class might look something like this:
Link : MyLink {
+ to init:
self handle-collisions with-type "Floor" with-method "make-step".
+ to make-step:
# step counting code here...
}
- jon
Constant Collisions
Thanks for the quick reply Jon.
Your suggestion did work--I missed the part where it created the Links--but has given rise to a new problem. That is, of course, the age old "they are touching so I get a collision every step". Because the method to handle collisions is only called when there is a collision, it's hard to use a flag to denote whether or not a new step is being made. Is there an easy way around this? I thought of storing the position of a collision when it occurs, but is the collision position on the floor available to the make-step function (when coded as + to make-step with floorObject (object):)? Are there any other ways?
Thanks!
try a lastCollisionTime variable
How about using a variable called lastCollisionTime which records when each collision occurs? Then, in the "iterate" method of the links, check the difference between the current time and the lastCollisionTime. If it's greater than a certain value, then the limb has been lifted off the ground. You may want to experiment with the actual time tolerance here, because the leg might drag or bounce slightly without really being lifted.
The controller method "get-time" will come in useful for implementing this.
- jon
how would you implement this
how would you implement this class in python? I'm trying to cause a simulation to end once a creature falls over (i.e. the link for its body collides with the floor).
Heres the
Heres the traceback:
Traceback (most recent call last):
File "coolwalker/environment.py", line 55, in ?
Environment()
File "coolwalker/environment.py", line 13, in __init__
Environment.init(self)
File "coolwalker/environment.py", line 26, in init
self.coolwalker = breve.createInstances( breve.Coolwalker, 1 )
File "lib/classes/breve/__init__.py", line 87, in createInstances
return inClass()
File "coolwalker/coolwalker.py", line 30, in __init__
self.init()
File "coolwalker/coolwalker.py", line 70, in init
self.bodyLink = breve.createInstances( breve.HeadLink, 1 )
File "lib/classes/breve/__init__.py", line 87, in createInstances
return inClass()
File "coolwalker/coolwalker.py", line 126, in __init__
self.handleCollisions(breve.Floor, self.signalSimulationEnd())
File "lib/classes/breve/Real.py", line 199, in handleCollisions
breve.breveInternalFunctionFinder.addCollisionHandler( self, self, theType, theMethod )
File "lib/classes/breve/__init__.py", line 139, in __call__
return breveInternal.callInternalFunction( self.function, args )
RuntimeError: invalid type for argument 1 of internal function "addCollisionHandler" (got "int", expected "array" )
An error occurred while executing the file "coolwalker/environment.py"
Context: Environment is the main experiment file in which in instance of coolwalker and of floor are created; I want coolwalker to reset stop if the main link touches the floor
Right now in coolwalker I have a subclass which looks like this:
class HeadLink(breve.Link):
def __init__( self ):
breve.Link.__init__(self)
self.signal = 0
self.handleCollisions(breve.Floor, self.signalSimulationEnd())
def signalSimulationEnd(self):
self.signal = 1
Help appreciated
handleCollisions wants a string
Looks like the error message there is messed up -- but handleCollisions wants the classname as a string, not as the Python object itself.
I realize that this is "un-pythonic" as they say, but it's for compatibility with the steve version.
- jon
Thanks Jon, worked fine.
Thanks Jon, worked fine.
Somewhat unrelated to the current thread, but do you know how I could calculate how far from vertical an object is, as a float from 0 to 1 (1 being vertical lets say)?
I realize i should really read up on what rotation matrices are and how they work and then figure out some way of getting that value from the getRotationMatrix method, but is there an easier way you can think of?
using a rotation matrix is easy...
Using a rotation matrix should be easy -- just transform the vector (0, 1, 0) in object space into world space and check the Y component:
newVector = myRotation * ( 0, 1, 0 ).
verticalComponent = newVector::y.
- jon
Thanks again Jon!
Thanks again Jon!