How to pick items based on distance?

How to pick items based on distance?

tomonori_s
Not applicable
1,342 Views
6 Replies
Message 1 of 7

How to pick items based on distance?

tomonori_s
Not applicable

[ FlexSim 18.0.10 ]

Hi @Benjamin W2-san,
I have confirmed the model. Thank you very much.
We also need a sample model where the operator chooses a product based on distance.
Can the attached model include the ability for the operator to select products based on distance? Or can you include the ability for the operator to select products based on distance with something close to the "global-table-in-picking-model-with-row-batching.fsm" created?

Also, I would like to reduce the number of items on top of the attached image like "img_01.PNG".
Next week, we will visit potential customers, so I would like to receive an answer as soon as possible.

demo-ver03.fsm

img-01.png

img.png

0 Likes
Accepted solutions (1)
1,343 Views
6 Replies
Replies (6)
Message 2 of 7

benjamin_w2
Not applicable
Accepted solution

Hi @tomonori S,

Picking Based on Distance

The key to ordering the orders by distance is to write custom code. From the attached model, in the Create Orders box, select the Create Object, add a label to the created items called "Rack" with a value of "Table("ItemLocation").executeCell(token.TaskRank, "Rack")". This will store the rack into the order.

In the Pickers Pull Orders and Items box, add an Assign Labels activity after the first Pull from List. The purpose of this activity is to re-order all of the pulled orders based on distance. Notice that this will only order the pulled orders.

Open up the Assign Labels activity. Add a label called "OrderedOrders". Select the arrow underneath "Value". Hover over "Array" and click "Create an Array of Values". Then click on the custom code icon. Delete the text of the custom code and past the following:

/**Custom Code*/
Object current = param(1);
treenode activity = param(2);
Token token = param(3);
Variant assignTo = param(4);
string labelName = param(5);
treenode processFlow = ownerobject(activity);
int orderArraySize = token.Orders.length;
Array orderedOrders = Array(0);
Array Orders = token.Orders;
Object aquiredOperator = token.Picker.as(Object);
double shortestDistance = 0.0;
int shortestIndex = 0;
for (int i = 1; i <= Orders.length; i++)
{
	double tempDistance = 0.0;
	Object object1 = aquiredOperator;
	Object object2 = Orders.Rack;
	double x1 = vectorprojectx(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
	double y1 = vectorprojecty(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
	double z1 = vectorprojectz(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
	double x2 = vectorprojectx(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
	double y2 = vectorprojecty(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
	double z2 = vectorprojectz(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
	tempDistance = sqrt(sqr(x1 - x2) + sqr(y1 - y2) + sqr(z1 - z2));
	if ((i == 1) || (tempDistance < shortestDistance))
	{
		shortestDistance = tempDistance;
		shortestIndex = i;
	}
	if (i == Orders.length)
	{
		orderedOrders.push(Orders[shortestIndex]);
		Orders.splice(shortestIndex,1);
	}
}
for (int i = 1; i <= orderedOrders.length; i++)
{
	double tempDistance = 0.0;
	Object object1 = orderedOrders.Rack;
	for (int j = 1; j <= Orders.length; j++)
	{
		Object object2 = Orders.Rack;
		double x1 = vectorprojectx(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
		double y1 = vectorprojecty(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
		double z1 = vectorprojectz(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
		double x2 = vectorprojectx(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
		double y2 = vectorprojecty(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
		double z2 = vectorprojectz(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
		tempDistance = sqrt(sqr(x1 - x2) + sqr(y1 - y2) + sqr(z1 - z2));
		if ((j == 1) || (tempDistance < shortestDistance))
		{
			shortestDistance = tempDistance;
			shortestIndex = j;
		}
		if (j == Orders.length)
		{
			orderedOrders.push(Orders[shortestIndex]);
			Orders.splice(shortestIndex,1);
		}
	}
}

Note that the above code will order the orders by looking first at the closest item to the operator, then the next closest item, then the next closest item. If you are looking for the shortest possible path, you will need to completely rebuild the model and design it for the optimizer.

Next, open up the Assign Labels in the first sub-flow underneath Pickers Pull Orders and Items. Underneath the label called "PullLable", edit the value to say, "token.parent.OrderedOrders[token.Rank].Label". Underneath the label "PullQuantity" edit the value to say, "token.parent.OrderedOrders[token.Rank].Quantity.

This will give you a better travel path than before.

Creating Different Number of Items

To reduce the number of items created within each rack, simply edit the "instructions" column within the table ItemLocation. Make sure that the value of this column is equal to or exceeds that of the "quantity" column or else the model will break.

20096-itemlocation.png

global-table-in-picking-model-with-row-batching-an.fsm

0 Likes
Message 3 of 7

tomonori_s
Not applicable

I have confirmed the model. Thank you very much.

In the simulation, the operator sometimes picks up the item without going to the front of the rack. Can this movement be made to go to the front of the rack and pick it up?

Also, is it difficult to rebuild the model for the optimizer if you want to find the shortest route?

0 Likes
Message 4 of 7

benjamin_w2
Not applicable

Hi @tomonori S, to make operators go to the front of the rack, make sure all racks are connected to the AStarNavigator.

In order for this model to run on the optimizer, we would most likely have to completely start over and re-design the logic. However, I believe that it is possible.

0 Likes
Message 5 of 7

tomonori_s
Not applicable

Hi Benjamin-san,
If the same part number is duplicated as in the attached image, it will be two pickings. Can you combine them into one picking?
In addition, it is a movement to direct the operator to the front of the rack. How should I connect the rack and AStarNavigator?

img.png

0 Likes
Message 6 of 7

benjamin_w2
Not applicable

Hi @tomonori S-san,

Yes, you should be able to fix this very easily. Notice that the row headers are the same, but the "OrderID" column is different. It looks like order 82 maps to OrderID 6. simply change the first red box to have an OrderID of 6 and you should be good to go.

To connect the rack to A*, simply make A-connections from each rack to the A* in the 3D model.

0 Likes
Message 7 of 7

tomonori_s
Not applicable

We changed order 82 to order ID 6, but we were not able to combine them into one picking.
Also, because I do not know how to direct the operator to the front of the rack, could you improve the attached model?

img.png

test-01.fsm

0 Likes