Life has been quite hectic lately but I am shooting for a second release of SIMPACK. I have spent time fixing bugs and adding a new package – robotics. This video shows a robotic workcell simulation I am working on.
Archive for the ‘Uncategorized’ Category
Robotic Workcell
April 13, 2007Source Code Now Available
September 18, 2006It was decided in the very beginning that this is an open source project since I benefited so much from other open source code. However, it still takes me considerable time to clean up the source before I can open it up. I started to use CVS to do version control, and then later found out SVN is now a more popular method. Like many other open source projects, I chose SourceForge to host it. I picked BSD license because it is less restricted. The result is far from perfect, but I finally managed to let it go. If you are interested in anything you see in this blog, check out the source code!
HalfEdge.pair
August 12, 2006To my startling I paid no attention to HalfEdge.pair when I decided that a triangle mesh should be generalized to a polytope instead of a polyhedron. HalfEdge.pair could be null and should be checked when traversing all the edges emitted from a vertex.
Make Movies
June 6, 2006Step 1:
Do screen grab at every frame and encode the captured image to JPEG format. The solution could come from Java 3D but using Robot seems to be a more stable method (from I read from different forums).
try { //setLocationRelativeTo(null); Rectangle win = getBounds(); Robot robot = new Robot(getGraphicsConfiguration().getDevice()); BufferedImage image = robot.createScreenCapture(new Rectangle(win.x, win.y, win.width, win.height)); FileOutputStream out = new FileOutputStream("image" + jpgCount + ".jpg"); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image); param.setQuality(0.9f, false); encoder.setJPEGEncodeParam(param); encoder.encode(image); out.close(); } catch(AWTException e) { e.printStackTrace(); } catch(IOException e) { System.err.println("I/O exception!"); } jpgCount++;
Step 2:
Stitch the still images into a movie using ffmpeg:
or
Bit rate is probably the main factor for quality. Choose wisely. The default bit rate of 200 yields low quality result.
Contact Joint Summary
April 11, 2006There are three DOF in the contact joint. A generic constraint equation is written as
J v = c  (1) 
The first DOF is in the normal direction. The LHS of Eq. (1) is
where r_{1} = cp – p_{1} and r_{2} = cp – p_{2}. The RHS of Eq. (1) is
c = erp/h⋅depth
But c is limited by maxvel, so
if (c > maxvel) c = maxvel
Since cfm is associated with the constraint DOF, a specific cfm can be entered here. There are 3 possible cfm, which are set up by soft_cfm, slip1, and slip2, respectively.
cfm(1) = soft_cfm
The impact has a direct effect on c
pick the larger value between contact and impact
if(c_i > c) c = c_i
The lower and upper bounds are
lo(1) = 0 hi(1) = infinity
The second DOF is the first tangent direction. Let t_{1} and t_{2} be the tangent directions to normal n
c = motion1 (so motion1 and motion2 are velocities) lo(2) = mu (if mu=0, the friction force is practically set to zero) hi(2) = mu cfm(2) = slip1
The LHS of the constraint equation in the second tangent direction is
The RHS of the constraint equation is
c = motion2 lo(3) = mu2 hi(3) = mu2 cfm(3) = slip2
Dualspace Expansion for Estimating Penetration depth
April 10, 2006So I have been implementing Dualspace Expansion for Estimating Penetration depth (DEEP) for a while now. In the past few days I put it to work and it sucked. The amount of frustration from doing Contact Manifold & Signed Distance Map and getting Trouble With The Projection kept piling up to this point, and this DEEP blow just pushed the frustration to an astronomical level. This morning I finally had a revelation that I might just need to go back to make boxbox collision work instead of finding new algorithms that add more unmanageable complexity without any realistic benefit.
But here is the twist of the story. After all, the time I have invested in this effort will not be wasted. An innocent bug was accidentally found and DEEP w/ contact manifold code finally works!! It turns out the problem is when only four Contact are used for every contact that is happenning. Somehow I still cannot duplicate the performance of test_crash, but with careful tunning of the contact parameters, the collision of the boxes will show some physically believable behaviors. To me it has been a major progress considering how many frustrating hours I have spent on coding this. For example, erp=0.8 never works and neither without using maxvel to restraint the correcting contact velocity.
Now a new problem emerges: DEEPGeom will break HashSpace …
Trouble With The Projection
March 13, 2006


The Gauss map on the right shows the overlay of a feature pair FV, where the intersection can be easily missed if this pair is projected onto a plane. There is definitely a chance I misunderstand how the projection works. Otherwise I have to workaround without the projection.
After some web searching, I learned that I was using orthographic projection, while I should use is gnomonic projection. The advantage for gnomonic projection is that the great circles will always be mapped to straight lines.
Contact Manifold & Signed Distance Map
January 19, 2006A quick review of my work for the past two months:
Contact Manifold
As I have been struggling with the boxbox collision detection, I started to get fascinated by the idea of constructing a contact manifold, which contains a number of selected contact points. My first attempt is to adapt Bullet code from Erwin Coumans, who claims to successfully build correct contact manifolds. Eventually I did not succeed to make the adapted Java code run correctly. Thus I stopped working on the contact manifold idea with frustration.
Signed Distance Map
Then I bought a book from Christer Ericson with the hope of getting some working boxbox collision and/or contact manifold codes. It turned out there was nothing in the book I could use immediately. In the meantime, the idea of signed distance map came to me but I don’t understand how it really works. I tried to resolve this problem by adapting PhysicsEngine. So far I have not yet made the adapted Java code work and inevitably the frustration grew.
Intersection and Penetration Depth
November 28, 2005So it has been two weeks since I started translating C++ SOLID code into Java code. Over the Thanksgiving weekend I intensely debugged my code such that it now runs reasonablely. One notable bug I have is that within the subroutine I cannot simply reassign the argument variable to a new object.
void test() { Vector3d v = new Vector3d(); foo(v); System.out.println(v.x + " " + v.y + " " + v.z); // still (0.0, 0.0, 0.0) } void foo(Vector3d v) { Vector3d a = new Vector3d(1.0, 2.0, 3.0); v = a; // this has no effect on v }
When checking the results from Penetration.java, it is found that the calculation of penetration depth is soemewhat unstable and slow. My todo list will just have to expand:
 To understand the GJK algorithm more deeply.
 To thoroughly test my current implementation.
I think it is quite reasonable to assume only one contact point when two convex objects contact or intersect/impact. Thus the penetration depth and the impact normal can be conveniently calculated from the GJK subroutines. I implemented this idea by modifying BoxBoxCollider.java today and the test results are satisfactory so far with minor observed intersections. The results certainly look better than the ODE implementation, which I don’t fully understand either. Let’s assume now the convex problems are resolved. Then I still need to investigate the complex/trimesh problems. More items on todo list:
 Check SOLID complex package and try to implement a corresponding one for my trimesh. Can RAPID code be integrated here?
 Try two packaging and delivery methods – applet and web start.
Crank Model Now Works
November 1, 2005Last Friday I expanded the piston assembly model to a full cranktrain model. The original Smith method worked immediately, but Baraff method did not. Today I finally have the bug fixed 🙂 My confidence in the Baraff method rises as the results match pretty well with those of the Smith method. Now the performace of the Baraff method is still a question mark. I don’t feel the program running any faster using the new method.
The bug fix is within buildTree() in World2.java
TreeNode buildTree(Body b) { // get b = the next enabled, untagged body, and tag it if (b.tag!=0  (b.flags & Body.Disabled)!=0) return null; b.tag = 1; aux.clear(); LinkedList stack = new LinkedList(); // tag all bodies and joints starting from b TreeNode root = new TreeNode(b, null); TreeNode node = root, childnode; stack.addFirst(node); while (stack.size() > 0) { node = (TreeNode)stack.removeFirst(); // pop body node off stack b = node.body; // traverse and tag all body's joints, // add untagged connected bodies to stack Iterator j = b.nodes.iterator(); while(j.hasNext()) { JointNode jn = (JointNode)j.next(); if(jn.joint.tag==0) { jn.joint.tag = 1; if(jn.body!=null && jn.body.tag==0) { childnode = new TreeNode(jn.joint, node); childnode = new TreeNode(jn.body, childnode); jn.body.tag = 1; stack.addFirst(childnode); } else aux.add(n.joint); // put boundary joints into auxiliary joint list } } } return root; }