compute turn penalties in lua profiles
This commit is contained in:
parent
53af4ee39f
commit
f9abfbf68a
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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 |
|
||||||
|
33
features/bicycle/turn_penalty.feature
Normal file
33
features/bicycle/turn_penalty.feature
Normal 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 |
|
@ -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
8
profiles/turnbot.lua
Normal 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
|
Loading…
Reference in New Issue
Block a user