Skip to content

Commit

Permalink
improving error messages, subscriptions with parameters, refs #2, #1099
Browse files Browse the repository at this point in the history
git-svn-id: file:///home/behr_mi/git/sumo_synched/trunk@15304 afbd958f-9f77-42d5-a016-97a22340ccf4
  • Loading branch information
behrisch committed Dec 10, 2013
1 parent 3b27c27 commit 135e9b4
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 60 deletions.
61 changes: 25 additions & 36 deletions sumo/src/traci-server/TraCIServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ TraCIServer::TraCIServer(const SUMOTime begin, const int port)
myExecutors[CMD_GET_SIM_VARIABLE] = &TraCIServerAPI_Simulation::processGet;
myExecutors[CMD_SET_SIM_VARIABLE] = &TraCIServerAPI_Simulation::processSet;

myParameterSizes[VAR_LEADER] = 9;

myDoCloseConnection = false;

// display warning if internal lanes are not used
Expand Down Expand Up @@ -452,7 +454,7 @@ TraCIServer::dispatchCommand() {
case CMD_SUBSCRIBE_EDGE_VARIABLE:
case CMD_SUBSCRIBE_SIM_VARIABLE:
case CMD_SUBSCRIBE_GUI_VARIABLE:
success = addObjectVariableSubscription(commandId);
success = addObjectVariableSubscription(commandId, false);
break;
case CMD_SUBSCRIBE_INDUCTIONLOOP_CONTEXT:
case CMD_SUBSCRIBE_MULTI_ENTRY_EXIT_DETECTOR_CONTEXT:
Expand All @@ -467,7 +469,7 @@ TraCIServer::dispatchCommand() {
case CMD_SUBSCRIBE_EDGE_CONTEXT:
case CMD_SUBSCRIBE_SIM_CONTEXT:
case CMD_SUBSCRIBE_GUI_CONTEXT:
success = addObjectContextSubscription(commandId);
success = addObjectVariableSubscription(commandId, true);
break;
default:
writeStatusCmd(commandId, RTYPE_NOTIMPLEMENTED, "Command not implemented in sumo");
Expand Down Expand Up @@ -567,9 +569,9 @@ TraCIServer::writeStatusCmd(int commandId, int status, const std::string& descri
void
TraCIServer::writeStatusCmd(int commandId, int status, const std::string& description, tcpip::Storage& outputStorage) {
if (status == RTYPE_ERR) {
WRITE_ERROR("Answered with error to command " + toString(commandId) + ": " + description);
WRITE_ERROR("Answered with error to command " + toHex(commandId, 2) + ": " + description);
} else if (status == RTYPE_NOTIMPLEMENTED) {
WRITE_ERROR("Requested command not implemented (" + toString(commandId) + "): " + description);
WRITE_ERROR("Requested command not implemented (" + toHex(commandId, 2) + "): " + description);
}
outputStorage.writeUnsignedByte(1 + 1 + 1 + 4 + static_cast<int>(description.length())); // command length
outputStorage.writeUnsignedByte(commandId); // command type
Expand Down Expand Up @@ -761,10 +763,12 @@ TraCIServer::processSingleSubscription(const Subscription& s, tcpip::Storage& wr
outputStorage.writeString(*j);
}
if (numVars > 0) {
for (std::vector<int>::const_iterator i = s.variables.begin(); i != s.variables.end(); ++i) {
std::vector<std::vector<unsigned char> >::const_iterator k = s.parameters.begin();
for (std::vector<int>::const_iterator i = s.variables.begin(); i != s.variables.end(); ++i, ++k) {
tcpip::Storage message;
message.writeUnsignedByte(*i);
message.writeString(*j);
message.writePacket(*k);
tcpip::Storage tmpOutput;
if (myExecutors.find(getCommandId) != myExecutors.end()) {
ok &= myExecutors[getCommandId](*this, message, tmpOutput);
Expand Down Expand Up @@ -834,45 +838,30 @@ TraCIServer::processSingleSubscription(const Subscription& s, tcpip::Storage& wr


bool
TraCIServer::addObjectVariableSubscription(int commandId) {
SUMOTime beginTime = myInputStorage.readInt();
SUMOTime endTime = myInputStorage.readInt();
std::string id = myInputStorage.readString();
int no = myInputStorage.readUnsignedByte();
TraCIServer::addObjectVariableSubscription(const int commandId, const bool hasContext) {
const SUMOTime beginTime = myInputStorage.readInt();
const SUMOTime endTime = myInputStorage.readInt();
const std::string id = myInputStorage.readString();
const int domain = hasContext ? myInputStorage.readUnsignedByte() : 0;
const SUMOReal range = hasContext ? myInputStorage.readDouble() : 0.;
const int num = myInputStorage.readUnsignedByte();
std::vector<int> variables;
for (int i = 0; i < no; ++i) {
variables.push_back(myInputStorage.readUnsignedByte());
std::vector<std::vector<unsigned char> > parameters;
for (int i = 0; i < num; ++i) {
const int varID = myInputStorage.readUnsignedByte();
variables.push_back(varID);
parameters.push_back(std::vector<unsigned char>());
for (int j = 0; j < myParameterSizes[varID]; j++) {
parameters.back().push_back(myInputStorage.readChar());
}
}
// check subscribe/unsubscribe
if (variables.size() == 0) {
removeSubscription(commandId, id, -1);
return true;
}
// process subscription
Subscription s(commandId, id, variables, beginTime, endTime, false, 0, 0);
initialiseSubscription(s);
return true;
}


bool
TraCIServer::addObjectContextSubscription(int commandId) {
SUMOTime beginTime = myInputStorage.readInt();
SUMOTime endTime = myInputStorage.readInt();
std::string id = myInputStorage.readString();
int domain = myInputStorage.readUnsignedByte();
SUMOReal range = myInputStorage.readDouble();
int no = myInputStorage.readUnsignedByte();
std::vector<int> variables;
for (int i = 0; i < no; ++i) {
variables.push_back(myInputStorage.readUnsignedByte());
}
// check subscribe/unsubscribe
if (variables.size() == 0) {
removeSubscription(commandId, id, -1);
return true;
}
Subscription s(commandId, id, variables, beginTime, endTime, true, domain, range);
Subscription s(commandId, id, variables, parameters, beginTime, endTime, hasContext, domain, range);
initialiseSubscription(s);
return true;
}
Expand Down
13 changes: 9 additions & 4 deletions sumo/src/traci-server/TraCIServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ class TraCIServer : public MSNet::VehicleStateListener {
/// @brief Map of commandIds -> their executors; applicable if the executor applies to the method footprint
std::map<int, CmdExecutor> myExecutors;

/// @brief Map of variable ids to the size of the parameter in bytes
std::map<int, int> myParameterSizes;

std::map<std::string, MSVehicle*> myVTDControlledVehicles;


Expand All @@ -343,9 +346,10 @@ class TraCIServer : public MSNet::VehicleStateListener {
* @param[in] contextDomainArg The domain ID of the context
* @param[in] rangeArg The range of the context
*/
Subscription(int commandIdArg, const std::string& idArg, const std::vector<int>& variablesArg,
Subscription(int commandIdArg, const std::string& idArg,
const std::vector<int>& variablesArg, const std::vector<std::vector<unsigned char> >& paramsArg,
SUMOTime beginTimeArg, SUMOTime endTimeArg, bool contextVarsArg, int contextDomainArg, SUMOReal rangeArg)
: commandId(commandIdArg), id(idArg), variables(variablesArg), beginTime(beginTimeArg), endTime(endTimeArg),
: commandId(commandIdArg), id(idArg), variables(variablesArg), parameters(paramsArg), beginTime(beginTimeArg), endTime(endTimeArg),
contextVars(contextVarsArg), contextDomain(contextDomainArg), range(rangeArg) {}

/// @brief commandIdArg The command id of the subscription
Expand All @@ -354,6 +358,8 @@ class TraCIServer : public MSNet::VehicleStateListener {
std::string id;
/// @brief The subscribed variables
std::vector<int> variables;
/// @brief The parameters for the subscribed variables
std::vector<std::vector<unsigned char> > parameters;
/// @brief The begin time of the subscription
SUMOTime beginTime;
/// @brief The end time of the subscription
Expand Down Expand Up @@ -381,8 +387,7 @@ class TraCIServer : public MSNet::VehicleStateListener {


private:
bool addObjectVariableSubscription(int commandId);
bool addObjectContextSubscription(int commandId);
bool addObjectVariableSubscription(const int commandId, const bool hasContext);
void initialiseSubscription(const Subscription& s);
void removeSubscription(int commandId, const std::string& identity, int domain);
bool processSingleSubscription(const TraCIServer::Subscription& s, tcpip::Storage& writeInto,
Expand Down
9 changes: 9 additions & 0 deletions sumo/src/utils/common/ToString.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ inline std::string toString(const T& t, std::streamsize accuracy = OUTPUT_ACCURA
}


template<typename T>
inline std::string toHex(const T i, std::streamsize numDigits=0) {
// taken from http://stackoverflow.com/questions/5100718/int-to-hex-string-in-c
std::stringstream stream;
stream << "0x" << std::setfill ('0') << std::setw(numDigits == 0 ? sizeof(T)*2 : numDigits) << std::hex << i;
return stream.str();
}


template <>
inline std::string toString<SumoXMLTag>(const SumoXMLTag& tag, std::streamsize accuracy) {
UNUSED_PARAMETER(accuracy);
Expand Down
30 changes: 12 additions & 18 deletions sumo/src/utils/xml/SUMOSAXAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,10 @@ void
SUMOSAXAttributes::emitUngivenError(const std::string& attrname, const char* objectid) const {
std::ostringstream oss;
oss << "Attribute '" << attrname << "' is missing in definition of ";
if (objectid == 0) {
oss << "a ";
}
oss << myObjectType;
if (objectid != 0) {
oss << " '" << objectid << "'";
if (objectid == 0 || objectid[0] == 0) {
oss << "a " << myObjectType;
} else {
oss << myObjectType << " '" << objectid << "'";
}
oss << ".";
WRITE_ERROR(oss.str());
Expand All @@ -138,12 +136,10 @@ void
SUMOSAXAttributes::emitEmptyError(const std::string& attrname, const char* objectid) const {
std::ostringstream oss;
oss << "Attribute '" << attrname << "' in definition of ";
if (objectid == 0) {
oss << "a ";
}
oss << myObjectType;
if (objectid != 0) {
oss << " '" << objectid << "'";
if (objectid == 0 || objectid[0] == 0) {
oss << "a " << myObjectType;
} else {
oss << myObjectType << " '" << objectid << "'";
}
oss << " is empty.";
WRITE_ERROR(oss.str());
Expand All @@ -154,12 +150,10 @@ void
SUMOSAXAttributes::emitFormatError(const std::string& attrname, const std::string& type, const char* objectid) const {
std::ostringstream oss;
oss << "Attribute '" << attrname << "' in definition of ";
if (objectid == 0) {
oss << "a ";
}
oss << myObjectType;
if (objectid != 0) {
oss << " '" << objectid << "'";
if (objectid == 0 || objectid[0] == 0) {
oss << "a " << myObjectType;
} else {
oss << myObjectType << " '" << objectid << "'";
}
oss << " is not " << type << ".";
WRITE_ERROR(oss.str());
Expand Down
10 changes: 8 additions & 2 deletions sumo/tools/traci/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,17 +338,23 @@ def _readSubscription(result):
raise FatalTraCIError("Cannot handle subscription response %02x for %s." % (response, objectID))
return objectID, response

def _subscribe(cmdID, begin, end, objID, varIDs):
def _subscribe(cmdID, begin, end, objID, varIDs, parameters=None):
_message.queue.append(cmdID)
length = 1+1+4+4+4+len(objID)+1+len(varIDs)
if length<=255:
if parameters:
for v in varIDs:
if v in parameters:
length += len(parameters[v])
if length <= 255:
_message.string += struct.pack("!B", length)
else:
_message.string += struct.pack("!Bi", 0, length+4)
_message.string += struct.pack("!Biii", cmdID, begin, end, len(objID)) + objID
_message.string += struct.pack("!B", len(varIDs))
for v in varIDs:
_message.string += struct.pack("!B", v)
if parameters and v in parameters:
_message.string += parameters[v]
result = _sendExact()
objectID, response = _readSubscription(result)
if response - cmdID != 16 or objectID != objID:
Expand Down
10 changes: 10 additions & 0 deletions sumo/tools/traci/vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,21 @@ def getLeader(vehID, dist=0.):
"""getLeader(string, double) -> (string, double)
Return the leading vehicle id together with the distance.
The dist parameter defines the maximum lookahead, 0 calculates a lookahead from the brake gap.
"""
traci._beginMessage(tc.CMD_GET_VEHICLE_VARIABLE, tc.VAR_LEADER, vehID, 1+8)
traci._message.string += struct.pack("!Bd", tc.TYPE_DOUBLE, dist)
return _readLeader(traci._checkResult(tc.CMD_GET_VEHICLE_VARIABLE, tc.VAR_LEADER, vehID))

def subscribeLeader(vehID, dist=0., begin=0, end=2**31-1):
"""subscribeLeader(string, double) -> None
Subscribe for the leading vehicle id together with the distance.
The dist parameter defines the maximum lookahead, 0 calculates a lookahead from the brake gap.
"""
traci._subscribe(tc.CMD_SUBSCRIBE_VEHICLE_VARIABLE, begin, end, vehID,
(tc.VAR_LEADER,), {tc.VAR_LEADER: struct.pack("!Bd", tc.TYPE_DOUBLE, dist)})

def getDrivingDistance(vehID, edgeID, pos, laneID=0):
"""getDrivingDistance(string, string, double, integer) -> double
Expand Down

0 comments on commit 135e9b4

Please sign in to comment.