FCL Error With ComputeSignedDistancePairwisePoints in PyDrake - drake

I'm getting a somewhat frequent error when performing collision queries using the ComputeSignedDistancePairwisePoints function, and it doesn't seem easy to find the conditions which cause the error. I saw this issue from 2019 on Github referencing the same error, but there weren't many details for the "fix".
The conditions of my simulation are as follows: I apply VHACD to decompose an object I would like to manipulate into several coarse convex bodies that jointly act as the collision geometry. The fingertips of the robot are modeled as spheres. At a seemingly random point in the simulation, this error occurs. Is there any recourse? Should I do something special with my collision geometries to prevent this from happening?
*** RuntimeError: Error with configuration
Original error message: external/fcl/include/fcl/narrowphase/detail/convexity_based_algorithm/gjk_libccd-inl.h:(1719): validateNearestFeatureOfPolytopeBeingEdge(): The origin is outside of the polytope. This should already have been identified as separating.
Shape 1: Sphere(0.01200000000000000025)
X_FS1
-0.40370167831914760548 -0.019479333109567995019 -0.9146832842595900015 0.74747104350671045303
-0.4289595844695910376 0.88710005183204809764 0.17043231187557600359 0.025509175267072643767
0.80809568110093199511 0.46116597188125679763 -0.36647962639802561524 0.045779118115638992026
0 0 0 1
Shape 2: Convex(v count: 16, f count: 28)
X_FS2
0.98447767053732548881 0.11941117744570119152 -0.12862615175162719905 0.70727978567772809004
-0.11946133329759119068 0.99281162514245557826 0.0073530149434261633107 0.019925905554638502493
0.12857957092852342895 0.0081269725622573462526 0.99166589447091968434 0.044593263795921309067
0 0 0 1
Solver: GjkSolver_libccd
collision_tolerance: 2.0097183471152322134e-14
max collision iterations: 500
distance tolerance: 9.9999999999999995475e-07
max distance iterations: 1000

This is a case of good news/bad news.
Good news: this isn't your fault.
Bad news: there's probably nothing you can do about it. It's most likely a bug in FCL.
Good news: the error message should provide almost enough information to reproduce the error and hunt it down.
Bad news: to be enough, we need to know what the convex shape is; we know it has 16 vertices and 28 faces, but that's not enough to reproduce the bug.
Hypothesis
It may well turn out there's a "problem" with the convex shape, but we need to get a hold of it to determine that. It's worth noting that VHACD advertises creating "near" convex parts. Neither Drake nor FCL particularly validates whether the shape is actually convex or not and it could well be that your shape is falling into that crack, leading to an inconsistent view on the distance problem.
Conclusion: This definitely constitutes a bug that should be addressed. I've opened an issue for it in Drake. If you can track down the convex shape details and submit them there, we can tackle the problem.

Related

Q-Learning: Inaccurate predictions

I recently started getting into Q-Learning. I'm currently writing an agent that should play a simple board game (Othello).
I'm playing against a random opponent. However it is not working properly. Either my agent stays around 50% winrate or gets even worse, the longer I train.
The output of my neural net is an 8x8 matrix with Q-values for each move.
My reward is as follows:
1 for a win
-1 for a loss
an invalid move counts as loss therefore the reward is -1
otherwise I experimented with a direct reward of -0.01 or 0.
I've made some observations I can't explain:
When I consider the prediction for the first move (my agent always starts) the predictions for the invalid moves get really close to -1 really fast. The predictions for the valid moves however seem to rise the longer I play. They even went above 1 (they were above 3 at some point), what shouldn't be possible since I'm updating my Q-values according to the Bellman-equation (with alpha = 1)
where Gamma is a parameter less than 1 (I use 0.99 for the most time). If a game lasts around 30 turns I would expect max/min values of +-0.99^30=+-0.73.
Also the predictions for the starting state seem to be the highest.
Another observation I made, is that the network seems to be too optimistic with its predictions. If I consider the prediction for a move, after which the game will be lost, the predictions for the invalid turns are again close to -1. The valid turn(s) however, often have predictions well above 0 (like 0.1 or even 0.5).
I'm somewhat lost, as I can't explain what could cause my problems, since I already double-checked my reward/target matrices. Any ideas?
i suspect your bellman calculation (specifically, Q(s', a')) does not check for valid moves as the game progresses. that would explain why "predictions for the invalid moves get really close to -1 really fast".

Bidirectional Path Tracing questions

I'm coding a Bidirectional Path Tracing for school in C++ and I have some questions (I don't find useful explanations on the web)
1) Why the EyePath has one more vertice ?
2) When I compute the direct illumination during the EyePath creation, do I need to take account of the value of the previous vertice ? I'm asking that because I saw it on a code but it seems weird.
3) I don't understand very well how to connect both paths. Randomly ? Everyone with everyone ? For the moment I connect randomly one vertice with another one.
4) PBRT book implements a contribution according to Eyepath and LightPath length. Do I need to do it knowing that all the objects in my geometry are diffuse ?
5) Are new rays randomly generated in a hemisphere at every bounce ?
All objects are diffuse.
For the moment I get this result with 15 samples.
1) Why the EyePath has one more vertice ?
That's the position sample on your eyes/camera. For pinhole camera, it's a fixed point, but for thin len camera with finite aperture, it needs to be sampled.
5) Are new rays randomly generated in a hemisphere at every bounce ?
That's what BRDF for. If you don't care importance sampling, uniform random on hemisphere is the simplest. Anyway, read Monte Carlo sampling chapter of the PBRT book.
I guess you're new to Monte Carlo ray tracing. The bidirectional path tracing is an advanced algorithm based on path tracing, light tracing and importance sampling. So make sure you understand these techniques well before any coding for bidirectional one~
PS: Just found a detailed explanation on the implementation of bidirectional path tracing (9-part series): http://rendering-memo.blogspot.com/2016/03/bidirectional-path-tracing-1-kickoff.html

OpenCV: PNP pose estimation fails in a specific case

I am using OpenCV's solvePnPRansac function to estimate the pose of my camera given a pointcloud made from tracked features. My pipeline consists of multiple cameras where I form the point cloud from matched features between two cameras, and use that as a reference to estimate the pose of one of the cameras as it starts moving. I have tested this in multiple settings and it works as long as there are enough features to track while the camera is in motion.
Strangely, during a test I did today, I encountered a failure case where solvePnP would just return junk values all the time. What's confusing here is that in this data set, my point cloud is much denser, it's reconstructed pretty accurately from the two views, the tracked number of points (currently visible features vs. features in the point cloud) at any given time was much higher than what I usually have, so theoretically it should have been a breeze for solvePnP, yet it fails terribly.
I tried with CV_ITERATIVE, CV_EPNP and even the non RANSAC version of solvePnP. I was just wondering if I am missing something basic here? The scene I am looking at can be seen in these images (image 1 is the scene and feature matches between two perspectives, image 2 is the point cloud for reference)
The part of the code doing PNP is pretty simple. If P3D is the array of tracked 3Dpoints, P2D is the corresponding set of image points,
solvePnpRansac(P3D, P2D, K, d, R, T, false, 500, 2.0, 100, noArray(), CV_ITERATIVE);
EDIT: I should also mention that my reference poincloud was obtained with a baseline of 8 feet between the cameras, whereas the building I am looking at was probably like a 100 feet away. Could the possible lack of disparity cause issues as well?

Explanation for Values in Scharr-Filter used in OpenCV (and other places)

The Scharr-Filter is explained in Scharrs dissertation. However the values given on page 155 (167 in the pdf) are [47 162 47] / 256. Multiplying this with the derivation-filter would yield:
Yet all other references I found use
Which is roughly the same as the ones given by Scharr, scaled by a factor of 32.
Now my guess is that the range can be represented better, but I'm curious if there is an official explanation somewhere.
To get the ball rolling on this question in case no "expert" can be found...
I believe the values [3, 10, 3] ... instead of [47 162 47] / 256 ... are used simply for speed. Recall that this method is competing against the Sobel Operator whose coefficient values are are 0, and positive/negative 1's and 2's.
Even though the divisor in the division, 256 or 512, is a power of 2 and can can be performed by a shift, doing that and multiplying by 47 or 162 is going to take more time. A multiplication by 3 however can in fact be done on some RISC architectures like the IBM POWER series in a single shift-and-add operation. That is 3x = (x << 1) + x. (On these architectures, the shifter and adder are separate units and can be done independently).
I don't find it surprising that Phd paper used the more complicated and probably more precise formula; it needed to prove or demonstrate something, and the author probably wasn't totally certain or concerned that it be used and implemented alongside other methods. The purpose in the thesis was probably to have "perfect rotational symmetry". Afterwards when one decides to implement it, that person I suspect used the approximation formula and gave up a little on perfect rotational symmetry, to gain speed. That person's goal as I said was to have something that was competitive at the expense of little bit of speed for this rotational stuff.
Since I'm guessing you are willing to do work this as it is your thesis, my suggestion is to implement the original algorithm and benchmark it against both the OpenCV Scharr and Sobel code.
The other thing to try to get an "official" answer is: "Use the 'source', Luke!". The code is on github so check it out and see who added the Scharr filter there and contact that person. I won't put the person's name here, but I will say that the code was added 2010-05-11.

How to optimize affinity propagation results?

I was wondering if anybody knows anything deeper than what I do about the Affinity Propagation clustering algorithm in the python scikit-learn package?
All I know right now is that I input an "affinity matrix" (affmat), which is calculated by applying a heat kernel transformation to the "distance matrix" (distmat). The distmat is the output of a previous analysis step I do. After I obtain the affmat, I pass that into the algorithm by doing something analogous to:
af = AffinityPropagation(affinity = 'precomputed').fit(affmat)
On one hand, I appreciate the simplicity of the inputs. On the other hand, I'm still not sure if I've got the input done correctly?
I have tried evaluating the results by looking at the Silhouette scores, and frequently (but not a majority of the time) I am getting scores close to zero or in the negative ranges, which indicate to me that I'm not getting clusters that are 'naturally grouped'. This, to me, is a problem.
Additionally, when I observe some of the plots, I'm getting weird patterns of clustering, such as the image below, where I clearly see 3 clusters of points, but AP is giving me 10:
I also see other graphs like this, where the clusters overlap a lot.:
How are the cluster centers' euclidean coordinates identified? I notice when I put in percent values (99.2, 99.5 etc.), rather than fraction values (0.992, 0.995 etc.), the x- and y-axes change in scale from [0, 1] to [0, 100] (but of course the axes are scaled appropriately such that I'm getting, on occasion, [88, 100] or [92, 100] and so on).
Sorry for the rambling here, but I'm having quite a hard time understanding the underpinnings of the python implementation of the algorithm. I've gone back to the original paper and read it, but I don't know how the manipulate it in the scikit-learn package to get better clustering.

Resources