Item sorter robot

Item sorter robot#

https://upload.wikimedia.org/wikipedia/commons/1/16/UR16e_robot_arm.png

Fig. 25 A robot arm with the pendant.
CC BY-SA 4.0. By Auledas. Source: Wikimedia Commons
#

Robot arms can automatize industrial processes like sorting trash for recycling and manufacturing cars. In this problem we are going to do neither of these two but build up on the top of the inventory system instead and prepare an order for shipment.

Previously we built a GUI for order processing. Now, the robot will automatically collect the items in an order in a box after an order is processed as follows.

The robot picks first one type three types of countable items which are in the boxes represented by a, b and c. After picking them, the arm places them in the shipment box represented by S:

 0  1  2  3 ️→ (y)
 1  a
 2  b  
 3  c     S
 4
 ↓
(x)

Note that the x and y axis are rotated according to the coordinate system of the robot. In the simulator 🟥, 🟩, and 🟦 colored dashed lines are x, y and z axis, respectively.

The robot picks one items from a, two items from b and one item from c according to the first order.

Note

This problem assumes that you have installed the robot simulator.

Requirements and assumptions:

  1. Continue code from the previous project (inventory system). You already committed the inventory system project, so the state of the old project will not be lost.

    Warning

    Do not create a new solution and build up on the previous one.

  2. Assume that your orders can have up to three countable items, which are placed in inventory boxes a, b, c. The shipment box is placed on S. So you have to pick items in the order from the inventory boxes and place them in the shipment box S:

  3. Use the following class:

using System.Net.Sockets;
using System.Text;

namespace InventorySystem;

public class Robot
{
    public const int urscriptPort = 30002, dashboardPort = 29999;
    public string IpAddress = "localhost";


    public void SendString(int port, string message)
    {
        using var client = new TcpClient(IpAddress, port);
        using var stream = client.GetStream();
        stream.Write(Encoding.ASCII.GetBytes(message));
    }

    public void SendUrscript(string urscript)
    {
        SendString(dashboardPort, "brake release\n");
        SendString(urscriptPort, urscript);
    }
}
  1. Create a class ItemSorterRobot that inherits from Robot.

    ItemSorterRobot includes a configurable URScript template UrscriptTemplate that has a placeholder {0} which represents the x coordinate of the item that has to be picked. We don’t need another parameter, because y-coordinate of the item boxes are the same and the shipment boxes position is also fixed. UrscriptTemplate could look like this:

        public const string UrscriptTemplate = @"
    def move_item_to_shipment_box():
        SBOX_X = 3
        SBOX_Y = 3
        ITEM_X = {0}
        ITEM_Y = 1
        DOWN_Z = 1
    
        def moveto(x, y, z = 0):
        ...
    "
    

    SBOX stands for shipment box, ITEM for the item types and DOWN for the down movement for picking up the items from the item boxes. _X and _Y correspond to x, y coordinates, respectively.

    UrscriptTemplate is used by the method PickUp(uint itemId). You can insert itemId to the UrscriptTemplate by using string.Format(UrscriptTemplate, itemId) like we have seen in section Strings and then send the resulting program using Robot.SendUrscript().

  2. You have to get the list of order lines from an order so you can control the robot program accordingly. For example, ProcessNextOrder could return a list of order lines.

  3. Whenever you send a program, the old program is overwritten. As we don’t have any feedback from the robot, use about 10 seconds for each movement to complete.

If you use Thread.Sleep(10000), then the GUI will freeze until the end of the sleep. You can use Task.Delay() as an alternative, but you have to write async in the function definition as follows:

  public async void Button_OnClick()
  {
      StatusMessages.Text += "Processing order" + Environment.NewLine;
      foreach (var orderLine in OrderBook.ProcessNextOrder())
          for (var i = 0; i < orderLine.Quantity; ++i)
          {
              StatusMessages.Text += $"Picking up {orderLine.Item.Name}" + Environment.NewLine;
              robot.PickUp(orderLine.Item.InventoryLocation);
              await Task.Delay(9500);
          }
  }

async makes a function asynchronous. Asynchronous functions do not stop program execution (e.g., GUI) while doing operations themselves.

  1. For the item box coordinates use the positions above. The distance between 0-1, 1-2 etc, is 10 cm.

    For example, the origin of the coordinate system drawn above corresponds to the robot tool coordinates (0, 0.1). So a would be at position (0 + 0.1, 0.1) and b at (0 + 2 * 0.1, 0.1).

  2. For picking up, the robot needs to move down 10 cm.

    Don’t care about grabbing and releasing the item – assume there is an tool attached to the robot and it automatically picks up and releases the items. So you don’t have to care about this.

  3. Add an additional field uint InventoryLocation to Item. This is the location of the item in the inventory which we will use to pick up items from with the robot arm.

  4. Test your system with the following objects and code:

         var item1 = new UnitItem
         {
             Name = "M3 screw",
             PricePerUnit = 1,
             InventoryLocation = 1
         };
         var item2 = new UnitItem
         {
             Name = "M3 nut",
             PricePerUnit = 1.5m,
             InventoryLocation = 2
         };
         var item3 = new UnitItem
         {
             Name = "pen",
             PricePerUnit = 1,
             InventoryLocation = 3
         };
         var orderLine1 = new OrderLine
         {
             Item = item1,
             Quantity = 1
         };
         var orderLine2 = new OrderLine
         {
             Item = item2,
             Quantity = 2
         };
         var orderLine3 = new OrderLine
         {
             Item = item3,
             Quantity = 1
         };
         var order1 = new Order
         {
             OrderLines = [orderLine1, orderLine2, orderLine3],
             Time = DateTime.Now - TimeSpan.FromDays(2)
         };
         var order2 = new Order
         {
             OrderLines = [orderLine2],
             Time = DateTime.Now
         };
    
         var customer1 = new Customer
         {
             Name = "Ramanda",
             Orders = []
         };
         var customer2 = new Customer
         {
             Name = "Totoro",
             Orders = []
         };
    
    
         customer1.CreateOrder(OrderBook, order1);
         customer2.CreateOrder(OrderBook, order2);
    
  5. Assume that the shipment boxes are automatically moved by a conveyor belt after one order is processed. In other words, there is an empty box waiting at shipment box position after you are done with the previous order.

  6. Optional: Add a TextBlock which shows status messages as shown in the video.

  7. Include the updated class diagram

  8. Create a video