question

tomonori S avatar image
0 Likes"
tomonori S asked tomonori S commented

How to pick items based on distance?

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

FlexSim 18.0.10
global tablepickingdistance
5 |100000

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

1 Answer

Benjamin W2 avatar image
0 Likes"
Benjamin W2 answered tomonori S commented

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:

  1. /**Custom Code*/
  2. Object current = param(1);
  3. treenode activity = param(2);
  4. Token token = param(3);
  5. Variant assignTo = param(4);
  6. string labelName = param(5);
  7. treenode processFlow = ownerobject(activity);
  8. int orderArraySize = token.Orders.length;
  9. Array orderedOrders = Array(0);
  10. Array Orders = token.Orders;
  11. Object aquiredOperator = token.Picker.as(Object);
  12. double shortestDistance = 0.0;
  13. int shortestIndex = 0;
  14. for (int i = 1; i <= Orders.length; i++)
  15. {
  16. double tempDistance = 0.0;
  17. Object object1 = aquiredOperator;
  18. Object object2 = Orders[i].Rack;
  19. double x1 = vectorprojectx(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
  20. double y1 = vectorprojecty(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
  21. double z1 = vectorprojectz(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
  22. double x2 = vectorprojectx(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
  23. double y2 = vectorprojecty(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
  24. double z2 = vectorprojectz(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
  25. tempDistance = sqrt(sqr(x1 - x2) + sqr(y1 - y2) + sqr(z1 - z2));
  26. if ((i == 1) || (tempDistance < shortestDistance))
  27. {
  28. shortestDistance = tempDistance;
  29. shortestIndex = i;
  30. }
  31. if (i == Orders.length)
  32. {
  33. orderedOrders.push(Orders[shortestIndex]);
  34. Orders.splice(shortestIndex,1);
  35. }
  36. }
  37. for (int i = 1; i <= orderedOrders.length; i++)
  38. {
  39. double tempDistance = 0.0;
  40. Object object1 = orderedOrders[i].Rack;
  41. for (int j = 1; j <= Orders.length; j++)
  42. {
  43. Object object2 = Orders[j].Rack;
  44. double x1 = vectorprojectx(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
  45. double y1 = vectorprojecty(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
  46. double z1 = vectorprojectz(object1, 0.5 * xsize(object1), -0.5 * ysize(object1), 0, model());
  47. double x2 = vectorprojectx(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
  48. double y2 = vectorprojecty(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
  49. double z2 = vectorprojectz(object2, 0.5 * xsize(object2), -0.5 * ysize(object2), 0, model());
  50. tempDistance = sqrt(sqr(x1 - x2) + sqr(y1 - y2) + sqr(z1 - z2));
  51. if ((j == 1) || (tempDistance < shortestDistance))
  52. {
  53. shortestDistance = tempDistance;
  54. shortestIndex = j;
  55. }
  56. if (j == Orders.length)
  57. {
  58. orderedOrders.push(Orders[shortestIndex]);
  59. Orders.splice(shortestIndex,1);
  60. }
  61. }
  62. }

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.

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


· 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.