Visual Components' Community

New Thinking for Factory Simulation
Welcome to Visual Components' Community Sign in | Help
in Search

Request: example for using component containers with python

Last post ti, maalis 3 2009 15:22 by krotta. 1 replies.
Page 1 of 1 (2 items)
Sort Posts: Previous Next
  • ma, maalis 2 2009 13:41

    • krotta
    • Top 25 Contributor
    • Joined on pe, helmi 22 2008
    • Kuopio, Finland
    • Posts 4

    Request: example for using component containers with python

    How to accomplish the following (rather common) behaviour on the production line using python script?

    Example

    Two part classes:
      1. Rack (container part) - with capacity of 20 parts. Predefined positions for the parts.
      2. Cell


    Elements:
     - Component creators for rack and simple-parts.
     - Three conveyours (rack in, cell in, rack out)
     - Table

    Material flow:
    Racks and cells are transfered along separate conveyors to the table.
    After the rack is placed on the table we'll wait for the cells to arrive.
    Every time cell arrives, we place it in the rack (with 20sec work time) and this continues until the rack capacity is full.
    After rack is filled it will be moved out along the final conveyour - and we'll let in the next rack.

    ---
    Even though this is probably quite simple thing to do I can't figure out how to place cells into certain positions of the container part with python.

    Grab command grabs the cell to the rack but doesn't allow the exact placement. Rack has predefined position for cells (using single coordinate with offsets would work just fine) and I we'll need to put the parts into those.

    FillContainer sounds like a working solution except there is no possibility to add single part to the container - only available command is "Fill" which is not suitable here.

    Here is the script that works just fine except for the container part positions>>

    from vcScript import *

    def OnRun():
      comp = getComponent()
      rackpath = comp.findBehaviour("path_RACK")
      cellpath = comp.findBehaviour("path_CELL")
      racksignal = comp.findBehaviour("signal_RACK")
      cellsignal = comp.findBehaviour("signal_CELL")
     
      while True:
        cellpath.Enabled = False
        #waiting for a rack to arrive
        triggerCondition(lambda: getTrigger() == racksignal)
        rack = racksignal.Value
        #rack has arrived - only one rack at the time on the table so disable the rackpath.
        rackpath.Enabled = False
        if (rack <> None):
          #finding out the container part behaviour from the rack and stopping the rack
          cpart = rack.findBehaviour("ComponentContainer")
          rack.stopMovement()
          print "start loading the rack [" + rack.Name + "] Capacity [" + str(cpart.Capacity) + "]"
        else:
          print"error - rack == none!" #just in case of faulty signal
          continue

        while (cpart.ComponentCount <= cpart.Capacity):
          print "[" + str(cpart.ComponentCount) + "/" + str(cpart.Capacity) +"] waiting for next part"
          cellpath.Enabled = True
          triggerCondition(lambda: getTrigger() == cellsignal)
          cellpath.Enabled = False
          cell = cellsignal.Value
          cpart.grab(cell)
          print "cell grabbed"
        print "rack full"
        rack.startMovement()
        cellpath.Enabled = True
        rackpath.Enabled = True

    ---------

     So the question is: how do I place parts into another container to predefined positions using python?

  • ti, maalis 3 2009 15:22 In reply to

    • krotta
    • Top 25 Contributor
    • Joined on pe, helmi 22 2008
    • Kuopio, Finland
    • Posts 4

    Re: Request: example for using component containers with python

    Nevermind, I figured it out. It was rather easy - creating another positionmatrix and assigning it to the part inside ComponentContainer seems to work fine.

    In case someone is having similar problems, here is one solution. It is not perfect but good enough for me.

    Table needs to have two one-way paths, inputs, sensors and signals (for the paths), one output and a python script. Rack needs to have ContainerComponent and a frame for offset calculation starting point.

    Python script for the table:

     

    from vcScript import *
    import math
    import vcMatrix
    import vcVector

    def printPosMatrix(mat):
      for Vec in [mat.P]:
        print ("Positio: %3.3g\t%3.3g\t%3.3g\t%3.3g"%(Vec.X,Vec.Y,Vec.Z,Vec.W))

    def GetCellLocation(rack,cell):
      if (rack == None):
        print "rack == NULL!"
        return
      if  (cell == None):
        print "cell == NULL!"
        return
      # find reference frame location from the rack
      #print "get Cell Location from " + rack.Name + " cell [" + cell.Name + "]"
      frame = rack.findFeature("f1")
      if not frame:
        return(None,None)
     
      cpart = rack.findBehaviour("ComponentContainer")
      # calculate next free position (slot) on the rack
      if (cpart.ComponentCount > 0):
        if (cpart.ComponentCount <= cpart.Capacity):
          #print "cpart.ComponentCount[" + str(cpart.ComponentCount) +"] capacity[" + str(cpart.Capacity) +"]"
          
          #rack has 8 vertical trays with capacity of 8 cells / tray, let's calculate which one is next to be filled
          tray_nodec = cpart.ComponentCount / 8.0
          slot = 0.125 # calculating the divider for the slots
          abs_position = tray_nodec / slot #absolute position should be equal to the cpart.ComponentCount...
          
          #because round() command does not work properly we are using imported math.ceil function to perform rounding
          #finding out the tray number (1-8)
          tray_no = math.ceil(tray_nodec)
          if (tray_no == 0):
            tray_no = 1
            
          #finding out the slot position on the tray_no
          if (tray_no > 1):
            slot_pos = abs_position-8*(tray_no-1)
          else:
            slot_pos = abs_position
                
          #print "tray_nodec[" + str(tray_nodec) + "] slot[" + str(slot) +"] abs_position[" + str(abs_position) +"]"
          #print "tray_no:" + str(tray_no) + " slot_position " + str(slot_pos)
          
          #define the stepsizes
          stepsize_X = 154
          stepsize_Y = 400
          stepsize_Z = -310
          
          #create new positionmatrix
          framemat = frame.PositionMatrix.P
          newmat = vcMatrix.new()
          
          #rotate the part to correct position
          newori = newmat.WPR
          newori.X = 0
          newori.Y = 90
          newori.Z = 0
          
          newpos = newmat.P
          newpos.W = 1
          if (tray_no == 1):
            #first tray needs no X-adjustment
            newpos.X = framemat.X
            newpos.Z = framemat.Z
            if (slot_pos ==1):
              newpos.Y = framemat.Y
            elif (slot_pos > 1) and (slot_pos <= 4):
              newpos.Y = framemat.Y + (slot_pos-1) * stepsize_Y
            else:
              newpos.Y = framemat.Y + (slot_pos-5) * stepsize_Y
              newpos.Z = framemat.Z + stepsize_Z
              
          else: #if tray > 1, we need to adjust X, too
            newpos.X = framemat.X + ((tray_no-1) * stepsize_X)
            newpos.Z = framemat.Z
            if (slot_pos ==1):
              newpos.Y = framemat.Y
            elif (slot_pos > 1) and (slot_pos <= 4):
              newpos.Y = framemat.Y + (slot_pos-1) * stepsize_Y
            else:
              newpos.Y = framemat.Y + ((slot_pos-5) * stepsize_Y)
              newpos.Z = framemat.Z + stepsize_Z
              
          #assing new position and rotation to the new positionmatrix
          newmat.P = newpos
          newmat.WPR = newori
          #printPosMatrix(newmat)

          #return positionmatrix with correct location information
          return(newmat)
         
         
    def OnRun():
      comp = getComponent()
      rackpath = comp.findBehaviour("path_RACK")
      cellpath = comp.findBehaviour("path_CELL")
      racksignal = comp.findBehaviour("signal_RACK")
      cellsignal = comp.findBehaviour("signal_CELL")
     
      while True:
        cellpath.Enabled = False
        #waiting for a rack to arrive
        triggerCondition(lambda: getTrigger() == racksignal)
        rack = racksignal.Value
        
        #rack has arrived - only one rack at the time on the table so disable the rackpath.
        rackpath.Enabled = False
        if (rack <> None):
          #finding out the container part behaviour from the rack and stopping the rack
          cpart = rack.findBehaviour("ComponentContainer")
          rack.stopMovement()
          print "start loading the rack [" + rack.Name + "] Capacity [" + str(cpart.Capacity) + "]"
        else:
          print"error - rack == none!" #just in case of faulty signal
          continue
          
          #continue filling the rack with cells until full
        while (cpart.ComponentCount < cpart.Capacity):
          print "rack capacity [" + str(cpart.ComponentCount) + "/" + str(cpart.Capacity) +"] waiting for next part"
          cellpath.Enabled = True
          
          #waiting for a cell to arrive
          triggerCondition(lambda: getTrigger() == cellsignal)
          cellpath.Enabled = False
          cell = cellsignal.Value
          
          #grab the cell into rack and assign new positionmatrix to it
          cpart.grab(cell)
          newpos = GetCellLocation(rack,cell)
          if (newpos <> None):
            cell.PositionMatrix = newpos
          
        #print "rack is full"
        rack.startMovement()
        cellpath.Enabled = True
        rackpath.Enabled = True

Page 1 of 1 (2 items)