billiards-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Billiards-devel] Comparing billiards to other simulators


From: Dimitris Papavasiliou
Subject: Re: [Billiards-devel] Comparing billiards to other simulators
Date: Thu, 1 Apr 2010 23:42:03 +0300

Hi,

> We were thinking of using the fizShot save and load methods to read and
> write test shots. Basically the file is a dump of the table state (state
> and position of each ball) before the events, a list of events from the
> cue's collision with the cue ball to the last ball stopping, and the
> final state of the table.

Just bear in mind that Poolfiz differs fundamentally from Billiards in
terms of its principle of operation.  Billiards employs a
general-pupose real-time numerical simulator in contrast to Poolfiz
which uses an analytical event-based model.  What I mean to say is
that, although you can get a list of events like the one you'll get
from Poolfiz using Billiards it might prove tricky.  From what I read
later-on though, you don't really need it.

> This looks like it. For the time being I think only the resulting table
> state (where the balls are as well as in which pocket they fell if they
> were pocketed) should be enough if we want to be able to switch between
> simulators for automated tests, but if we set the same coefficients in
> poolfiz and billiards and compare the results they yield, then the full
> path might get useful to know how the simulation differs.

Regarding the pockets:  currently they're implemented as a single body
in Billiards together with the ball return tunnels.  So in order to
record which pocket a ball fell into there are two options.

a)  Set up a collision callback to look for ball-pocket collisions
then get the position of the ball at that moment and calculate the
pocket from that.  For example if the position x is smaller than 0.5 *
billiards.tablewidth in absolute value then it fell in some center
pocket.  If its y is positive its in the east pocket otherwise it's
the west pocket.  Something like that.

b)  Break up the pocket and ball-return body into multiple bodies, one
for each pocket and one for the return tunnels.  Then you can simply
check for collisions and derive the pocket the ball fell into from the
collision data.

> I will first add the logging of where the balls are pocketed if this
> information is not already taken in account by billiards.
> Then I will create http pages that allow to set the table state and shot
> parameters, as well as one that allows to get that information, and then
> I will create a basic program that translate poolfiz objects to and from
> billiards with these http pages. I'll give you an update after that.

Regarding the pockets:  I actually thought of a thrid approach much
better that both of the above.  When a collision between two bodies
takes place you can specify the number of contact points to be
generated.  Specifying zero contact points makes the collision have no
physical effect on the simulation, but it is still detected.  So you
can define a small cylindrical volume inside each pocket small enough
so as not to collide with the pocket itslelf (although this could be
taken care of if necessary) but large enough so that the ball can't
possibly miss it.  When a ball collides with these volumes you flag
the ball as having been pocketed in the respective pocket and return
0.

Some implementation details: The only "hard" part is specifying the
volume positions and sizes.  This just needs a little trial and error.
 Set dynamics.drawvolumes = true inside your .billiards file to
actually see the volumes of all bodies.  Then in pooltable.lua add a
few bodies right before the pocket mesh and body specification at the
beginnig:

ewpocket = bodies.capsule {
   ispocketvolume = true,
   pocketnumber = 1,

   radius = ...,
   length = ....,
   position = ...,
}

You need six such bodies of course.  Then once these have been
specified add a check inside collision.lua:

if other.ispocketvolume then
   ball.lastpocket = other.pocketnumber

   return 0
end

This flags the ball that the last pocket it fell into was pocket
number x.  Then the logger can access that information for pocketed
balls (which you can already check with ball.ispocketed == true which
is set inside billiard.lua) and export it via http.  One other thing
which might prove tricky would be to position the volume in such a way
that a ball won't go through it as it rolls down a tunnel on its way
to the return slot (this would flag all balls as having been pocketed
through one of the two pockets closest to the slot).  But you also
need to position it in such a way that a ball can't touch it without
being pocketed.

To set any parameter you can use the settings page:

localhost:29176/settings?thisparam=thisvalue&thatparam=thatvalue...

On second thought you might not want to use this page as it will
return some irrelevant html but it should be easy to create a page
that will return nothing and set parameters.  The relevant code from
settings.lua is just:

            -- Set the new values.

            for argument, value in pairs (query) do
               assert(loadstring (argument .. "=" .. value))()
            end

It should be easy to create a page just like that which will print
parameters.  Sine you need to process these programatically the best
solution would be a plain-text comma-separated value list.  The only
trouble is that Techne does not currently allow query parameters
without values.  For example you can't use a query of the form:

localhost:29176/query?thisparam&thatparam&...

Instead you'd have to use one like this:

localhost:29176/query?param1=billiards.tablewidth&param2=billiards.tableheight&...

This complicates things without reason though.  I can look into making
the necessary changes within the weekend to use the first approach.
There's another matter, whether it's possible right now to get ball
positions etc. using that interface.  You'd have to specify a query
like:

localhost:29176/query?bodies.balls[1].position[1]&bodies.balls[1].position[2]&..

but I'm not sure this would parse correctly.  I'll have to test it.
Furthermore I'm not sure it would be convenient to get the whole table
state like this.  Maybe a dedicated page would be better.  Like:

localhost:29176/tablestate

which would return a bunch of values with all ball state parameters in
some convenient form.  You can still use the query page to get
standard parameters like tablewidth etc. if needed.

> Do you have any suggestions for how I could start billiards from the
> host program?

This questions raises another matter.  Can poolfiz actually run on
Linux?  Because if it can't then we have a rather big problem on our
hands.  If it can the easiest way would probably be to use the system
command like this:

system ("billiards -Oexperiment -Otoon &");

Billiards will stay running after your host program terminates so
you'll have to explicitly quit it somehow.

Let me know which of the above parts you'll need help with.  Also let
me know if you implement any of this.   Most of these features would
be useful if implemented generically enough so if you don't have any
objections I'll add them to the main Billiards code.

Dimitris




reply via email to

[Prev in Thread] Current Thread [Next in Thread]