PequodLZ avatar image
PequodLZ asked Felix Möhlmann commented

Change the elevators logic to scan all floors instead of by shortest distance

I noticed a line of code where it says "ORDER BY distance ASC" on the lower right corner whenever i click an elevator bank. I'm not a coding wiz but thats definitely enough to tell me that the elevator serves passengers based on shortest distance. I decided to test an extreme case where one floor is really far from the other floors, lo and behold the elevators rarely visit the high floor.

Here's my FlexSim file testing it: HCattempt2.fsm

I want the elevator to behave much like a standard elevator building that 'scans' all the building floors. They will move in one direction (say upward) and stop to pick up all who wish to go in that direction and drop them off in their respective floors. Once all (who want to go up) have been served, it switches 'direction' and 'checks all who want to go down' and will serve the 'one who wants to go down on the highest floor' such that the poor souls all the way up there actually get served.

Is there any way to do this using that Request List Pull Query or by Process Flow? I did see this one thread that I think was trying to do something similar: Flexsim HC for patient flow

I didn't really quite get it though, I'm not too familiar with process flow.

FlexSim 23.2.2
hcattempt2.fsm (65.4 KiB)
· 2
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Felix Möhlmann avatar image Felix Möhlmann commented ·

After some testing it seems there are two problems that prevent this from working with the default query and will also make it difficult, if not impossible, to customize the elevator bank to work in this fashion. And the distance ordering isn't actually one of those.

The "Elevator.canStop()" method is actually what prevents the elevators from visiting the top floor while they are busy transporting other passengers. It mandates that an elevator that is currently not empty will only stop for requests that want to go in the current direction of the elevator. To reach the top floor, the elevator has to go up. But any traveller on the top floor can obviously only go down, so "canStop()" forbids the elevator from pulling those requests. This is also true for the bottom floor. Both will only be visited when the elevator is either empty and there are no closer requests or when a traveller wants to go to those floors from somewhere else. Both of those siutation happen far more often for the bottom floor, so the issue is a lot less pronounced in that case. While this could be worked around by adding another condition to the query that would allow the elevator to pull request from the top and bottom floors, the second issue is, as far as I can tell, the overall bigger problem.

The second issue are the rules at which points the query is actually used. For example, when an elevator arrives at a floor and the last passenger exits, it will not invoke the query and instead let the oldest request from that floor enter regardless of which direction it wants to travel.

So overall you would probably have to build completely custom logic using the elevator task executer instead of the elevator bank. I'd probably use the same approach: Have a list with requests and pull the 'best' one. But with a custom build logic you'd have control over when exactly a new request is queried/pulled.

This is only conjecture based on some testing I did, so I only post this as a comment in case someone else has more insight or a better idea on how to customize the logic.

0 Likes 0 ·
PequodLZ avatar image PequodLZ Felix Möhlmann commented ·

Hello, thanks for answering and sorry for the late reply. I'm going to try and use the elevator task executor like you suggested but I'm just not familiar with lists so i don't necessarily know where to start.

Here's a file I made from another thread that I could use as a start: Elevators.fsm

I know I can push to list Flow Items but I'm not sure on how to utilize Label Fields and Expression Fields. I also did try pushing to a list from a source and pull from list using a sink and the items just teleport straight to the sink. In general I just don't know how to actually use a list.

I'm also assuming I have to edit the Queue Strategy under the Dispatcher tab for the elevator task executor. Can the elevators code editor pull from an item list? Can it make use of the labels (of the Flow Items) I originally assigned in the source? In general I'm also not very knowledgeable in C++ but I'll try to make it work.

0 Likes 0 ·
elevators.fsm (35.9 KiB)

1 Answer

Felix Möhlmann avatar image
1 Like"
Felix Möhlmann answered Felix Möhlmann commented

Took some time but I think I have a pretty decent working example. I tried to name everything as descriptive as possible, so it should hopefully be understandable what each activity and list expression is doing. (One exception would be the list field "PriorityWhenEmpty" - you will have to read the comments in the code to understand the idea behind it).

The main thing to understand is that the token keeps track of the current target z-coordinate and in which direction it is travelling. This information is then used to decide which people to load and/or where to move next.


elevators-fm.fsm (51.5 KiB)
· 2
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

PequodLZ avatar image PequodLZ commented ·


It might take a while for me to fully digest everything and I hope you don't mind follow-up questions in the coming days. This is giving me a really good understanding of how tokens work. For now I just want to ask the label "Location" at the source has the value "current.getLocation(0.5, 0.5, 0)". What's the reason for those 3 particular numbers?

0 Likes 0 ·
Felix Möhlmann avatar image Felix Möhlmann PequodLZ commented ·

The three values determine relative to which point of the object the coordinates are measured. They each represent one of the axes (x, y, z) and go from 0 to 1. So (0.5, 0.5, 0) means the command will return the coordinates of the center spot of the bottom face of the object's bounding box. I really only use the first two in the "Travel to Loc" activity. Though since the elevator shouldn't be able to travel along the x- or y-axis they might not even be needed.

And you are of course welcome to post any follow-up questions.

0 Likes 0 ·