compute turn penalties in lua profiles

This commit is contained in:
Emil Tin 2013-02-23 08:33:33 +01:00 committed by DennisOSRM
parent 53af4ee39f
commit f9abfbf68a
7 changed files with 95 additions and 15 deletions

View File

@ -150,7 +150,7 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
edgeBasedNodes.push_back(currentNode); edgeBasedNodes.push_back(currentNode);
} }
void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) { void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State *myLuaState) {
Percent p(_nodeBasedGraph->GetNumberOfNodes()); Percent p(_nodeBasedGraph->GetNumberOfNodes());
int numberOfSkippedTurns(0); int numberOfSkippedTurns(0);
int nodeBasedEdgeCounter(0); int nodeBasedEdgeCounter(0);
@ -273,14 +273,15 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
if(_trafficLights.find(v) != _trafficLights.end()) { if(_trafficLights.find(v) != _trafficLights.end()) {
distance += speedProfile.trafficSignalPenalty; distance += speedProfile.trafficSignalPenalty;
} }
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w); unsigned penalty = 0;
if(TurnInstructions.UTurn == turnInstruction) { TurnInstruction turnInstruction = AnalyzeTurn(u, v, w, penalty, myLuaState);
if(turnInstruction == TurnInstructions.UTurn)
distance += speedProfile.uTurnPenalty; distance += speedProfile.uTurnPenalty;
}
// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) { // if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
// distance += TurnInstructions.AccessRestrictionPenalty; // distance += TurnInstructions.AccessRestrictionPenalty;
// turnInstruction |= TurnInstructions.AccessRestrictionFlag; // turnInstruction |= TurnInstructions.AccessRestrictionFlag;
// } // }
distance += penalty;
//distance += heightPenalty; //distance += heightPenalty;
@ -325,7 +326,21 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
INFO("Generated " << edgeBasedNodes.size() << " edge based nodes"); INFO("Generated " << edgeBasedNodes.size() << " edge based nodes");
} }
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const { TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, unsigned& penalty, lua_State *myLuaState) const {
double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
if( speedProfile.has_turn_function ) {
try {
//call lua profile to compute turn penalty
penalty = luabind::call_function<int>( myLuaState, "turn_function", 180-angle );
} catch (const luabind::error &er) {
std::cerr << er.what() << std::endl;
//TODO handle lua errors
}
} else {
penalty = 0;
}
if(u == w) { if(u == w) {
return TurnInstructions.UTurn; return TurnInstructions.UTurn;
} }
@ -371,7 +386,6 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID
return TurnInstructions.NoTurn; return TurnInstructions.NoTurn;
} }
double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
return TurnInstructions.GetTurnDirectionOfInstruction(angle); return TurnInstructions.GetTurnDirectionOfInstruction(angle);
} }

View File

@ -50,6 +50,14 @@
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/BaseConfiguration.h" #include "../Util/BaseConfiguration.h"
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <luabind/luabind.hpp>
class EdgeBasedGraphFactory : boost::noncopyable { class EdgeBasedGraphFactory : boost::noncopyable {
public: public:
struct EdgeBasedNode { struct EdgeBasedNode {
@ -71,9 +79,10 @@ public:
}; };
struct SpeedProfileProperties{ struct SpeedProfileProperties{
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0) {} SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0), has_turn_function(false) {}
int trafficSignalPenalty; int trafficSignalPenalty;
int uTurnPenalty; int uTurnPenalty;
bool has_turn_function;
} speedProfile; } speedProfile;
private: private:
@ -133,10 +142,11 @@ public:
template< class InputEdgeT > template< class InputEdgeT >
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, SpeedProfileProperties speedProfile); explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, SpeedProfileProperties speedProfile);
void Run(const char * originalEdgeDataFilename); void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges ); void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( DeallocatingVector< EdgeBasedNode> & nodes); void GetEdgeBasedNodes( DeallocatingVector< EdgeBasedNode> & nodes);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const; void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, unsigned& penalty, lua_State *myLuaState) const;
unsigned GetNumberOfNodes() const; unsigned GetNumberOfNodes() const;
}; };

View File

@ -134,6 +134,9 @@ int main (int argc, char *argv[]) {
} }
speedProfile.uTurnPenalty = 10*lua_tointeger(myLuaState, -1); speedProfile.uTurnPenalty = 10*lua_tointeger(myLuaState, -1);
speedProfile.has_turn_function = lua_function_exists( myLuaState, "turn_function" );
std::vector<ImportEdge> edgeList;
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions); NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
in.close(); in.close();
INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights"); INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights");
@ -148,7 +151,7 @@ int main (int argc, char *argv[]) {
INFO("Generating edge-expanded graph representation"); INFO("Generating edge-expanded graph representation");
EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping, speedProfile); EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping, speedProfile);
std::vector<ImportEdge>().swap(edgeList); std::vector<ImportEdge>().swap(edgeList);
edgeBasedGraphFactory->Run(edgeOut.c_str()); edgeBasedGraphFactory->Run(edgeOut.c_str(), myLuaState);
std::vector<_Restriction>().swap(inputRestrictions); std::vector<_Restriction>().swap(inputRestrictions);
std::vector<NodeID>().swap(bollardNodes); std::vector<NodeID>().swap(bollardNodes);
std::vector<NodeID>().swap(trafficLightNodes); std::vector<NodeID>().swap(trafficLightNodes);

View File

@ -59,5 +59,5 @@ Feature: Bike - Handle ferry routes
When I route I should get When I route I should get
| from | to | route | time | | from | to | route | time |
| a | d | abcd | 3600s +-1 | | a | d | abcd | 3600s +-10 |
| d | a | abcd | 3600s +-1 | | d | a | abcd | 3600s +-10 |

View File

@ -0,0 +1,33 @@
@routing @bicycle @turn_penalty
Feature: Turn Penalties
Background:
Given the profile "turnbot"
Scenario: Bike - turns should incur a delay that depend on the angle
Given the node map
| c | d | e |
| b | j | f |
| a | s | g |
And the ways
| nodes |
| sj |
| ja |
| jb |
| jc |
| jd |
| je |
| jf |
| jg |
When I route I should get
| from | to | route | time | distance |
| s | a | sj,ja | 39s +-1 | 242m +-1 |
| s | b | sj,jb | 30s +-1 | 200m +-1 |
| s | c | sj,jc | 29s +-1 | 242m +-1 |
| s | d | sj,jd | 20s +-1 | 200m +-1 |
| s | e | sj,je | 29s +-1 | 242m +-1 |
| s | f | sj,jf | 30s +-1 | 200m +-1 |
| s | g | sj,jg | 39s +-1 | 242m +-1 |

View File

@ -73,6 +73,8 @@ ignore_areas = true -- future feature
traffic_signal_penalty = 5 traffic_signal_penalty = 5
u_turn_penalty = 20 u_turn_penalty = 20
use_turn_restrictions = false use_turn_restrictions = false
turn_penalty = 60
turn_bias = 1.4
-- End of globals -- End of globals
function get_exceptions(vector) function get_exceptions(vector)
@ -308,3 +310,13 @@ function way_function (way)
way.type = 1 way.type = 1
return 1 return 1
end end
function turn_function (angle)
-- compute turn penalty as angle^2, with a left/right bias
k = turn_penalty/(90.0*90.0)
if angle>=0 then
return angle*angle*k/turn_bias
else
return angle*angle*k*turn_bias
end
end

8
profiles/turnbot.lua Normal file
View File

@ -0,0 +1,8 @@
-- Testbot, with turn penalty
-- Used for testing turn penalties
require 'testbot'
function turn_function (angle)
return 200*math.abs(angle)/180 -- penalty
end