This tutorial shows Podcars, state saving/loading, routing preferences and more!
Files#
Transcription#
Outline#
So I think you said it's the 13th, I think it's even the 14th tutorial starting in 2013 off by one error. Everybody who programs likes these. So what shall we be talking about today? Podcars. And if you think it's something like a podcast, then I'll explain what it is in a moment. This will be the big topic of the tutorial, the podcars. And then we also spend a few slides on the topics of state saving and loading because it's something we never featured in the tutorial and has gotten quite a bit of support extensions in the last time. So I want to highlight it for you and also on routing preferences because it's a new feature that I want to spread the knowledge. I want to spread the good news, so to speak. As always, in the last year, the aim in doing the tutorial was to avoid showing you any kind of XML files. It has gotten better over the years, but in the very end, I'm afraid there will be some XML. So if you want to follow the tutorial, you should have at least version 1.27.0, which came out last week, which will be superseded by 1.27.1 probably next week or the week after that for some small quality cleanup, but it's not affecting the tutorial. So if you have that version, you're good to go. You can find a link to the tutorial files on the website or in the slides, but if you have the slides, you have the files as well. But generally, I don't recommend to follow along while I talk because I'll probably be too fast for that. But don't worry, we'll record everything. And also, I have this thing where you can see my mouse and you can see all the buttons that I press. So it will all be in the video. You won't miss a thing. So just try to be attentive and you'll be good.
Podcars / Personal Rapid Transit (PRT)#
So what are podcars? Well, it's also known as personal rapid transit. The vehicles are called pods by the people talking about them. And it's about small automated on-demand public transport. And it sits in a, for those that never heard about it, I know there are some in the audience who know all about podcars, but for those who are new to the topic, it sits, in an interesting intersection between public and private transport. So it's a public system in the sense that it's not your own vehicle and you're not driving, but it's nearer to private transport in the sense that it brings you between, from origin to destination without any extra stops. So it's basically, it's driving around just for you. And so, yeah, it tries to be the best of both worlds, the best of public transport and the best of private transport. And in terms of economic function, there's the promise of doing public transport with less resources. So whereas private cars sit unused on the road, on parking spaces for a lot of time, those public systems, they get a lot more use out of the material. And also, if you organize the system better, then you need much less road space. So instead of having wide roads with overtaking lanes and everything, here you can go with rather narrow infrastructure, either on tracks or, as we'll see, actually on wheels and guideways. So this is the promise. We'll do our public transport with more efficiency. And this is an old promise. So more than 50 years ago, people were thinking about building these things. There's something that you can find on YouTube about the Cabinentaxi von Krauss Maffei, a German company that was building prototypes of this in 1974. And you can see an image. It's something quite innovative, where you have extra infrastructure, and it's used with the vehicles driving above it and hanging below from it. So it's seeing double the capacity with one piece of infrastructure. Pretty nice. But it was not deployed for various reasons. And then on the other side of the Atlantic, you have the Morgantown PRT. And this is remarkable because it's very old, and it's the biggest system that was ever put into operation, and it's still operating to this day with a very good safety and efficiency record. So this thing is the living proof that this actually works. It's not an empty promise. It's not terribly big as a network. So it connects the university campus that is spread over Morgantown with five stations and roughly six kilometers. And there are more installations all over the world that are smaller, that only have two or three stations. So this is really a nice example for that. And it's small pod cars that run on rubber wheels on a concrete track. And just to show you that this is not only stuff from the past that's maybe still running. This is from this year. In Mumbai, the Indians are building a podcar system, and it's to connect a business district that is very busy. So they already have a problem with lots of congestions there, and they're building something with a very dense network of stations. I read they want to have a station every 200 meters. And it's also to be rubber wheels on concrete tracks. So this is being built, and I think they want to expand the network to eight or nine kilometers, and then if it goes well, maybe more. All right, so it's the past, but maybe also the future. And this is where we come in with SUMO, because, well, if somebody thinks about building it, it's always a good idea to simulate it beforehand.
osmWebWizard - Morgantown#
So we're going to try to replicate, well, no, we will replicate the Morgantown PRT system in SUMO. And we start, as always, with the OSM web wizard. So when I start this, let's do this live, see how it goes. I can just put in here "Morgantown", and off we go. And then you can already see in blue here a curious structure. And when we zoom in, there's already one of the key points of this podcar system. You can see these stations, and they look quite different from rail stations that you're used to, and also, I think, quite different from roads that you're used to. It's so-called offline stations. So you have tracks that bypass the station on the outside, and then you have these orthogonal tracks or bays for entering and exiting the cars. And so the stopping cars don't impede the traffic that doesn't have to stop, which is a major point of difference between normal rail operations, where you don't have these offline stations.
All right, so we can download this with a few settings that I'm explaining on the slide. So we don't need all the road types. We want to keep it clean, so we're only importing the features that this is being mapped at. And now it's already kind of awkward, because the people who are mapping this Morgantown thing, they've used an OpenStreetMap bus guideway for most of this thing, and then there's a little loop on top, which they tagged as Monorail. So this is typical OpenStreetMap for you. Stuff like that just happens. So if you want to import this, then you have to click on Monorail and Bus Guideway, and leave out everything else. This is for you to follow. There's this tab here where you can select which types of infrastructure you want to import. And of course, it's faster and easier if you disable the stuff that you don't need. And for anybody who's new to the OSM Web Wizard, of course, you can select other things there as well. Traffic modes where you want to import random traffic and the volume, which you want to import it, and whether it's through traffic or not. But today, we're not going to use any of that. So that's all disabled. We only want public transport, and we can set a scenario duration of, I think, two hours. And then we generate the scenario, and I'll speed this up and just open the scenario as it is. So the OSM Web Wizard gives you a big folder of files, a network file, and the raw OpenStreetMap data, and everything that's used to define traffic and stops. And so this is what we basically the shape that we saw on the web. And now it's inside SUMO with a few clicks. And we see here some stations, these green things, and here as well. So you see these interesting structures that I talked about. And now when we press run, we actually see something running there. So this is too small. Let's have this a little bigger. These are visualization presets that you can build yourself out of these settings here if you make the vehicles large. But I've prepared them beforehand. And so now you have something moving here along that system. And then at some point, something else appears. And you'll notice by now, this is not how podcars are supposed to work. This is like a regular bus running between stations, and it's stopping here, and it's not making use of these little bays. So this is just what OpenStreetMap gives you, and it's just the basic network we're building on. We have to improve this. So let's do this.
One-click scenario limitations#
First of all, as mentioned, we have these inconsistencies with what it actually is being tagged as, bus guideway or monorail. The stops are wrong, and the public transport line that we're importing, it's not meant to represent this type of personal rapid transport that we're aiming for. On top of that, whoever defined those tracks, they didn't bother with setting the speed limit. So if you download this from OpenStreetMap, it says 100 kilometers per hour for this infrastructure, which is not actually the case in Morgantown. And yes, also the vehicles, they don't drive continuously there, as you would expect. They just disappear, and then a new vehicle appears.
Using netedit to fix infrastructure#
This is all something we want to fix. And so we start with netedit. So let's do this. Of course, you can start netedit from your start menu or from the folder of binaries, but you can also start it from within sumo-gui. There's a shortcut here, Ctrl + T, so we'll do that, and now we have our network ready to be edited in netedit, the graphical editor. Small question to the audience, who here has never opened netedit? Please raise your hands. Okay. So then I hope the others can still learn something and are not getting bored. And for you, I'm going a bit slower. So what do we want to do? We want to clean the road types. We want to fix the speeds. We want to fix the places for stopping. So first of all, let's fix what these edges are, what their types are. So I'm going to the selection mode by pressing the letter S. You can also find this here under this, behind this button. And I want to select everything. I could just hold Shift and draw a rectangle, that would work, or I can use this selection by attribute. So if I select everything that is faster than 10 meters per second, I'm also getting the whole edges in the network. That's good enough. And now I'm switching to the inspection mode where I get to see and modify attributes. And now when I click on any of these selected things, selection is shown in blue, then I get to edit them all at once. So let's change the speed from what is equivalent to 100 kilometers per hour to 53 kilometers per hour. And that is 14.75 meters per second. And let's also change the permissions of this all to "bus". So two clicks. And now everything is for bus. That's good. And I can get rid of the selection by pressing Esc, or actually Shift + Esc here in this mode. If I'm in the selection mode, it's just Esc. Next thing I want to do is fix the infrastructure with respect to stopping. And to help me with this, I'll first activate the labeling of these stops by name so I can avoid making mistakes. So I press this settings, graphical settings button here, and I go to additional objects and select show full name. And so we see the stop here is named Walnut. And these stops are called Beechurst. This is all faculty of the university there. And I want to get rid of these and instead have the stops here at the little base. So I'm going to the additional mode by pressing the letter A, and let's actually copy the name first. So back to inspect mode. Click on it. Copy the Beechurst string, and now I can put this in here. Beechurst. And I can click a few new stops. And with a click on D for delete mode, I can get rid of the old and wrong ones. And this I could repeat for all these stations here. But I'll speed this up and just switch to the network where I already did all this. So I removed the old online stations and instead edit the new offline station. Let's do this one more time to drive home the point. So let's copy the name. You will see why I copied the name in a little bit. So now a few more stops here. And then delete mode, which is a button but also a hot key. And get rid of the old ones. All right. And then you would save everything, save the network, and save the infrastructure. Okay. And then we can continue.
Modelling PRT Vehicles#
After fixing the network and the infrastructure, we want to model the fleet of podcars that are moving on that infrastructure to service the passenger demand. And for this, we'll be using a feature of SUMO that has been available for some time. It was first presented during the 2020 tutorial, it's the taxi device. So it's a generalized module for demand-responsive transport. It's something where vehicles in the simulation are automatically routed to pick up passengers that demand to be transported with that mode of traffic. And since presenting it six years ago, a few features have been added. As you know, in SUMO, there are different abstract vehicle classes that are used to regulate who gets to drive where. And for a long time, there was a specific taxi class. And so if you ever wanted to model this kind of demand-responsive transport, you had to put it on elements that were all the same. They all had to be permitted for taxi. And now this has been finally resolved. So now you can have demand-responsive traffic on rails, and you can put it in the air with a new class drone or on the water. And you can separate all these networks of traffic and still have them be serviced by the taxi device. Also, you can restrict the persons. You can tell them this category of person can only be serviced with this kind of fleet. So you have some additional layers of modeling who gets to use what. And then there is a new feature where you can say taxis that don't currently do anything, well, there are several things they can do; they can just wait at the side of the road, or they can keep driving in circles waiting for new requests. And something else that is now possible is to have them drive to a specific point. A waiting area, a taxi stand, and have them wait there. And if there are multiple stands, they will distribute among them to find one that is free. So there is a lot of configuration possible with that. And there are other features added like instant redispatch once a taxi becomes idle. We will be actually making use of this. But it is all automated. Nothing to do. Reservations can be modeled in SUMO. And the taxi device finally permits to save its state and reload it. We will also be seeing that today. And lots of fixes to the algorithms with respect to accuracy and stability.
Defining PRT Vehicles in netedit#
So this is what we will be using. And the first thing we will do for that is to define a new type, a vehicle type. So let's go back to netedit. Okay. I'm doing this in another folder here. And let's open this here. So I will be opening a network from that folder. Okay. A new vehicle type.
netedit has multiple major modes: the network mode, the demand mode and the data mode. To define the type we will be going for the demand mode. You can of course always switch to a mode via hotkey, in this case it is F3. And then we have another sub mode for defining types. The type mode activated by hotkey T. And we will be defining a new type. Let's call it the taxi type, actually let's call it the podcar. And by looking it up on the internet we know some properties of the podcars that are driving in Morgantown. So let's go back. What have we? A length of 4.72 meters. The minimum gap, well, I kind of estimated this from the literature. And a maximum speed of 15 meters per second. Also we are saying this is driving on this bus guideway. So we classify it as bus.
And also from the literature we know that they are not very quick to accelerate. It says for passenger comfort limited to 0.6 meters per second. So these are the basic settings you can do here. But we will need at least one more extended attribute, so we are opening the extended attribute editor. And setting the person capacity to 8. Here it gives you the default of the bus type with 85. But we are having smaller vehicles, so we are setting this to 8. And actually there are more positions for standing persons. But this is enough here. And then we have to set some parameters, to actually make this into a taxi.
And here you can see which ones we need: has.taxi.device is one (so it is a taxi), and we are setting a drop off duration to 0, which means there is no post trip negotiation, where you have to pay for the fare or something. That is all done. So the vehicle stops, you get out, and then the podcar can continue. So we want to set a drop off duration of 0. And also since we are running on these guideways, there is nowhere to go for the taxi. So when it stops, it is not parking. It stays on the guideway. So these are the three parameters that we want to configure. And we do this with this parameter dialogue. So let's see. One more. And that should be it. And then we have defined our taxi type.
Next step. We are defining the pod cars themselves, and then make use of this type. We are still in the demand mode. And now, we have to define how many we want, and where they drive initially. So let's define one long route. This is the route mode (pressing the letter R - also find it here in the modes). And in this mode I just click a number of edges, they don't need to be and I define a route. But of course it has to match the network, so I'm defining a route for buses on this bus guideway. And so I just start clicking somewhere, and another click, it connects all this in between, and one more click all the way up to this station, and then I can actually come down again and click once more to have a route that goes all the way in a circle, and I conclude this by pressing Enter. And then in the next step I define a flow on that route. A flow is a quick way to define lots of vehicles with similar properties, that are all going to run on that route.
As one gimmick here, I want to have a simulation where they all start spread out over the network. I could just start them all in the bottom, and then it would take some time to fill the network, but I'll define them with a random departage. So they will start somewhere along that route, and when I start the simulation, it will already be kind of busy. So let's do that. I'm going to the vehicle mode, this is here, hotkey V, and then I select that I want to have a flow over an existing route. This is why I just defined the route, and I'm setting the depart edge to random. And the depart position to free, so not just at the start of the edge but at any kind of position along the edge that is still available, so there is some algorithm behind the insertion that tries to find a free spot. And then, again, from the literature I know that usually 69 podcars are running around on these tracks, so I want to define the number 69, and they all can be inserted in the first second. And now I click on that route. First of all I have to pick the type, and then I can click here, and now I have defined my podcars. If I want to look at it again, I can go to the inspect mode, and I will see this is my flow, 69, and maybe I'm not happy with the name, maybe I want to name them pod. And then in the simulation they will be called pod0, pod1, pod2, and so on. So let's name them pod. And then I can save all this. Let's call it taxi. All right. So we're not quite done that yet, but we're pretty far along. So now we need to set some simulation options to let these taxis do their job. And in netedit you can define a sumo configuration by pressing Shift + F10. Only F10 opens up options for netedit itself, for processing the network. But Shift + F10 is for the sumo configuration. And these are the options we want to set. The dispatcher that runs in the background and tells the pods to pick up passengers, it should be running at least every 20 seconds, just to get a better service here. So it's a compromise between computational effort and reaction time. The simulation will be slower if you set a much smaller number here. And then we define the idle algorithm. What are taxis, what are the pods to do while they don't have a job? And this is taking some liberty here, because in the real world you would have some kind of management system that distributes them. So at every station there's always a few pods waiting to pick up passengers. But for the purpose of this tutorial, it's working perfectly fine to just have them circle randomly on the network, and then they'll actually be where they need to be most of the time. I tested it. I tested also a more advanced management scheme, but random circling works surprisingly well. And then we have to say that we want our taxis to be buses in this case, which avoid some warnings. So let's do this. And all these options are device options for the taxi device, so we'll have an easy time finding them. So I'm pressing Shift + F10 to edit the SUMO option, and I'm going to the taxi device tab on here. There are 20 random circling. And then bus. That's it. And we can save our SUMO configuration. And I think that's it, yes, so lets run this. We can launch the configuration from netedit, but only if we already loaded the config. So instead we can also just double click here. And well, let's have them be a little bigger again. And for effect, let's reload. And then you see already in the first two simulation steps, we have them spread out all over the network. And they're just running along. Randomly, because there's nothing yet for them to do. There's no passenger demand that would guide them to stop at these in between stations. Okay. So this is our next target, our next objective. We want to have some passenger demand that wants to ride between these stations.
Defining Passenger demand in netedit#
Okay. Now we could generate demand that's actually appearing at these little stops. That's possible. But it's not the best thing we could do. Actually let me load the version where I fixed the network. So here. Now we have all these little offline stations. We could generate random traffic between specific offline stations. But as you can see, they are not all created equal. So from this station, it's easy to go to the north. But you wouldn't go to the south. If you want to go to the south, you have to start from this station here. So when you're picking a station, you have to do this with your destination in mind. And if we just generate traffic between random stations, then it will be kind of awkward. And the persons would maybe start here, and the pods would have to do a big loop to get up to the north. So before we define our random passenger demand, we're doing a little preprocessing step. And so just in reality, there will be some infrastructure. There will be some stairs, and some service paths that connect all these bases. And the person wanting to travel from the south to the north, they will know which bay to pick. Because this is local knowledge, or it's somewhere on the signs. And so we'll start from that as well. We'll have some common element where the persons can start. And after that, our automatic routing should send them to the correct bay. So this is how we do it. We're using netedit to run the Python tool generateStationEdges.py.
And we don't need to define much. We only need the network file and the stop file. And then we have two options here: join stations true and build true. And the join stations, what it does is it generates one piece of pedestrian infrastructure for all the stops that have the same name. And this is why we took some effort to make sure they all have the correct names in the beginning. So. And build just means build me a new network. And then this is what everything that's being built should be called. So let's do this. Let's see how we can call the tool from within netedit. So this is what the tools menu is for. And then some of them are just in the base folder reflecting the historical growth of our tools. And some of them are in subfolders relating to topic and generateStationEdges is something that builds networks. So it's on the net folder. Here we can just click this button to fill in the name of the current file. And for the stops we'll use this. And let's call this net2. And then we're setting these two options and running our tool. And that's already it. OK.
And now we have a new network. Let's see. That should have happened probably in this folder here. Never mind. Where is it? Let's try this again. And this time I'm looking at the paths. So I'm in the taxis folder. OK. So let's do this again on the persons folder. And yes, now we're in the correct folder. And we'll run the tool. And that's it. And now we have new files in this folder: a network called net2, and a new file of stops. Stops that are connected with the pedestrian infrastructure. So let's make sure we're loading that and taking a look at it. So back to netedit. Let me clean up a little bit my workspace. I will be just as confused as you.
Let's just start with loading the network. This is the new network. The only thing that's different is that for every station we have a small piece of pedestrian infrastructure here. And when we now load the new stops file, we can see that they are connected with these small green lines to that pedestrian infrastructure. So there's some way to connect these, the stations to the pedestrian network. And then the next step, which is, again, somewhat simple, will generate our random pedestrian demand. So we are running the tool randomTrips.py here.
And there is this option for persons. Where is it? I moved it recently, so now I have to find it. I'm using the current network. And is there something else I need to be doing? I'm using the additional file. And I have, of course, to define the output. If I don't want the default name. And ... ah, yes. There are some details. Right now I don't want to do validation. Because I'm defining these taxis as buses. And the DRA router, which is doing validation in the background, still expects them to be vehicle class taxi. So this is why I have to uncheck this. Now where is the validation button? It's supposed to be there somewhere. Here. So I uncheck this. And then I have to define which mode they should travel with. Because right now, if I just generate random persons that would try to walk from one of these little pedestrian edges to the next. And they couldn't. They can't walk on the guideway. So I have to tell them, you should do intermodal routing. You should go to some station and use one of these podcars. And this is what I'm doing by assigning them to the taxi mode.
And now when I run this, I have my persons. I promised to not show you XML, but actually I kind of like to show you what this file looks like anyway. So you have here persons. Each person has a person trip. And these things here, "Towers_access" and "Beechurst_access", these are the IDs of the small pedestrian edges that we generated. And they are supposed to get from one to the other by mode taxi. This is what we did.
And we're almost done putting it all together. There are still some simulation options we have to set. We have to permit those taxis to pick up and drop off passengers at public transport stops. Because this is not how taxis work by default. They don't use the bus stop for stopping. So this is a SUMO option. And also in order to increase the efficiency of the system, we are setting a default group for the persons. Everybody is in the same group can share a taxi vehicle. And here we're just saying everybody can share with everybody, they're all in the same group. Groups are something that you can customize per person. But here that we are setting a default group. And so this means five persons going from the bottom station to the topmost station, they can just all get into the same podcar and nicely get along with each other. So as you recall, we're just going to the SUMO option settings by Shift + F10. And one way to quickly get to options is to use this little search bar, and by putting in "taxi" here. No, actually, it's even better if I use person trip.
I'm getting to all the options that I want. The default group. The string is arbitrary. As long as you set one, they all share. And here the transfers PT stops. And that's it. I'm saving the configuration. And let's run this in SUMO. And no, I didn't load the pods. So before I start clicking too much, I'll just use the thing that I already prepared. And here we go. All right. So what do we see?
We see again the pods. But we also see in blue the persons. Actually, blue are the persons that are riding, and we have persons in yellow that are waiting. So right now, the persons are colored according to the mode they're in. We would also find some in cyan, because they're in the process of accessing the stops. And so they're being moved along nicely. They're being picked up. You can see how they wait. And then they don't have to wait very long. The pod will come pick them up and bring them to the destination. And if you never worked with persons in SUMO, there are several things you can do with them. You can inspect their plans. So this one here, it's starting at the station called Medical_access. Medical, actually. Actually, no. It started at Beechurst and wants to go to Medical. This is the trip. This is the top line. This is the high-level overview of what it wants to do. And then actually this resolves in several steps. First it walks to one of these specific bays.
Using this access element, then it is waiting for a taxi that brings it to the medical bus stop. And then it walks again to end up on that little pedestrian edge. So this is the plan of this person. And overall, I think we generated 3600 persons, one per second for one hour. And they're being all delivered. And if we don't set a delay, it runs real quick. So this is our podcast simulation. And it's not exactly how things are running in Morgantown. Because, as mentioned, they're probably not driving around randomly when they have nothing to do. But rather they would smartly congregate at two service areas that you can actually find on the tracks. One here and one here. I didn't find this on the literature, but I find it rather obvious from the layout that these are service and waiting areas where you can have surplus, where you can have pods that are not needed at the moment. If you have little traffic demand, probably you're not running 69 pods all the time. So there's still room for making this more realistic. But I think as a showcase, it serves pretty nicely. And then, of course, you have this still unrealistic behavior of running even after all the persons are gone, which I'm sure they don't do in reality. So these are podcars. And this is the main part of the tutorial. But we're not done yet. There are still a few more things we can do.
Scenario Evaluation#
First of all, we can evaluate our scenario. And for this, one very easy thing is to just run it and put some infos in log files. So let's see. We can set some SUMO options for outputs. We can set the tripinfo output. And if we want anything on the podcars, because they never arrive, we have to set this option "write output for unfinished" (tripinfo-output.write-unfinished). We're just shutting down the simulation at some point. The pods are still working, so to speak. And normally the tripinfo output only holds, finished trips. But with this option, write unfinished, we get still some summaries on how long did they drive and how often did they stop. How much time did they lose in various situations. So with this write unfinished, we get all that. And so even in netedit, you can configure all these options. And also we can separate the output of the persons and the vehicles if we set this option personinfo-output. If you don't set it, Persons and vehicles go in the same file, but if you set the option personinfo-output, then they go into separate files, which simplifies post-processing. And of course, there are other outputs that we could set, for example, the stop output. And you can find all these options with the search box where you configure the SUMO config options. If you do all that, you get, among other things, statistics for the rides that the persons took. And now, where can you get it? This is the white on black window suggestive of running things on the command line. So if you run sumo on the command line, which you probably often do because you don't always need the graphical interface, then you can get this output.
But of course, the same output can also go into log file, which you can just open in your text editor. So let's do this real quick. Let's open the config in netedit and add some output options. Load SUMO config. And set some outputs. So let's have some statistics.
There is this option, duration log statistics, which I like a lot, but we can also have the statistics output. And let's write a log file. This is the log option. And usually I would type all these on the command line, but I think this is more didactic. So let's save the config and run it. And then I think we have the wrong config. Did we have persons? Yes. Sorry. I used the wrong configuration file, so let's look at something where it's already working. Ah, and here I didn't set the options. Okay. Sorry for that. Wasting some time. One log statistics. Okay.
Where are my outputs? Just to not waste anything else, I'm running it here. And this is where you could find these outputs that I showed you on the slide. And you would also have them in the log file, as I said. So I wanted to do some refinements on this scenario. Actually, I wanted to show you something else. Sorry for that. Statistics on further post-processing on outputs. So you have an output file that gives you a line for every file. The trip info output, for every vehicle you know how long it was running in the network. You can investigate them. But maybe you want statistics, further statistics on that. So one of the tools that are accessible via netedit is the attributeStats.py tool. Where you can just drop in any of the output files of SUMO. And for every attribute in that file, it will give you a nice summary. So let's do this here. We have tripinfos. So let's do this on this track. You have netedit, and you have the tools menu. And here you have this in the output folder, the tool attributeStats.py. And there you can drop in any kind of output file that you want. Let's use this. And just run it, and it will give you all these summary statistics. And there you can, for example, see what time, so, every device, including the taxi device, includes some specific statistics. And the taxi device tells you how many customers did one of these pods have on average. What time did it spend occupied by customers. And what distance did it spend occupied. And you can compare this to the total time that was on the network. So there's your basic analysis of efficiency of the system. What is the utilization of the pods. And if you use another output, like the stop output, you can see how many persons on average were riding in one pod car.
So lots of options for post-processing where you don't have to program everything from hand. You can use our tooling. So here, if you look at statistics on the stops, you can see, for example, in this case, average utilization of 2.4 persons per pod.
Scenario Refinement#
And now there's one refinement that I wanted to do. It's management of merging back from the stations. The network, as we build it, simply has built priority junctions everywhere. That means one of those paths. Always gets priority and the others, they have to wait for a gap in traffic. And this is not the most efficient way to do it. Presumably at the Morgantown PRT, they have some smarter management system where they cooperatively merge onto the tracks. And if you want this automated merging, you can simply use netedit and set the junction type of all these junctions there from priority to type zipper. And zipper, a zipper merge, is a form of cooperative merging. So if you do that, everything will run better. So if you look at the statistics of the rides of the persons, you can see that instead of waiting one minute six seconds, they only wait one minute three seconds. And overall, of course, that trip gets faster. I mean, you can say this is not a large effect, but you see these details, they do have effects. So one thing to keep in mind when you're building a podcar simulation.
State saving and loading#
In the remaining time, there are two more topics that I want to touch. One is state saving and loading. And I'm pretty happy that this is now working even with the podcar simulation - that would not have worked last year. A lot of work went into that. Why would you want to do state saving and loading? Well, I think the main reason is if you have a large scenario that you want to do research on and you want to run it again and again, and you don't want the warm-up time. So there's some period of you're filling your network, and this is not where you want to get your data from. You want your data from some later state. And so you could do the warm-up first, save the state of the simulation then, and run it multiple times from that point on. And there are two things that you may want to have. Maybe, you want to run the scenario with different initialization of stochastics. So you save it, you load it, and then from the point on where you load it, it should run a little different every time. You can do that. Simply by setting a new random seed. And then after you load your state, the different variants, they diverge, they do different things. So sometimes this is what you want. But maybe you want an exact replication of vehicular behavior. Because you're doing emission modeling. The pods or cars or trains, they should drive the exact same way, but you're using a different emission model and testing the outputs. And then, of course, you want exact replication. And if you do that, there's an option where the state of the random number generator is part. It's saved along with everything else. And when you run it again, it evolves in the exact same way, that you had. So these are your options with state saving and loading. Either it diverges or it stays the same. And both of them are useful depending on the occasion. Another thing where state saving might come handy is if you have a long running simulation. And at least as of now, you can't really look at it in the meantime. It's running on some server. There's no interface for you to look at. And maybe it's running for days. But you would like to know what's happening in the simulation. So one thing you can do is periodically save the state, maybe once per hour. Just save out the whole system, all the cars, where there are all the persons. And when you're wondering why is my simulation taking so long, you can just load specific states and see what was happening in the simulation at different points in time. So monitoring is another thing. We've even used this to do remote visualization where the simulation runs on some server, and it saves the state every second. And then you can just load the state and see how it evolves on some other machine.
One thing with the state is we're not guaranteeing compatibility. So if you're saving the state with one simulation version, it's probably not going to load with the next. Because from one version to the next, we find more things that we want to put in the state to make sure it really replicates. And so we're not guaranteeing compatibility. All the input files will work the same unless we do a major version change. But the states, you just have to save them again once more if you upgrade some more. So do we still have the time? Well, I'm sparing you the example. I'm just telling you the options. So --save-state is the option. And either you're setting the option times with one or more values at which the state is being saved. Or there's another option where you say with a certain period automatically, it saves every hour or something like that. And then also you can set the files where it should save at, the list of file names. And if you don't do that, it will just give a prefix and find its own names. One other thing to keep in mind, by default, persons and containers will not be part of the state. But if you want them, there's an option for that. Now, if we do this with our podcars simulation, let's save it at time point 1000. We will actually find that the original and the loaded simulation diverge. And why is that? Because we have to explicitly save the state of the random number generator. So there is some randomness in behavior also in the podcar simulation, specifically in how fast the pedestrians walk. There's some random element in this pedestrian model. And this will be enough to diverge the simulations. And also it's a matter of precision. If you write down the position of every podcar and every person at time 1000, you have to have enough digits or the surrounding error will be big enough to diverge the simulation. So if you cut some digits, then one person will arrive a little earlier or a little later. And things will evolve differently from there. So keep that in mind, if you need exact replication, you also need to play around with the precision values. By default, only two digits of precision are saved in the state. And now at the current state of the simulator, if you run this podcar simulation with state, then you will see it can perfectly replicate the fcd output, which means the position of every person in every podcar will be the same. Also the vehicle route output. But for the trip info output, there are some minor things that are not yet working. So there are these access stages where a person transfers between walking and a bus stop. And they kind of leave the network. They're on these narrow green lines. And this is not restored when you load it from a state. So it will work the same. But if they were using access in the past, then the output will not reflect all the access stages. It's a minor thing. But if you do a file comparison, you will see there are some differences still because of that. So this is state saving and loading. You don't always need it. But when you need it, you know it's there.
Routing Preferences#
And for the last topic, so I'm bleeding a little bit in the next session, but bear with me. It's a new feature in SUMO. It's routing preferences. Until now, all the routing in SUMO is mostly by travel time. You can also route by distance, but the main criterion is everybody, every car, every person is doing that which brings them to their destination in the fastest possible way. Now, consider this toy example here. We have a road. And next to the road, we have a cycling track. And because of the curvature of the road, the outside, the cycling track is a bit longer. So in classic SUMO, the bike would say, well, I could use either road. I could use either the road or the cycling track. I will use the road because, well, it's a bit shorter. Realistically, many bicycle riders would still prefer the cycle path. And now in SUMO, you can reflect that preference with a new feature called routing preferences.
There are actually two things there. The first is a new attribute for the edges that's called routing type. It can be an arbitrary string. If you don't set it, it's just the edge type. You know from OpenStreetMap, every edge already has a type like highway motorway or highway residential or cycleway. But maybe this is not the correct granularity for you. So you can set your own routing type if you need it. In this case, I just defined the routing type as cycleway to suggest what it's about. And then there's something that you define in an additional file. It's the preference structure. And here are two examples. So there's a preference for specific to the routing type cycleway. And if you have vehicle class bicycle, then you give to this priority 2. So baseline is priority 1. Priority 2 is basically saying it's twice as I like this twice as much. And practically what it means is the travel time is divided by the priority. So in this extreme case, I would be willing to drive almost twice as long if I get to satisfy my preference of this routing type. Just maybe a bit of an extreme example, but it's just to show the point. And likewise, you could define some roads that have a bad surface and that cars could drive, but maybe they would like to avoid it. And if you set the priority to 0.5, then they wouldn't use them even if they are twice as theoretically twice as fast there. So anything above zero you can put in there just divides the travel time. And you can either define this per vehicle class or by list of classes or by list of types. So it's very you can be very specific about preferences for the participants of the simulation. Very fine grain if you need it. And the only sad thing here is that you cannot yet define preferences in netedit. So you actually have to type this out, copy this out and put it in the XML files. I'm sure this will change in the inversion 1.28.0. But as of today, I couldn't show it in netedit, how you define preferences. So if you do this and if you put this in an additional file and load it in your SUMO configuration as additional file, then you will see that in this case of a minor detour, the bike would prefer the cycle way. I hope you find this useful. At least now you know that it's there as a feature. I'm using this extensively in railway simulation where you have two tracks running in parallel. But one is the preferred direction because the trains should not be in conflict. So depending on the country, they they prefer to ride on the right track, on other countries always on the left track in running direction. And so with these preferences you can say which is the preferred track, even though from a pure routing point of view, they would be almost equal distance or maybe the inside curve would be better, but it would still be the wrong track. So they are already useful.
Conclusion#
In conclusion to this tutorial, even if you want put cars, use Web Wizard to get a quick start, at least for existing installations. If you still don't know all the tools that SUMO brings, you can use netedit to find them. And also, from personal experiences, it's not a bad idea to use large language models to get an overview of capabilities and components. The documentation can be quite large, but LLMs are more than up to the task of reading the documentation for you. But don't trust every word that they generate, so double-check. But still, I find them useful. Another thing to figure out how stuff works is to extract tests. So we have thousands of tests running every night and every commit, actually. And you can get small input examples out of our test suite with a small script that is on our website (https://sumo.dlr.de/extractTest.php). So you just put down the path of the test, and then you get a folder with a simulation that you can run. Don't forget to read the documentation. Please do report bugs. We don't mind if it's on the mailing list or on GitHub. Nowadays, most of the reports come on GitHub. That's fine. Please do share your scenarios and results and talk to us. We're always happy to talk to you. Thank you.
