bark-simulator / bark

Open-Source Framework for Development, Simulation and Benchmarking of Behavior Planning Algorithms for Autonomous Driving
https://bark-simulator.github.io/
MIT License
287 stars 69 forks source link

calculate the distance between the Agent and the road edge #499

Closed tinmodeHuang closed 3 years ago

tinmodeHuang commented 3 years ago

my idea is to calculate distance between every point in a road egde and the agent and take the minimum of distances as the distance between the Agent and the road edge.

the snippet in /bark/world/objects/agent.hpp:

double GetDistance2RoadEdge() const;

the one in /bark/world/objects/agent.cpp:

#include <boost/geometry.hpp>
...
double Agent::GetDistance2RoadEdge() const {
  double tmp;
  double distance = std::numeric_limits<double>::max();
  Polygon agent_poly = GetPolygonFromState(GetCurrentState());
  for (auto const& point : boost::make_iterator_range(
           boost::geometry::exterior_ring(road_corridor_->GetPolygon()))) {
             tmp = Distance(agent_poly, point);
             distance = tmp < distance ?  tmp : distance;
           }
  return distance;
}

the one in /bark/python_wrapper/world/agent.cpp:

      .def("Distance2RoadEdge", &Agent::GetDistance2RoadEdge)

but the error was thrown out as running bazel test //....

ERROR: /home/tinmode/bark/bark/world/BUILD:1:11: Compiling bark/world/objects/agent.cpp failed: (Exit 1): gcc failed: error executing command /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer '-std=c++0x' -MD -MF ... (remaining 93 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox gcc failed: error executing command /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer '-std=c++0x' -MD -MF ... (remaining 93 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
In file included from ./bark/commons/transformation/frenet.hpp:12:0,
                 from ./bark/world/objects/agent.hpp:13,
                 from bark/world/objects/agent.cpp:10:
./bark/geometry/line.hpp: In function 'bark::geometry::Line bark::geometry::SmoothLine(const Line&, double)':
./bark/geometry/line.hpp:601:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (size_t j = 0; j <= num_points; ++j) {
                        ~~^~~~~~~~~~~~~
In file included from ./bark/world/objects/agent.hpp:18:0,
                 from bark/world/objects/agent.cpp:10:
./bark/world/goal_definition/goal_definition.hpp: In member function 'virtual const Polygon& bark::world::goal_definition::GoalDefinition::GetShape() const':
./bark/world/goal_definition/goal_definition.hpp:30:60: warning: no return statement in function returning non-void [-Wreturn-type]
   virtual const bark::geometry::Polygon& GetShape() const {}
                                                            ^
In file included from ./bark/world/opendrive/road.hpp:17:0,
                 from ./bark/world/map/lane.hpp:16,
                 from ./bark/world/map/road_corridor.hpp:18,
                 from ./bark/world/map/map_interface.hpp:18,
                 from ./bark/world/objects/agent.hpp:19,
                 from bark/world/objects/agent.cpp:10:
./bark/world/opendrive/commons.hpp: In function 'bark::geometry::Line bark::world::opendrive::CreateLineWithOffsetFromLine(bark::geometry::Line, int, bark::world::opendrive::XodrLaneWidth, double, double)':
./bark/world/opendrive/commons.hpp:208:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 1; i < simplified_prev_line.obj_.size(); i++) {
                     ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from external/boost/boost/graph/adjacency_iterator.hpp:13:0,
                 from external/boost/boost/graph/detail/adjacency_list.hpp:37,
                 from external/boost/boost/graph/adjacency_list.hpp:255,
                 from ./bark/world/map/roadgraph.hpp:12,
                 from ./bark/world/map/map_interface.hpp:19,
                 from ./bark/world/objects/agent.hpp:19,
                 from bark/world/objects/agent.cpp:10:
external/boost/boost/detail/iterator.hpp: At global scope:
external/boost/boost/detail/iterator.hpp:13:37: note: #pragma message: This header is deprecated. Use <iterator> instead.
 BOOST_HEADER_DEPRECATED("<iterator>")
                                     ^
In file included from bark/world/objects/agent.cpp:10:0:
./bark/world/objects/agent.hpp: In constructor 'bark::world::objects::Agent::Agent(const State&, const BehaviorModelPtr&, const DynamicModelPtr&, const ExecutionModelPtr&, const Polygon&, const ParamsPtr&, const GoalDefinitionPtr&, const MapInterfacePtr&, const bark::geometry::Model3D&)':
./bark/world/objects/agent.hpp:193:10: warning: 'bark::world::objects::Agent::first_valid_timestamp_' will be initialized after [-Wreorder]
   double first_valid_timestamp_;
          ^~~~~~~~~~~~~~~~~~~~~~
./bark/world/objects/agent.hpp:192:21: warning:   'bark::world::goal_definition::GoalDefinitionPtr bark::world::objects::Agent::goal_definition_' [-Wreorder]
   GoalDefinitionPtr goal_definition_;
                     ^~~~~~~~~~~~~~~~
bark/world/objects/agent.cpp:20:1: warning:   when initialized here [-Wreorder]
 Agent::Agent(const State& initial_state,
 ^~~~~
In file included from bark/world/objects/agent.cpp:10:0:
./bark/world/objects/agent.hpp: In copy constructor 'bark::world::objects::Agent::Agent(const bark::world::objects::Agent&)':
./bark/world/objects/agent.hpp:193:10: warning: 'bark::world::objects::Agent::first_valid_timestamp_' will be initialized after [-Wreorder]
   double first_valid_timestamp_;
          ^~~~~~~~~~~~~~~~~~~~~~
./bark/world/objects/agent.hpp:192:21: warning:   'bark::world::goal_definition::GoalDefinitionPtr bark::world::objects::Agent::goal_definition_' [-Wreorder]
   GoalDefinitionPtr goal_definition_;
                     ^~~~~~~~~~~~~~~~
bark/world/objects/agent.cpp:64:1: warning:   when initialized here [-Wreorder]
 Agent::Agent(const Agent& other_agent)
 ^~~~~
In file included from external/boost/boost/geometry/core/closure.hpp:24:0,
                 from external/boost/boost/geometry/geometry.hpp:34,
                 from external/boost/boost/geometry.hpp:17,
                 from bark/world/objects/agent.cpp:9:
external/boost/boost/geometry/core/ring_type.hpp: In instantiation of 'struct boost::geometry::ring_return_type<const bark::geometry::Polygon_t<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> > >':
external/boost/boost/geometry/core/exterior_ring.hpp:124:55:   required by substitution of 'template<class Polygon> typename boost::geometry::ring_return_type<const Polygon>::type boost::geometry::exterior_ring(const Polygon&) [with Polygon = bark::geometry::Polygon_t<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >]'
bark/world/objects/agent.cpp:149:71:   required from here
external/boost/boost/geometry/core/ring_type.hpp:212:17: error: no type named 'type' in 'struct boost::geometry::core_dispatch::ring_return_type<void, const bark::geometry::Polygon_t<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> > >'
         >::type type;
                 ^~~~
external/boost/boost/geometry/core/ring_type.hpp: In instantiation of 'struct boost::geometry::ring_return_type<bark::geometry::Polygon_t<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> > >':
external/boost/boost/geometry/core/exterior_ring.hpp:103:49:   required by substitution of 'template<class Polygon> typename boost::geometry::ring_return_type<Geometry>::type boost::geometry::exterior_ring(Polygon&) [with Polygon = bark::geometry::Polygon_t<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >]'
bark/world/objects/agent.cpp:149:71:   required from here
external/boost/boost/geometry/core/ring_type.hpp:212:17: error: no type named 'type' in 'struct boost::geometry::core_dispatch::ring_return_type<void, bark::geometry::Polygon_t<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> > >'
bark/world/objects/agent.cpp: In member function 'double bark::world::objects::Agent::GetDistance2RoadEdge() const':
bark/world/objects/agent.cpp:149:71: error: no matching function for call to 'exterior_ring(bark::geometry::Polygon)'
            boost::geometry::exterior_ring(road_corridor_->GetPolygon()))) {
                                                                       ^
In file included from external/boost/boost/geometry/geometry.hpp:49:0,
                 from external/boost/boost/geometry.hpp:17,
                 from bark/world/objects/agent.cpp:9:
external/boost/boost/geometry/core/exterior_ring.hpp:103:49: note: candidate: template<class Polygon> typename boost::geometry::ring_return_type<Geometry>::type boost::geometry::exterior_ring(Polygon&)
 inline typename ring_return_type<Polygon>::type exterior_ring(Polygon& polygon)
                                                 ^~~~~~~~~~~~~
external/boost/boost/geometry/core/exterior_ring.hpp:103:49: note:   substitution of deduced template arguments resulted in errors seen above
external/boost/boost/geometry/core/exterior_ring.hpp:124:55: note: candidate: template<class Polygon> typename boost::geometry::ring_return_type<const Polygon>::type boost::geometry::exterior_ring(const Polygon&)
 inline typename ring_return_type<Polygon const>::type exterior_ring(
                                                       ^~~~~~~~~~~~~
external/boost/boost/geometry/core/exterior_ring.hpp:124:55: note:   substitution of deduced template arguments resulted in errors seen above

according to my understanding, it causes the error that roadcorridor->GetPolygon() is not of the boost::geometry::model::polygon<boost::geometry::model::d2::point_xy> type. I'll appreciate any suggestions you give!

klemense1 commented 3 years ago

why not use Polygon's function double Distance(const Polygon& poly, const Point2d& p) and compare the road polygon and the point of the agent's rear axis?

tinmodeHuang commented 3 years ago

the function you mentioned was in use, for answer to the latter, the purpose is to mapping the distance with whether driving out of the road or not. Moreover, build successfully after the modification as shown below:

double Agent::GetDistance2RoadEdge() const {
  boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > green;
  boost::geometry::read_wkt(
        "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))", green);
  double tmp;
  double distance = std::numeric_limits<double>::max();
  Polygon agent_poly = GetPolygonFromState(GetCurrentState());
  for (auto const& point : boost::make_iterator_range(
           boost::geometry::exterior_ring(green))) {
             tmp = Distance(agent_poly, point);
             distance = tmp < distance ?  tmp : distance;
           }
  return distance;
}

it turns out that the type of road_corridor_->GetPolygon() don't fit into the type bg::geometry::exterior_ring() required.

patrickhart commented 3 years ago

For checking whether you are on the road or not have a look here: https://github.com/bark-simulator/bark/blob/master/bark/world/evaluation/evaluator_drivable_area.hpp

Evaluators in BARK are called at every time-step to evaluate certain criteria, such as whether the agent is on the road or not.

patrickhart commented 3 years ago

additionally, the LaneCorridor returns you the line strings of the lane, see here: https://github.com/bark-simulator/bark/blob/7ba226af803127adcf6f4f3fc6e1c49cecde6a33/bark/world/map/lane_corridor.hpp#L36

then you can use the Distance function as mentioned by @klemense1

tinmodeHuang commented 3 years ago

first of all, thanks for the advice. However, if do it as you say, it seems that I need to identify which linestring is edges of the road. the last modification as shown below:

double Agent::GetDistance2RoadEdge() const {
  double tmp;
  double distance = std::numeric_limits<double>::max();
  Polygon agent_poly = GetPolygonFromState(GetCurrentState());
  for (auto const& point : boost::make_iterator_range(
           boost::geometry::exterior_ring(road_corridor_->GetPolygon().obj_))) {
             tmp = Distance(agent_poly, point);
             distance = tmp < distance ?  tmp : distance;
           }
  return distance;
}

type of the member variable .obj_ of road_corridor_->GetPolygon()just meets the requirement of boost::geometry::exterior_ring()to parameter. it seems that the calculated distance can exactly represents the distance between the roadedge and the ego agent. could you check if the snippet above does it?

patrickhart commented 3 years ago

first of all, thanks for the advice. However, if do it as you say, it seems that I need to identify which linestring is edges of the road.

No, this is done automatically by the map_interace as it returns always the, e.g., left or right lane from the current LaneCorridor.

the last modification as shown below:

double Agent::GetDistance2RoadEdge() const {
  double tmp;
  double distance = std::numeric_limits<double>::max();
  Polygon agent_poly = GetPolygonFromState(GetCurrentState());
  for (auto const& point : boost::make_iterator_range(
           boost::geometry::exterior_ring(road_corridor_->GetPolygon().obj_))) {
             tmp = Distance(agent_poly, point);
             distance = tmp < distance ?  tmp : distance;
           }
  return distance;
}

type of the member variable .obj_ of road_corridor_->GetPolygon()just meets the requirement of boost::geometry::exterior_ring()to parameter. it seems that the calculated distance can exactly represents the distance between the roadedge and the ego agent. could you check if the snippet above does it?

This could potentially also return die distance to the front since it is a closed polygon. So it does not purely provide the distance to the road edges/lines.

tinmodeHuang commented 3 years ago

you're right, it have also been taken into consideration. though all vehicles spawn at those places far from the ends of roadcorridor most of the time, there is little risk so long as other agents, even the exterior controlled one, don't take the distance as input. Moreover, the ego agent always spawn among the others. by the way, if the left lanestring from the current LaneCorridor is always returned, how to identify if that is the left boundary, the right one or even the middle lane markings from the current road. whether or not there is the easy way to get the identifier of lanes if lanes are arranged in some kind of order.

patrickhart commented 3 years ago

There are interfaces available in the lanecorridor that determine this based on the a graph based map representation (the RoadGraph)

tinmodeHuang commented 3 years ago

I'll have a try in the future.