Path: blob/main/src/traci-server/TraCIServerAPI_Person.cpp
169665 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file TraCIServerAPI_Person.cpp14/// @author Daniel Krajzewicz15/// @date 26.05.201416///17// APIs for getting/setting person values via TraCI18/****************************************************************************/19#include <config.h>2021#include <utils/common/StringTokenizer.h>22#include <microsim/transportables/MSTransportableControl.h>23#include <microsim/MSVehicleControl.h>24#include <microsim/transportables/MSPerson.h>25#include <microsim/MSNet.h>26#include <microsim/MSEdge.h>27#include <libsumo/Person.h>28#include <libsumo/StorageHelper.h>29#include <libsumo/TraCIConstants.h>30#include <libsumo/VehicleType.h>31#include "TraCIServer.h"32#include "TraCIServerAPI_VehicleType.h"33#include "TraCIServerAPI_Person.h"34#include "TraCIServerAPI_Simulation.h"353637// ===========================================================================38// method definitions39// ===========================================================================40bool41TraCIServerAPI_Person::processGet(TraCIServer& server, tcpip::Storage& inputStorage,42tcpip::Storage& outputStorage) {43const int variable = inputStorage.readUnsignedByte();44const std::string id = inputStorage.readString();45server.initWrapper(libsumo::RESPONSE_GET_PERSON_VARIABLE, variable, id);46try {47if (!libsumo::Person::handleVariable(id, variable, &server, &inputStorage)) {48return server.writeErrorStatusCmd(libsumo::CMD_GET_PERSON_VARIABLE, "Get Person Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);49}50} catch (libsumo::TraCIException& e) {51return server.writeErrorStatusCmd(libsumo::CMD_GET_PERSON_VARIABLE, e.what(), outputStorage);52}53server.writeStatusCmd(libsumo::CMD_GET_PERSON_VARIABLE, libsumo::RTYPE_OK, "", outputStorage);54server.writeResponseWithLength(outputStorage, server.getWrapperStorage());55return true;56}575859bool60TraCIServerAPI_Person::processSet(TraCIServer& server, tcpip::Storage& inputStorage,61tcpip::Storage& outputStorage) {62std::string warning = ""; // additional description for response63// variable64int variable = inputStorage.readUnsignedByte();65if (variable != libsumo::VAR_PARAMETER66&& variable != libsumo::ADD67&& variable != libsumo::REMOVE68&& variable != libsumo::APPEND_STAGE69&& variable != libsumo::REPLACE_STAGE70&& variable != libsumo::REMOVE_STAGE71&& variable != libsumo::CMD_REROUTE_TRAVELTIME72&& variable != libsumo::VAR_MOVE_TO73&& variable != libsumo::MOVE_TO_XY74&& variable != libsumo::VAR_SPEED75&& variable != libsumo::VAR_TYPE76&& variable != libsumo::VAR_SPEED_FACTOR77&& variable != libsumo::VAR_LENGTH78&& variable != libsumo::VAR_WIDTH79&& variable != libsumo::VAR_HEIGHT80&& variable != libsumo::VAR_MINGAP81&& variable != libsumo::VAR_COLOR82) {83return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Change Person State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);84}8586try {87// TODO: remove declaration of c after completion88MSTransportableControl& c = MSNet::getInstance()->getPersonControl();89// id90std::string id = inputStorage.readString();91// TODO: remove declaration of p after completion92const bool shouldExist = variable != libsumo::ADD;93MSTransportable* p = c.get(id);94if (p == nullptr && shouldExist) {95return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Person '" + id + "' is not known", outputStorage);96}97// process98switch (variable) {99case libsumo::VAR_SPEED: {100double speed = 0;101if (!server.readTypeCheckingDouble(inputStorage, speed)) {102return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Setting speed requires a double.", outputStorage);103}104// set the speed for all present and future (walking) stages and modify the vType so that stages added later are also affected105libsumo::Person::setSpeed(id, speed);106}107break;108case libsumo::VAR_TYPE: {109std::string vTypeID;110if (!server.readTypeCheckingString(inputStorage, vTypeID)) {111return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The vehicle type id must be given as a string.", outputStorage);112}113libsumo::Person::setType(id, vTypeID);114break;115}116case libsumo::VAR_SPEED_FACTOR: {117double speedfactor = 0;118if (!server.readTypeCheckingDouble(inputStorage, speedfactor)) {119return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Setting SpeedFactor requires a double.", outputStorage);120}121libsumo::Person::setSpeedFactor(id, speedfactor);122}123break;124case libsumo::VAR_COLOR: {125libsumo::TraCIColor col;126if (!server.readTypeCheckingColor(inputStorage, col)) {127return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The color must be given using the according type.", outputStorage);128}129libsumo::Person::setColor(id, col);130break;131}132case libsumo::ADD: {133if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {134return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Adding a person requires a compound object.", outputStorage);135}136if (inputStorage.readInt() != 4) {137return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Adding a person needs four parameters.", outputStorage);138}139std::string vTypeID;140if (!server.readTypeCheckingString(inputStorage, vTypeID)) {141return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "First parameter (type) requires a string.", outputStorage);142}143std::string edgeID;144if (!server.readTypeCheckingString(inputStorage, edgeID)) {145return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Second parameter (edge) requires a string.", outputStorage);146}147double depart;148if (!server.readTypeCheckingDouble(inputStorage, depart)) {149return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Third parameter (depart) requires a double.", outputStorage);150}151double pos;152if (!server.readTypeCheckingDouble(inputStorage, pos)) {153return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Fourth parameter (position) requires a double.", outputStorage);154}155libsumo::Person::add(id, edgeID, pos, depart, vTypeID);156}157break;158case libsumo::REMOVE: {159int why = 0;160if (!server.readTypeCheckingByte(inputStorage, why)) {161return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Removing a person requires a byte.", outputStorage);162}163libsumo::Person::remove(id, (char)why);164}165break;166case libsumo::APPEND_STAGE: {167if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {168return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Adding a person stage requires a compound object.", outputStorage);169}170int numParameters = inputStorage.readInt();171if (numParameters == 13) {172libsumo::TraCIStage stage;173libsumo::StorageHelper::readStage(inputStorage, stage);174libsumo::Person::appendStage(id, stage);175} else {176const int stageType = StoHelp::readTypedInt(inputStorage, "The first parameter for adding a stage must be the stage type given as int.");177if (stageType == libsumo::STAGE_DRIVING) {178// append driving stage179if (numParameters != 4) {180return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Adding a driving stage needs four parameters.", outputStorage);181}182std::string edgeID;183if (!server.readTypeCheckingString(inputStorage, edgeID)) {184return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Second parameter (edge) requires a string.", outputStorage);185}186std::string lines;187if (!server.readTypeCheckingString(inputStorage, lines)) {188return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Third parameter (lines) requires a string.", outputStorage);189}190std::string stopID;191if (!server.readTypeCheckingString(inputStorage, stopID)) {192return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Fourth parameter (stopID) requires a string.", outputStorage);193}194libsumo::Person::appendDrivingStage(id, edgeID, lines, stopID);195} else if (stageType == libsumo::STAGE_WAITING) {196// append waiting stage197if (numParameters != 4) {198return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Adding a waiting stage needs four parameters.", outputStorage);199}200double duration;201if (!server.readTypeCheckingDouble(inputStorage, duration)) {202return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Second parameter (duration) requires a double.", outputStorage);203}204std::string description;205if (!server.readTypeCheckingString(inputStorage, description)) {206return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Third parameter (description) requires a string.", outputStorage);207}208std::string stopID;209if (!server.readTypeCheckingString(inputStorage, stopID)) {210return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Fourth parameter (stopID) requires a string.", outputStorage);211}212libsumo::Person::appendWaitingStage(id, duration, description, stopID);213} else if (stageType == libsumo::STAGE_WALKING) {214// append walking stage215if (numParameters != 6) {216return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Adding a walking stage needs six parameters.", outputStorage);217}218std::vector<std::string> edgeIDs;219if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {220return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Second parameter (edges) route must be defined as a list of edge ids.", outputStorage);221}222double arrivalPos;223if (!server.readTypeCheckingDouble(inputStorage, arrivalPos)) {224return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Third parameter (arrivalPos) requires a double.", outputStorage);225}226double duration;227if (!server.readTypeCheckingDouble(inputStorage, duration)) {228return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Fourth parameter (duration) requires a double.", outputStorage);229}230double speed;231if (!server.readTypeCheckingDouble(inputStorage, speed)) {232return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Fifth parameter (speed) requires a double.", outputStorage);233}234std::string stopID;235if (!server.readTypeCheckingString(inputStorage, stopID)) {236return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Fourth parameter (stopID) requires a string.", outputStorage);237}238libsumo::Person::appendWalkingStage(id, edgeIDs, arrivalPos, duration, speed, stopID);239} else {240return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Invalid stage type for person '" + id + "'", outputStorage);241}242}243244}245break;246247case libsumo::REPLACE_STAGE : {248if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {249return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Replacing a person stage requires a compound object.", outputStorage);250}251if (inputStorage.readInt() != 2) {252return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Replacing a person stage requires a compound object of size 2.", outputStorage);253}254const int nextStageIndex = StoHelp::readTypedInt(inputStorage, "First parameter of replace stage should be an integer");255if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {256return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Second parameter of replace stage should be a compound object", outputStorage);257}258if (inputStorage.readInt() != 13) {259return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Second parameter of replace stage should be a compound object of size 13", outputStorage);260}261libsumo::TraCIStage stage;262libsumo::StorageHelper::readStage(inputStorage, stage);263libsumo::Person::replaceStage(id, nextStageIndex, stage);264}265break;266267case libsumo::REMOVE_STAGE: {268const int nextStageIndex = StoHelp::readTypedInt(inputStorage, "The message must contain the stage index.");269libsumo::Person::removeStage(id, nextStageIndex);270}271break;272case libsumo::CMD_REROUTE_TRAVELTIME: {273if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {274return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Rerouting requires a compound object.", outputStorage);275}276if (inputStorage.readInt() != 0) {277return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);278}279libsumo::Person::rerouteTraveltime(id);280}281break;282case libsumo::VAR_MOVE_TO: {283if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {284return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Setting position requires a compound object.", outputStorage);285}286const int numArgs = inputStorage.readInt();287if (numArgs != 3) {288return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "Setting position should obtain the edge id, the position and the lateral position.", outputStorage);289}290std::string laneID;291if (!server.readTypeCheckingString(inputStorage, laneID)) {292return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The first parameter for setting a position must be the laneID given as a string.", outputStorage);293}294double position = 0;295if (!server.readTypeCheckingDouble(inputStorage, position)) {296return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The second parameter for setting a position must be the position given as a double.", outputStorage);297}298double posLat = 0;299if (!server.readTypeCheckingDouble(inputStorage, posLat)) {300return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The third parameter for setting a position must be the lateral position given as a double.", outputStorage);301}302// process303libsumo::Person::moveTo(id, laneID, position, posLat);304}305break;306case libsumo::MOVE_TO_XY: {307if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {308return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "MoveToXY person requires a compound object.", outputStorage);309}310const int numArgs = inputStorage.readInt();311if (numArgs != 5 && numArgs != 6) {312return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "MoveToXY person should obtain: edgeID, x, y, angle, keepRouteFlag and optionally matchThreshold.", outputStorage);313}314// edge ID315std::string edgeID;316if (!server.readTypeCheckingString(inputStorage, edgeID)) {317return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The first parameter for moveToXY must be the edge ID given as a string.", outputStorage);318}319// x320double x = 0;321if (!server.readTypeCheckingDouble(inputStorage, x)) {322return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The second parameter for moveToXY must be the x-position given as a double.", outputStorage);323}324// y325double y = 0;326if (!server.readTypeCheckingDouble(inputStorage, y)) {327return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The third parameter for moveToXY must be the y-position given as a double.", outputStorage);328}329// angle330double angle = 0;331if (!server.readTypeCheckingDouble(inputStorage, angle)) {332return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The fourth parameter for moveToXY must be the angle given as a double.", outputStorage);333}334int keepRouteFlag = 1;335if (!server.readTypeCheckingByte(inputStorage, keepRouteFlag)) {336return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The fifth parameter for moveToXY must be the keepRouteFlag given as a byte.", outputStorage);337}338double matchThreshold = 100;339if (numArgs == 6) {340if (!server.readTypeCheckingDouble(inputStorage, matchThreshold)) {341return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The sixth parameter for moveToXY must be the matchThreshold given as a double.", outputStorage);342}343}344libsumo::Person::moveToXY(id, edgeID, x, y, angle, keepRouteFlag, matchThreshold);345}346break;347case libsumo::VAR_PARAMETER: {348if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {349return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);350}351//read itemNo352inputStorage.readInt();353std::string name;354if (!server.readTypeCheckingString(inputStorage, name)) {355return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);356}357std::string value;358if (!server.readTypeCheckingString(inputStorage, value)) {359return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);360}361libsumo::Person::setParameter(id, name, value);362}363break;364default:365try {366if (!TraCIServerAPI_VehicleType::setVariable(libsumo::CMD_SET_PERSON_VARIABLE, variable, p->getSingularType().getID(), server, inputStorage, outputStorage)) {367return false;368}369} catch (ProcessError& e) {370return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, e.what(), outputStorage);371}372break;373}374} catch (libsumo::TraCIException& e) {375return server.writeErrorStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, e.what(), outputStorage);376}377server.writeStatusCmd(libsumo::CMD_SET_PERSON_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);378return true;379}380381382/****************************************************************************/383384385