Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
libsumo/Lane.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2017-2023 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
23// C++ TraCI client API implementation
24/****************************************************************************/
25#include <config.h>
26
27#include <microsim/MSNet.h>
28#include <microsim/MSLane.h>
29#include <microsim/MSEdge.h>
30#include <microsim/MSVehicle.h>
31#include <microsim/MSLink.h>
34#include <libsumo/Helper.h>
36#include "Lane.h"
37
38
39namespace libsumo {
40// ===========================================================================
41// static member initializations
42// ===========================================================================
43SubscriptionResults Lane::mySubscriptionResults;
44ContextSubscriptionResults Lane::myContextSubscriptionResults;
45
46
47// ===========================================================================
48// static member definitions
49// ===========================================================================
50std::vector<std::string>
51Lane::getIDList() {
52 std::vector<std::string> ids;
54 return ids;
55}
56
57
58int
59Lane::getIDCount() {
60 return (int)getIDList().size();
61}
62
63
64std::string
65Lane::getEdgeID(const std::string& laneID) {
66 return getLane(laneID)->getEdge().getID();
67}
68
69
70double
71Lane::getLength(const std::string& laneID) {
72 return getLane(laneID)->getLength();
73}
74
75
76double
77Lane::getMaxSpeed(const std::string& laneID) {
78 return getLane(laneID)->getSpeedLimit();
79}
80
81double
82Lane::getFriction(const std::string& laneID) {
83 return getLane(laneID)->getFrictionCoefficient();
84}
85
86int
87Lane::getLinkNumber(const std::string& laneID) {
88 return (int)getLane(laneID)->getLinkCont().size();
89}
90
91
92std::vector<TraCIConnection>
93Lane::getLinks(const std::string& laneID) {
94 std::vector<TraCIConnection> v;
95 const MSLane* const lane = getLane(laneID);
97 for (const MSLink* const link : lane->getLinkCont()) {
98 const std::string approachedLane = link->getLane() != nullptr ? link->getLane()->getID() : "";
99 const bool hasPrio = link->havePriority();
100 const double speed = MIN2(lane->getSpeedLimit(), link->getLane()->getSpeedLimit());
101 const bool isOpen = link->opened(currTime, speed, speed, SUMOVTypeParameter::getDefault().length,
103 const bool hasFoe = link->hasApproachingFoe(currTime, currTime, 0, SUMOVTypeParameter::getDefaultDecel());
104 const std::string approachedInternal = link->getViaLane() != nullptr ? link->getViaLane()->getID() : "";
105 const std::string state = SUMOXMLDefinitions::LinkStates.getString(link->getState());
106 const std::string direction = SUMOXMLDefinitions::LinkDirections.getString(link->getDirection());
107 const double length = link->getLength();
108 v.push_back(TraCIConnection(approachedLane, hasPrio, isOpen, hasFoe, approachedInternal, state, direction, length));
109 }
110 return v;
111}
112
113
114std::vector<std::string>
115Lane::getAllowed(const std::string& laneID) {
116 SVCPermissions permissions = getLane(laneID)->getPermissions();
117 if (permissions == SVCAll) { // special case: write nothing
118 permissions = 0;
119 }
120 return getVehicleClassNamesList(permissions);
121}
122
123
124std::vector<std::string>
125Lane::getDisallowed(const std::string& laneID) {
126 return getVehicleClassNamesList(invertPermissions((getLane(laneID)->getPermissions()))); // negation yields disallowed
127}
128
129
130std::vector<std::string>
131Lane::getChangePermissions(const std::string& laneID, const int direction) {
132 if (direction == libsumo::LANECHANGE_LEFT) {
133 return getVehicleClassNamesList(getLane(laneID)->getChangeLeft());
134 } else if (direction == libsumo::LANECHANGE_RIGHT) {
135 return getVehicleClassNamesList(getLane(laneID)->getChangeRight());
136 } else {
137 throw TraCIException("Invalid direction for change permission (must be " + toString(libsumo::LANECHANGE_LEFT) + " or " + toString(libsumo::LANECHANGE_RIGHT));
138 }
139}
140
141
142TraCIPositionVector
143Lane::getShape(const std::string& laneID) {
144 TraCIPositionVector pv;
145 const PositionVector& shp = getLane(laneID)->getShape();
146 for (PositionVector::const_iterator pi = shp.begin(); pi != shp.end(); ++pi) {
147 TraCIPosition p;
148 p.x = pi->x();
149 p.y = pi->y();
150 p.z = pi->z();
151 pv.value.push_back(p);
152 }
153 return pv;
154}
155
156
157double
158Lane::getWidth(const std::string& laneID) {
159 return getLane(laneID)->getWidth();
160}
161
162
163double
164Lane::getCO2Emission(const std::string& laneID) {
165 return getLane(laneID)->getEmissions<PollutantsInterface::CO2>();
166}
167
168
169double
170Lane::getCOEmission(const std::string& laneID) {
171 return getLane(laneID)->getEmissions<PollutantsInterface::CO>();
172}
173
174
175double
176Lane::getHCEmission(const std::string& laneID) {
177 return getLane(laneID)->getEmissions<PollutantsInterface::HC>();
178}
179
180
181double
182Lane::getPMxEmission(const std::string& laneID) {
183 return getLane(laneID)->getEmissions<PollutantsInterface::PM_X>();
184}
185
186
187double
188Lane::getNOxEmission(const std::string& laneID) {
189 return getLane(laneID)->getEmissions<PollutantsInterface::NO_X>();
190}
191
192double
193Lane::getFuelConsumption(const std::string& laneID) {
194 return getLane(laneID)->getEmissions<PollutantsInterface::FUEL>();
195}
196
197
198double
199Lane::getNoiseEmission(const std::string& laneID) {
200 return getLane(laneID)->getHarmonoise_NoiseEmissions();
201}
202
203
204double
205Lane::getElectricityConsumption(const std::string& laneID) {
206 return getLane(laneID)->getEmissions<PollutantsInterface::ELEC>();
207}
208
209
210double
211Lane::getLastStepMeanSpeed(const std::string& laneID) {
212 return getLane(laneID)->getMeanSpeed();
213}
214
215
216double
217Lane::getLastStepOccupancy(const std::string& laneID) {
218 return getLane(laneID)->getNettoOccupancy();
219}
220
221
222double
223Lane::getLastStepLength(const std::string& laneID) {
224 const MSLane* lane = getLane(laneID);
225 double length = 0;
226 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
227 for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
228 length += (*j)->getVehicleType().getLength();
229 }
230 if (vehs.size() > 0) {
231 length = length / (double)vehs.size();
232 }
233 lane->releaseVehicles();
234 return length;
235}
236
237
238double
239Lane::getWaitingTime(const std::string& laneID) {
240 return getLane(laneID)->getWaitingSeconds();
241}
242
243
244double
245Lane::getTraveltime(const std::string& laneID) {
246 const MSLane* lane = getLane(laneID);
247 double meanSpeed = lane->getMeanSpeed();
248 if (meanSpeed != 0) {
249 return lane->getLength() / meanSpeed;
250 } else {
251 return 1000000.;
252 }
253}
254
255
256int
257Lane::getLastStepVehicleNumber(const std::string& laneID) {
258 return (int)getLane(laneID)->getVehicleNumber();
259}
260
261
262int
263Lane::getLastStepHaltingNumber(const std::string& laneID) {
264 const MSLane* lane = getLane(laneID);
265 int halting = 0;
266 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
267 for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
268 if ((*j)->getSpeed() < SUMO_const_haltingSpeed) {
269 ++halting;
270 }
271 }
272 lane->releaseVehicles();
273 return halting;
274}
275
276
277std::vector<std::string>
278Lane::getLastStepVehicleIDs(const std::string& laneID) {
279 const MSLane* lane = getLane(laneID);
280 std::vector<std::string> vehIDs;
281 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
282 for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
283 vehIDs.push_back((*j)->getID());
284 }
285 lane->releaseVehicles();
286 return vehIDs;
287}
288
289
290std::vector<std::string>
291Lane::getFoes(const std::string& laneID, const std::string& toLaneID) {
292 std::vector<std::string> foeIDs;
293 const MSLink* const link = getLane(laneID)->getLinkTo(getLane(toLaneID));
294 if (link == nullptr) {
295 throw TraCIException("No connection from lane '" + laneID + "' to lane '" + toLaneID + "'");
296 }
297 for (const MSLink* foe : link->getFoeLinks()) {
298 foeIDs.push_back(foe->getLaneBefore()->getID());
299 }
300 return foeIDs;
301}
302
303
304std::vector<std::string>
305Lane::getInternalFoes(const std::string& laneID) {
306 const MSLane* lane = getLane(laneID);
307 const std::vector<const MSLane*>* foeLanes;
308 std::vector<const MSLane*>::const_iterator it;
309 std::vector<std::string> foeIDs;
310
311 if ((lane->isInternal() || lane->isCrossing()) && lane->getLinkCont().size() > 0) {
312 MSLink* link = lane->getLinkCont().front();
313 foeLanes = &link->getFoeLanes();
314
315 for (it = foeLanes->begin(); foeLanes->end() != it; ++it) {
316 foeIDs.push_back((*it)->getID());
317 }
318 }
319 return foeIDs;
320}
321
322
323const std::vector<std::string>
324Lane::getPendingVehicles(const std::string& laneID) {
325 MSLane* const l = getLane(laneID); // validate laneID
326 std::vector<std::string> vehIDs;
328 if (veh->getLane() == l) {
329 vehIDs.push_back(veh->getID());
330 }
331 }
332 return vehIDs;
333}
334
335
336double
337Lane::getAngle(const std::string& laneID, double relativePosition) {
338 double angle;
339 MSLane* lane = getLane(laneID);
340 if (relativePosition == libsumo::INVALID_DOUBLE_VALUE) {
341 Position start = lane->getShape().front();
342 Position end = lane->getShape().back();
343 angle = start.angleTo2D(end);
344 } else {
345 angle = lane->getShape().rotationAtOffset(lane->interpolateLanePosToGeometryPos(relativePosition));
346 }
347
348 return GeomHelper::naviDegree(angle);
349}
350
351
352void
353Lane::setAllowed(const std::string& laneID, std::string allowedClass) {
354 setAllowed(laneID, std::vector<std::string>({allowedClass}));
355}
356
357
358void
359Lane::setAllowed(const std::string& laneID, std::vector<std::string> allowedClasses) {
360 MSLane* const l = getLane(laneID);
363}
364
365
366void
367Lane::setDisallowed(const std::string& laneID, std::string disallowedClasses) {
368 setDisallowed(laneID, std::vector<std::string>({disallowedClasses}));
369}
370
371
372void
373Lane::setDisallowed(const std::string& laneID, std::vector<std::string> disallowedClasses) {
374 MSLane* const l = getLane(laneID);
375 l->setPermissions(invertPermissions(parseVehicleClasses(disallowedClasses)), MSLane::CHANGE_PERMISSIONS_PERMANENT); // negation yields allowed
377}
378
379
380void
381Lane::setChangePermissions(const std::string& laneID, std::vector<std::string> allowedClasses, const int direction) {
382 MSLane* const l = getLane(laneID);
383 if (direction == libsumo::LANECHANGE_LEFT) {
384 l->setChangeLeft(parseVehicleClasses(allowedClasses));
385 } else if (direction == libsumo::LANECHANGE_RIGHT) {
386 l->setChangeRight(parseVehicleClasses(allowedClasses));
387 } else {
388 throw TraCIException("Invalid direction for change permission (must be " + toString(libsumo::LANECHANGE_LEFT) + " or " + toString(libsumo::LANECHANGE_RIGHT));
389 }
390}
391
392
393void
394Lane::setMaxSpeed(const std::string& laneID, double speed) {
395 getLane(laneID)->setMaxSpeed(speed);
396}
397
398
399void
400Lane::setLength(const std::string& laneID, double length) {
401 getLane(laneID)->setLength(length);
402}
403
404
405void
406Lane::setFriction(const std::string& laneID, double friction) {
407 getLane(laneID)->setFrictionCoefficient(friction);
408}
409
410
411std::string
412Lane::getParameter(const std::string& laneID, const std::string& param) {
413 return getLane(laneID)->getParameter(param, "");
414}
415
416
418
419
420void
421Lane::setParameter(const std::string& laneID, const std::string& key, const std::string& value) {
422 getLane(laneID)->setParameter(key, value);
423}
424
425
427
428
429MSLane*
430Lane::getLane(const std::string& id) {
431 MSLane* const lane = MSLane::dictionary(id);
432 if (lane == nullptr) {
433 throw TraCIException("Lane '" + id + "' is not known");
434 }
435 return lane;
436}
437
438
439void
440Lane::storeShape(const std::string& id, PositionVector& shape) {
441 shape = getLane(id)->getShape();
442}
443
444
445std::shared_ptr<VariableWrapper>
446Lane::makeWrapper() {
447 return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
448}
449
450
451bool
452Lane::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
453 switch (variable) {
454 case TRACI_ID_LIST:
455 return wrapper->wrapStringList(objID, variable, getIDList());
456 case ID_COUNT:
457 return wrapper->wrapInt(objID, variable, getIDCount());
458 case LANE_LINK_NUMBER:
459 return wrapper->wrapInt(objID, variable, getLinkNumber(objID));
460 case LANE_EDGE_ID:
461 return wrapper->wrapString(objID, variable, getEdgeID(objID));
462 case VAR_LENGTH:
463 return wrapper->wrapDouble(objID, variable, getLength(objID));
464 case VAR_MAXSPEED:
465 return wrapper->wrapDouble(objID, variable, getMaxSpeed(objID));
466 case VAR_FRICTION:
467 return wrapper->wrapDouble(objID, variable, getFriction(objID));
468 case LANE_ALLOWED:
469 return wrapper->wrapStringList(objID, variable, getAllowed(objID));
470 case LANE_DISALLOWED:
471 return wrapper->wrapStringList(objID, variable, getDisallowed(objID));
472 case LANE_CHANGES:
473 paramData->readUnsignedByte();
474 return wrapper->wrapStringList(objID, variable, getChangePermissions(objID, paramData->readByte()));
475 case VAR_CO2EMISSION:
476 return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
477 case VAR_COEMISSION:
478 return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
479 case VAR_HCEMISSION:
480 return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
481 case VAR_PMXEMISSION:
482 return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
483 case VAR_NOXEMISSION:
484 return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
486 return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
488 return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
490 return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
492 return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID));
494 return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID));
496 return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID));
498 return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID));
500 return wrapper->wrapInt(objID, variable, getLastStepHaltingNumber(objID));
501 case LAST_STEP_LENGTH:
502 return wrapper->wrapDouble(objID, variable, getLastStepLength(objID));
503 case VAR_WAITING_TIME:
504 return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
506 return wrapper->wrapDouble(objID, variable, getTraveltime(objID));
507 case VAR_WIDTH:
508 return wrapper->wrapDouble(objID, variable, getWidth(objID));
509 case VAR_SHAPE:
510 return wrapper->wrapPositionVector(objID, variable, getShape(objID));
512 return wrapper->wrapStringList(objID, variable, getPendingVehicles(objID));
513 case VAR_ANGLE:
514 paramData->readUnsignedByte();
515 return wrapper->wrapDouble(objID, variable, getAngle(objID, paramData->readDouble()));
517 paramData->readUnsignedByte();
518 return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
520 paramData->readUnsignedByte();
521 return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
522 default:
523 return false;
524 }
525}
526}
527
528
529/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
const SVCPermissions SVCAll
all VClasses are allowed
SVCPermissions invertPermissions(SVCPermissions permissions)
negate the given permissions and ensure that only relevant bits are set
const std::vector< std::string > & getVehicleClassNamesList(SVCPermissions permissions)
Returns the ids of the given classes, divided using a ' '.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
T MIN2(T a, T b)
Definition StdDefs.h:76
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition StdDefs.h:58
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
#define LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(CLASS, DOM)
Definition TraCIDefs.h:76
#define LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(CLASS)
Definition TraCIDefs.h:123
static double naviDegree(const double angle)
C++ TraCI client API implementation.
void rebuildAllowedLanes(const bool onInit=false)
Definition MSEdge.cpp:300
const MSVehicleContainer::VehicleVector & getPendingVehicles() const
retrieve vehicles waiting for insertion
Representation of a lane in the micro simulation.
Definition MSLane.h:84
static void insertIDs(std::vector< std::string > &into)
Adds the ids of all stored lanes into the given vector.
Definition MSLane.cpp:2357
void setChangeRight(SVCPermissions permissions)
Sets the permissions for changing to the right neighbour lane.
Definition MSLane.cpp:4338
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition MSLane.h:579
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition MSLane.h:119
static const long CHANGE_PERMISSIONS_PERMANENT
Definition MSLane.h:1334
double getLength() const
Returns the lane's length.
Definition MSLane.h:593
void setChangeLeft(SVCPermissions permissions)
Sets the permissions for changing to the left neighbour lane.
Definition MSLane.cpp:4332
void setPermissions(SVCPermissions permissions, long long transientID)
Sets the permissions to the given value. If a transientID is given, the permissions are recored as te...
Definition MSLane.cpp:4299
bool isCrossing() const
Definition MSLane.cpp:2468
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition MSLane.cpp:2325
bool isInternal() const
Definition MSLane.cpp:2456
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition MSLane.h:474
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition MSLane.h:504
double interpolateLanePosToGeometryPos(double lanePos) const
Definition MSLane.h:545
virtual const PositionVector & getShape(bool) const
Definition MSLane.h:293
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:745
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition MSLane.h:707
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition MSLane.cpp:3222
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:183
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:322
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition MSNet.h:433
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position
Definition Position.h:264
A list of positions.
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
static double getDefaultDecel(const SUMOVehicleClass vc=SVC_IGNORING)
Returns the default deceleration for the given vehicle class This needs to be a function because the ...
static const SUMOVTypeParameter & getDefault()
return the default parameters, this is a function due to the http://www.parashift....
Representation of a vehicle.
Definition SUMOVehicle.h:62
static StringBijection< LinkState > LinkStates
link states
static StringBijection< LinkDirection > LinkDirections
link directions
const std::string & getString(const T key) const
virtual std::string readString()
Definition storage.cpp:180
virtual int readUnsignedByte()
Definition storage.cpp:155
virtual int readByte()
Definition storage.cpp:128
virtual double readDouble()
Definition storage.cpp:362
TRACI_CONST double INVALID_DOUBLE_VALUE
TRACI_CONST int LAST_STEP_VEHICLE_ID_LIST
TRACI_CONST int LAST_STEP_VEHICLE_NUMBER
TRACI_CONST int VAR_NOXEMISSION
TRACI_CONST int TRACI_ID_LIST
TRACI_CONST int VAR_WAITING_TIME
std::map< std::string, libsumo::SubscriptionResults > ContextSubscriptionResults
Definition TraCIDefs.h:338
TRACI_CONST int LANE_LINK_NUMBER
TRACI_CONST int LANE_CHANGES
TRACI_CONST int LAST_STEP_LENGTH
TRACI_CONST int VAR_ANGLE
TRACI_CONST int LANE_EDGE_ID
TRACI_CONST int VAR_PMXEMISSION
TRACI_CONST int VAR_COEMISSION
TRACI_CONST int VAR_WIDTH
TRACI_CONST int VAR_MAXSPEED
TRACI_CONST int LAST_STEP_MEAN_SPEED
TRACI_CONST int VAR_CO2EMISSION
TRACI_CONST int LANECHANGE_RIGHT
TRACI_CONST int VAR_PENDING_VEHICLES
TRACI_CONST int VAR_FUELCONSUMPTION
std::map< std::string, libsumo::TraCIResults > SubscriptionResults
{object->{variable->value}}
Definition TraCIDefs.h:337
TRACI_CONST int VAR_SHAPE
TRACI_CONST int LAST_STEP_VEHICLE_HALTING_NUMBER
TRACI_CONST int VAR_LENGTH
TRACI_CONST int VAR_HCEMISSION
TRACI_CONST int ID_COUNT
TRACI_CONST int VAR_PARAMETER
TRACI_CONST int LANECHANGE_LEFT
TRACI_CONST int LAST_STEP_OCCUPANCY
TRACI_CONST int VAR_NOISEEMISSION
TRACI_CONST int LANE_DISALLOWED
TRACI_CONST int VAR_PARAMETER_WITH_KEY
TRACI_CONST int VAR_FRICTION
TRACI_CONST int VAR_CURRENT_TRAVELTIME
TRACI_CONST int LANE_ALLOWED
TRACI_CONST int VAR_ELECTRICITYCONSUMPTION