给定几何车道,我该如何告诉汽车行驶的路线?

时间:2018-07-04 06:12:14

标签: python math geometry simulation

我正试图让一辆汽车沿着一条车道行驶。我知道车道的所有点,因为现在车道用多边形表示,以两组线段为边界。给定这两个边界,我想找到汽车将要行驶的另一组线段,例如铁路,使其始终位于两个边界段之间。每个边界线段中的线数可能并不总是相同,线段不是“平行”的。

图(这是一个非常简单的图,但是我相信它传达了信息):

Representation of what I want

我已经考虑过以下问题,但我认为它们没有起作用,或者至少效率不高:

  1. 将其拆分为四边形或四边形和三角形,
  2. 从长度为10的线开始,然后旋转直到其终点与两个边界边均等距离,然后重复和
  3. 对于每个输出段,平均两个边界边的斜率。

我想到了更多,但不值得一提。

感谢您的帮助,请随时提出任何问题。

2 个答案:

答案 0 :(得分:1)

以下想法受Dynamic Time Warping(DTW)的启发。这是Shreyas Pimpalgaonkar的想法在评论中的延伸:

总体思路是将街道一侧的点与另一侧的点匹配。例如,沿两侧分布100个点,并尝试在它们之间画线。我们将用于匹配点的标准是接近度。因此,连接线的总长度应尽可能小。一旦有了这些线,就可以计算它们的中点并连接它们。根据您开始的点数,这也会使您的线条更平滑。

这里有一些细节:分配积分并不难。您可以每x单位放置一个点。或者,您可以在线段上分配恒定数量的点。最后,点的分布并不重要。不过,均匀分布会给您更好的结果。

中心点是DTW变体。该算法的基本数据是一个匹配矩阵,该矩阵告诉您将一个点匹配到另一个点的代价是多少。为此,可以使用两点的欧几里得距离。一旦有了这个矩阵(它不必是一个完整的矩阵;对角线附近的条目通常就足够了;请参阅Wikipedia文章中的位置约束),您只需使用动态程序即可解决翘曲问题。

最后,您连接到中间点。就是这样。

我还要补充一点,这不一定能保证路径保持在车道内。但是,只有在非常怪异的道路群中才会破坏。为了安全起见,您可以调整成本矩阵,以使算法不会匹配连接线与车道边界交叉的点。

这里有一些例子。如果需要更平滑的路径,则可以更改在连接线上选择的点(而不是中点)。您可以例如相对于生成线的拉普拉斯算子优化插值参数。这将为您提供线性方程组,使您可以控制路径的平滑度。但是,要保证路径不再留在车道内并不容易。

enter image description here

enter image description here

enter image description here

答案 1 :(得分:-1)

首先,如果您已经设计了一些代码部分,然后提出了问题。只有通过分析才能使您有很多选择,都可以通过java / python来完成。

我只是向您展示一个简单的示例,它详细说明了地图中使用的路径/车道追随者。

private void CarMove(final Marker marker, final LatLng beginLatLng, final LatLng endLatLng, final long duration) {
        final Handler handler = new Handler();
        final long startTime = SystemClock.uptimeMillis();

        final Interpolator interpolator = new LinearInterpolator();

        // set car bearing for current part of path
        float angleDeg = (float)(180 * getAngle(beginLatLng, endLatLng) / Math.PI);
        Matrix matrix = new Matrix();
        matrix.postRotate(angleDeg);
        marker.setIcon(BitmapDescriptorFactory.fromBitmap(Bitmap.createBitmap(mMarkerIcon, 0, 0, mMarkerIcon.getWidth(), mMarkerIcon.getHeight(), matrix, true)));

        handler.post(new Runnable() {
            @Override
            public void run() {
                // calculate phase of animation
                long elapsed = SystemClock.uptimeMillis() - startTime;
                float t = interpolator.getInterpolation((float) elapsed / duration);
                // calculate new position for marker
                double lat = (endLatLng.latitude - beginLatLng.latitude) * t + beginLatLng.latitude;
                double lngDelta = endLatLng.longitude - beginLatLng.longitude;

                if (Math.abs(lngDelta) > 180) {
                    lngDelta -= Math.signum(lngDelta) * 360;
                }
                double lng = lngDelta * t + beginLatLng.longitude;

                marker.setPosition(new LatLng(lat, lng));

                // if not end of line segment of path 
                if (t < 1.0) {
                    // call next marker position
                    handler.postDelayed(this, 16);
                } else {
                    // call turn animation
                    nextTurnAnimation();
                }
            }
        });
    }