question

Ankith T avatar image
0 Likes"
Ankith T asked Jason Lightfoot edited

How to block opposite traffic while a specific vehicle is traveling on AGV Path

In My model a Big forklift (Transporter) is traveling on the aisles where other vehicles (TaskExecuter) such as tuggers or Electric pallet jacks use. when ever this forklift in on the aisles it should occupy whole aisle so that what ever coming in opposite direction should stop or do not enter the aisle until forklift exits that aisle. But what ever vehicles going in the same direction of Forklift can do there operations as usual.


Please refer to attached images regarding more clarity about the question. Here i would like to know the logic how to stop opposite flow traffic when Big Forklift is on that specific aisles.


1678979297537.png


1678979332545.png

FlexSim 21.0.10
agvnetworkblocking
1678979297537.png (93.6 KiB)
1678979332545.png (88.3 KiB)
· 3
5 |100000

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

Joerg Vogel avatar image Joerg Vogel commented ·
@Ankith T, one way direction path or omnidirectional path system? Unfortunately the picture resolution is not large enough to be certain about this.
0 Likes 0 ·
Ankith T avatar image Ankith T Joerg Vogel commented ·
each agv path represents one way direction path
0 Likes 0 ·
Jason Lightfoot avatar image Jason Lightfoot ♦♦ commented ·

Hi @Ankith T, were our answers helpful? If so, please click the "Accept" button at the bottom of the one that best answers your question. Or if you still have questions, add a comment and we'll continue the conversation.

If we haven't heard back from you within 3 business days we'll auto-accept an answer, but you can always unaccept and comment back to reopen your question.

0 Likes 0 ·
Kavika F avatar image
0 Likes"
Kavika F answered Kavika F commented

Hey @Ankith T, I've got a possible solution. It's a simplified version, but maybe it could translate to your model.

1679615991152.png

I I have two parallel lines of work. I only want the smaller AGVs to use the lane when the Forklift isn't using it (and vice versa). I setup the Control Points (CPs) to have several labels on them:

1679616089832.png

  • LaneEnd - a reference to the CP that denotes the other end of the lane (in this case CP3; if you look at CP3, it will have this CP as its LaneEnd reference).
  • NeighborCP - a reference to the CP in the other lane at the same position as this CP.
  • Occupants - an array that keeps track of how many AGVs are currently in this lane

I added a label on each AGV; a "Type" label for either "small" or "large" to help distinguish whether an AGV needed to occupy both lanes.

1679616429923.png

I added these CPs to a group "LaneEnds" and made a small Process Flow to activate some traffic controlling when an AGV arrives at a CP.

1679616255987.png

Here is the code for the Traffic Controller Custom Code:

/**Custom Code*/
Object current = param(1);
treenode activity = param(2);
Token token = param(3);
treenode processFlow = ownerobject(activity);

Object currentCP = token.currentCP;
Object trafficManager = Model.find("TrafficManager");
AGV agv = AGV(token.agv);
token.labels.assert("Stopped", 0);

treenode laneEnd = currentCP.labels["LaneEnd"].value;
treenode neighborCP = currentCP.labels["NeighborCP"].value;
Array curTEs = currentCP.labels["Occupants"].value;

// I (TE) arrive at CP
// Check to see if I am leaving the lane
int isLeavingLane = 0;
for (int i = 1; i <= curTEs.length; i++) {
  if (curTEs[i].name == agv.object.name) {
    isLeavingLane = 1;
    break;
  }
}

if (isLeavingLane) {
  curTEs = curTEs.splice(1, 1);
  currentCP.labels["Occupants"].value = curTEs;
  laneEnd.labels["Occupants"].value = curTEs;
  sendmessage(trafficManager, currentCP);
  return 0;
}

// Check to see if the neighbor has occupants
Array neighborTEs = neighborCP.labels["Occupants"].value;

// If there are no occupants in the neighbor lane, then proceed normally
if (neighborTEs.length == 0) {
  curTEs.push(agv.object);
  currentCP.labels["Occupants"].value = curTEs;
  laneEnd.labels["Occupants"].value = curTEs;
  return 0;
}

// The neighbor lane has occupants; do I need to wait? (Yes if either TE is "large")
int curTEIsLarge = agv.object.labels["Type"].value == "large" ? 1 : 0;
int neighborIsLarge = 0;
for (int i = 1; i <= neighborTEs.length; i++) {
  TaskExecuter neighborTE = neighborTEs[i];
  if (neighborTE.labels["Type"].value == "large") {
    neighborIsLarge = 1;
    break;
  }
}

// If you don't need to wait, then proceed normally
if (!curTEIsLarge && !neighborIsLarge) {
  curTEs.push(agv.object);
  currentCP.labels["Occupants"].value = curTEs;
  laneEnd.labels["Occupants"].value = curTEs;
  return 0;
}

// Either I'm large or my neighbor has a large occupant;
// Stop traveling until I get a message saying the neighbor is clear
agv.object.stop(STATE_STOPPED, 1);
token.labels["Stopped"].value = 1;
trafficManager.labels["stoppedAGVs"].value.as(Array).push(agv.object);

return 1;

I hope the comments I have help you understand what's happening. Basically, I'm running checks on each CP and lane to make sure it's okay for them to travel. If not, I stop them.

If an AGV is stopped, it will need to resume somehow. That's where the "TrafficManager" comes in. If an AGV is leaving the area, it will send a message to the "TrafficManager" fixed resource - just a cube I used to send a message to. It has an OnMessage trigger that fires this code when it gets a message from a CP:

/**Custom Code*/
Object current = ownerobject(c);
Object fromObject = param(1);
Variant msgparam1 = param(2);
Variant msgparam2 = param(3);
Variant msgparam3 = param(4);

Array stoppedAGVs = current.labels["stoppedAGVs"].value;
if (stoppedAGVs.length == 0) {
  return 0;
}

AGV agv = AGV(stoppedAGVs[1]);
Object currentLaneCP1 = fromObject.labels["NeighborCP"].value;
Object currentLaneCP2 = currentLaneCP1.labels["LaneEnd"].value;

agv.object.resume(1);
stoppedAGVs.pop();
//current.labels["stoppedAGVs"].value = stoppedAGVs;
currentLaneCP1.labels["Occupants"].value = [agv.object];
currentLaneCP2.labels["Occupants"].value = [agv.object];

return 1;

Basically, it resumes the stopped AGV and sets the Occupants to contain the newly resumed AGV.

This is what it looks like in action:

2-lane-stopping.gif

blocking-traffic.fsm


· 1
5 |100000

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

Kavika F avatar image Kavika F ♦ commented ·

blocking-traffic_1.fsm

Updated to have a small AGV on the same path following the Forklift.

0 Likes 0 ·
Jason Lightfoot avatar image
0 Likes"
Jason Lightfoot answered Ankith T commented

You show where the TEs should stop, but not where the Transporter should stop if the TEs have already occupied part of the circuit - by identifying both I think you may see how many shared resources you need and how you might manage the stop/continue logic using a process flow.

(It looks like the outer loop is anticlockwise travel, with the inner loop being clockwise)

· 5
5 |100000

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

Ankith T avatar image Ankith T commented ·

Transporter should stop at the previous aisle before it enters the other aisle. i have pasted a picture to show where transporter should stop and direction of aisles here.


1678984194324.png

0 Likes 0 ·
1678984194324.png (106.9 KiB)
Jason Lightfoot avatar image Jason Lightfoot ♦♦ Ankith T commented ·

Thanks - that's as I suspected. So you could create a resource for each non-passing section such as a control area and give it attributes representing the state (clockwise or counter clockwise - east/west - north/south). If a control area you need is allocated to a different transport type and in the wrong state then you have to stop. When you acquire the section set it to the state you need so that any other travellers can travel in the same direction.

0 Likes 0 ·
Ankith T avatar image Ankith T Jason Lightfoot ♦♦ commented ·

when a forklift travel right side, i want to stop the traffic which is flowing left side, both use different AGV path, how would you like me to setup the control area? Do i have to put single control area for both or should i put control area for the opposite traffic aisle?

0 Likes 0 ·
Show more comments