Box2D Forums

It is currently Tue May 21, 2013 2:31 am

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Pybox2d and b2Segment
PostPosted: Sun Jul 20, 2008 7:25 am 
Offline

Joined: Sun Jul 20, 2008 6:48 am
Posts: 25
I have been working with python and pybox2d on a little race car project. What i have been trying to do is give the car some sensors so that a computer bot can sense the environment it has to drive through. So for the sensors i thought ray casting would be the way to go, which means using b2Segment and b2Shape.TestSegment. However i am stuck after spending alot of time trying to get b2Segment and b2Shape.TestSegment to work. That is, i can't get TestSegment to return true.

It's either my comprehension/implementation of how b2Segment/TestSegment works or its pybox2d. I was just wondering if anyone has managed to get b2Segment and b2Shape.TestSegment to work with pybox2d? My code is a little entangled and dependant on the framework so i won't try and past huge chunks of code, however i will go through my reasoning and hopefully someone can shed some light on my dilemma.

1. Create a b2Segment with p1 and p2 in world coordinates (attached to the body of the car)
2. Create a AABB in world coordinates around the b2Segment to detect shapes that intersect with the AABB (also attached to the car)
3. Check to see if those shapes found in step 2 intersect the b2Segment, e.g detectedShapes[i].TestSegment( ..., ..., ..., b2Segment from step 1, ...)
4. If a shape does intersect with b2Segment then TestSegment returns true, otherwise false

I can currently detect those shapes that intersect with the AABB, however i can not get step 3/4 to work. The funny thing is, i ported my entire project from pymunk to pybox2d because it had the ray cast functionality :P
Any help will be greatly appreciated.


Top
 Profile  
 
PostPosted: Sun Jul 20, 2008 7:38 am 
Offline

Joined: Mon Jan 07, 2008 10:51 am
Posts: 1911
Sounds about right. You should show us your call of TestSegment, in case you've got something wrong.
See the wiki page on TestSegment. My guess is you are passing lambda==0 or not passing the correct XForm.


Top
 Profile  
 
PostPosted: Sun Jul 20, 2008 7:50 am 
Offline

Joined: Sun Jul 20, 2008 6:48 am
Posts: 25
I have tried to remove the majority of framework (PyQt4.4) dependent code.

Code:

#10px = 1m <--Just a side note to give an idea of scale

self.start = [0, -1.5]  #<--relative to car body
self.end = [-2, -7.0] #<--relative to car body

self.b2dSeg = box2d.b2Segment()
mappedP1 = self.mapToScene( QtCore.QPointF( self.start[0], self.start[1] ) )
mappedP2 = self.mapToScene( QtCore.QPointF( self.end[0], self.end[1] ) )
self.b2dSeg.p1 = box2d.b2Vec2( mappedP1.x(), mappedP2.y() )
self.b2dSeg.p2 = box2d.b2Vec2( mappedP2.x(), mappedP2.y() )

self.intersectDist = None #<-- Python does have a default float32 type, so i just decided to set it to Null/None ???? :P
self.intersectNorm = box2d.b2Vec2( 0.0, 0.0 )

# get nearby shapes
aabb = box2d.b2AABB()

sensorRect = QtCore.QRectF(-2.0, -7.0, 2.0, 5.5)  #<--- A rectangle around self.b2dSeg
mappedTopLeft = self.mapToScene( QtCore.QPointF( sensorRect.topLeft().x(), sensorRect.topLeft().y() ) )
mappedBottomRight = self.mapToScene( QtCore.QPointF( sensorRect.bottomRight().x(), sensorRect.bottomRight().y() ) )
      
aabb.lowerBound.Set( min( mappedTopLeft.x(), mappedBottomRight.x() ), min( mappedTopLeft.y(), mappedBottomRight.y() ) )
aabb.upperBound.Set( max( mappedTopLeft.x(), mappedBottomRight.x() ), max( mappedTopLeft.y(), mappedBottomRight.y() ) )
            
maxCount = 256
shapes = None
number_of_shapes = 0.0
(number_of_shapes, shapes) = self.world.Query( aabb, maxCount )
   
for i in range( 0, number_of_shapes ):
   if( ( shapes[i].GetFilterData().categoryBits ) == 4 ): #<-- Want to ignore the car body (== 2) which is detected in the Query above
      hit = shapes[i].TestSegment( shapes[i].GetBody().GetXForm(), self.intersectDist, self.intersectNorm, self.b2dSeg, 1 )
      print hit, ", ", self.intersectDist
         


Top
 Profile  
 
PostPosted: Sun Jul 20, 2008 6:12 pm 
Offline

Joined: Sun Jul 20, 2008 6:48 am
Posts: 25
So has anyone successfully used PyBox2d and TestSegment together? I'm not sure if the lambda value that i am passing to TestSegment is correct. For example, if i pass in

lambda = 1.0

then i get the error:

TypeError: in method 'b2Shape_TestSegment', argument 3 of type 'float32 *'

So if it needs a float i thought use the numpy.float32 type. When i use that i get the same error.

Any thoughts?


Top
 Profile  
 
PostPosted: Mon Jul 21, 2008 11:45 am 
Offline

Joined: Mon Jan 07, 2008 10:51 am
Posts: 1911
In the C++, lambda is passed by reference. It seems the conversion tool has difficulty representing that sort of thing, and I notice b2World.Query has been changed to avoid that sort of problem.
So you either need some obscure syntax to represent pointers properly in python, or the bindings need to be regenerated changing TestSegment to have a declaration similar to Query (i.e. returing a tuple of answers rather than returning extra things through arguments). I don't know how to do either.


Top
 Profile  
 
PostPosted: Mon Jul 21, 2008 6:34 pm 
Offline

Joined: Sun Jul 20, 2008 6:48 am
Posts: 25
I have abandoned trying to get TestSegment to work, as i'm short on time. However, if i find a solution in the future i will post it here. In the mean time i will contact the PyBox2d guys and see if they can tell me what i'm doing or their doing wrong :)


Top
 Profile  
 
PostPosted: Mon Jul 21, 2008 7:27 pm 
Offline

Joined: Mon Feb 18, 2008 12:30 am
Posts: 88
BorisTheBrave is right. Unfortunately, I didn't notice the function while wrapping the code and will have to create a workaround for it.

I will create a workaround for it and put it in the next release.

Also, though it doesn't relate to your problem, this code can be simplified:
neonnds wrote:
Code:
(number_of_shapes, shapes) = self.world.Query( aabb, maxCount )
   
for i in range( 0, number_of_shapes ):
   if( ( shapes[i].GetFilterData().categoryBits ) == 4 ):
...


to be just:
Code:
(number_of_shapes, shapes) = self.world.Query( aabb, maxCount )
   
for shape in shapes:
   if( ( shape.GetFilterData().categoryBits ) == 4 ):
...


Top
 Profile  
 
PostPosted: Tue Jul 22, 2008 6:49 pm 
Offline

Joined: Sun Jul 20, 2008 6:48 am
Posts: 25
Good oh. Look forward to the fix. Thanks for the responses :)


Top
 Profile  
 
PostPosted: Sun Aug 24, 2008 2:36 am 
Offline

Joined: Sun Jul 20, 2008 6:48 am
Posts: 25
kne came up with the solution to getting TestSegment working. This will require PyBox2d , svn revision 35 or above, and the latest Box2d svn trunk. Thanks kne.

Code:
self.start = [0, -1.5]  #<--relative to car body
self.end = [-2, -7.0] #<--relative to car body

self.b2dSeg = box2d.b2Segment()
mappedP1 = self.mapToScene( QtCore.QPointF( self.start[0], self.start[1] ) )
mappedP2 = self.mapToScene( QtCore.QPointF( self.end[0], self.end[1] ) )
self.b2dSeg.p1 = box2d.b2Vec2( mappedP1.x(), mappedP2.y() )
self.b2dSeg.p2 = box2d.b2Vec2( mappedP2.x(), mappedP2.y() )

self.intersectDist = 0.0
self.intersectNorm = box2d.b2Vec2( 0.0, 0.0 )

# get nearby shapes
aabb = box2d.b2AABB()

sensorRect = QtCore.QRectF(-2.0, -7.0, 2.0, 5.5)  #<--- A rectangle around self.b2dSeg
mappedTopLeft = self.mapToScene( QtCore.QPointF( sensorRect.topLeft().x(), sensorRect.topLeft().y() ) )
mappedBottomRight = self.mapToScene( QtCore.QPointF( sensorRect.bottomRight().x(), sensorRect.bottomRight().y() ) )
     
aabb.lowerBound.Set( min( mappedTopLeft.x(), mappedBottomRight.x() ), min( mappedTopLeft.y(), mappedBottomRight.y() ) )
aabb.upperBound.Set( max( mappedTopLeft.x(), mappedBottomRight.x() ), max( mappedTopLeft.y(), mappedBottomRight.y() ) )
           
maxCount = 256
shapes = None
number_of_shapes = 0.0
(number_of_shapes, shapes) = self.world.Query( aabb, maxCount )

for shape in shapes:
   hit, intersectDist, intersectNorm = shape.TestSegment( shape.GetBody().GetXForm(), b2dSeg, maxLambda )



Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: Google [Bot] and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group