Ejemplo n.º 1
0
static bool
FeedWayPointLine(WayPointList &way_points, RasterTerrain &terrain,
                 const TCHAR *line)
{
  if (TempString[0] == '\0' ||
      TempString[0] == 0x1a || // dos end of file
      _tcsstr(TempString, TEXT("**")) == TempString || // Look For Comment
      _tcsstr(TempString, TEXT("*")) == TempString) // Look For SeeYou Comment
    /* nothing was parsed, return without error condition */
    return true;

  WAYPOINT *new_waypoint = way_points.append();
  if (new_waypoint == NULL)
    return false; // failed to allocate

  new_waypoint->Details = NULL;

  if (!ParseWayPointString(new_waypoint, TempString, terrain)) {
    way_points.pop();
    return false;
  }

  if (!WaypointInTerrainRange(new_waypoint, terrain)) {
    way_points.pop();
    return true;
  }

  return true;
}
Ejemplo n.º 2
0
void PathPlanner::slotComputePath(const QVector3D& vehiclePosition, const WayPointList& wayPointList)
{
    Q_ASSERT(!wayPointList.isEmpty());

    if(!mIsInitialized) initialize();

    WayPointList wayPointsWithHighInformationGain = wayPointList;
    wayPointsWithHighInformationGain.prepend(WayPoint(vehiclePosition, 0));

    qDebug() << __PRETTY_FUNCTION__ << "computing path for waypointlist" << wayPointsWithHighInformationGain.toString();

    // mDeviceOccupancyGrid points to device memory filled with grid-values of quint8.
    // After fillOccupancyGrid(), empty cells contain a 0, occupied cells contain a 254/255.
    // The cell containing the start is set to 1. Then, one thread is launched per cell,
    // looking into the neighboring cells. If a neighboring cell (26 3d-neighbors) contains
    // a value other than 0 or 254/255, the current cell is set to min(neighbor)+1.
    // This is executed often, so that all cells reachable from start get filled with the
    // distance TO start

    alignPathPlannerGridToColliderCloud();

    QTime t;
    t.start();

    WayPointList computedPath;

    copyParametersToGpu(&mParametersPathPlanner);

    const bool haveToMapGridOccupancyTemplate = checkAndMapGridOccupancy(mCudaVboResourceGridOccupancyTemplate);
    const bool haveToMapGridOccupancyPathPlanner = checkAndMapGridOccupancy(mCudaVboResourceGridPathPlanner);

    // Only re-creates the occupancy grid if the collider cloud's content changed
    populateOccupancyGrid();

    // The first path leads from vehicle position to first waypoint. Clear the occupancy grid above the vehicle!
    // This is currently necessary, because we also scan bernd and the fishing rod, occupying our own cells.
    clearOccupancyGridAboveVehiclePosition(
        mGridOccupancyPathPanner,
        vehiclePosition.x(),
        vehiclePosition.y(),
        vehiclePosition.z(),
        &mCudaStream);

    // We have freed the occupancy grid a little to make path planning easier/possible. Restore it to the real grid asap.
    mRepopulateOccupanccyGrid = true;

    // Make some room for waypoints in host memory. The first float4's x=y=z=w will store just the number of waypoints
    float* waypointsHost = new float[mMaxWaypoints * 4];

    // Find a path between every pair of waypoints
    quint32 indexWayPointStart = 0;
    quint32 indexWayPointGoal = 1;
    quint32 pathNumber = 0;
    do
    {
        mParametersPathPlanner.start = CudaHelper::convert(wayPointsWithHighInformationGain.at(indexWayPointStart));
        mParametersPathPlanner.goal = CudaHelper::convert(wayPointsWithHighInformationGain.at(indexWayPointGoal));

        qDebug() << __PRETTY_FUNCTION__ << "now computing path from" << indexWayPointStart << ":" << wayPointsWithHighInformationGain.at(indexWayPointStart).toString() << "to" << indexWayPointGoal << ":" << wayPointsWithHighInformationGain.at(indexWayPointGoal).toString();

        copyParametersToGpu(&mParametersPathPlanner);

        // Copy the populated and dilated occupancy grid into the PathFinder's domain
        cudaSafeCall(cudaMemcpy(
                         mGridOccupancyPathPanner,
                         mGridOccupancyTemplate,
                         mParametersPathPlanner.grid.getCellCount(),
                         cudaMemcpyDeviceToDevice));

        // Now start path planning.
        markStartCell(mGridOccupancyPathPanner, &mCudaStream);

        growGrid(
            mGridOccupancyPathPanner,
            &mParametersPathPlanner,
            &mCudaStream);

        // We must set the waypoints-array on the device to a special value because
        // a bug can lead to some waypoints not being written. This is ok
        // as long as we can detect this. When memsetting with 0, we can,
        // otherwise we'd find a waypoint from a previous run and couldn't
        // detect this incidence.
        cudaSafeCall(cudaMemset(
                         (void*)mDeviceWaypoints,
                         255, // interpreted as float, should be NaN!
                         4 * mMaxWaypoints * sizeof(float)));

        retrievePath(
            mGridOccupancyPathPanner,
            mDeviceWaypoints,
            &mCudaStream);

        cudaSafeCall(cudaMemcpy(
                         (void*)waypointsHost,
                         (void*)mDeviceWaypoints,
                         4 * mMaxWaypoints * sizeof(float),
                         cudaMemcpyDeviceToHost));

        if(fabs(waypointsHost[0]) < 0.001 && fabs(waypointsHost[1]) < 0.001 && fabs(waypointsHost[2]) < 0.001)
        {
            qDebug() << __PRETTY_FUNCTION__ << "found NO path from" << indexWayPointStart << ":" << wayPointsWithHighInformationGain.at(indexWayPointStart).toString() << "to" << indexWayPointGoal << ":" << wayPointsWithHighInformationGain.at(indexWayPointGoal).toString();
            // When no path was found, we try to find a path to the next waypoint, skipping the problematic one.
            indexWayPointGoal++;
        }
        else
        {
            qDebug() << __PRETTY_FUNCTION__ << "found path with" << waypointsHost[0] << "waypoints";
            // The first waypoint isn't one, it only contains the number of waypoints
            for(int i=1; i<=waypointsHost[0]; i++)
            {
                // workaround for the no-waypoint-bug, which will show values of NaN/NaN/NaN/NaN due to the 255-memset above
                if(isnan(waypointsHost[4*i+3]))
                {
                    qDebug() << __PRETTY_FUNCTION__ << "ignoring waypoint that was skpped in retrievePath due to bug in growGrid.";
                    continue;
                }

                WayPoint newWayPoint;

                if(i == 1)
                {
                    newWayPoint = wayPointsWithHighInformationGain.at(indexWayPointStart);
                }
                else if(i == (int)waypointsHost[0])
                {
                    newWayPoint = wayPointsWithHighInformationGain.at(indexWayPointGoal);
                }
                else
                {
                    newWayPoint = WayPoint(QVector3D(waypointsHost[4*i+0], waypointsHost[4*i+1], waypointsHost[4*i+2]), 0);
                }

                // Append all points of the first path, and then only starting at the second point of the following paths.
                // Otherwise, we have the end of path A and the beginning of path B in the list, although they're the same.
                if(pathNumber == 0 || i > 1)
                {
                    computedPath.append(newWayPoint);
                }
            }

            qDebug() << __PRETTY_FUNCTION__ << "found path between" << wayPointsWithHighInformationGain.at(indexWayPointStart).toString() << "and" << wayPointsWithHighInformationGain.at(indexWayPointGoal).toString() << ":" << computedPath.toString();

            pathNumber++;
            indexWayPointStart = indexWayPointGoal;
            indexWayPointGoal++;
        }
    } while(indexWayPointGoal < wayPointsWithHighInformationGain.size());

    delete waypointsHost;

    if(haveToMapGridOccupancyTemplate) checkAndUnmapGridOccupancy(mCudaVboResourceGridOccupancyTemplate);
    //    cudaGraphicsUnmapResources(1, &mCudaVboResourceGridPathFinder, 0);

    if(haveToMapGridOccupancyPathPlanner) checkAndUnmapGridOccupancy(mCudaVboResourceGridPathPlanner);
    //    cudaGraphicsUnmapResources(1, &mCudaVboResourceGridOccupancy, 0);

    emit path(computedPath.list(), WayPointListSource::WayPointListSourceFlightPlanner);

    qDebug() << __PRETTY_FUNCTION__ << "took" << t.elapsed() << "ms.";
}