Delft University of Technology
FACULTY MECHANICAL, MARITIME AND MATERIALS ENGINEERING
Department Marine and Transport Technology Mekelweg 2 2628 CD Delft the Netherlands Phone +31 (0)15-2782889 Fax +31 (0)15-2781397 www.mtt.tudelft.nl
This report consists of 74 pages and 2 appendices. It may only be reproduced literally and as a whole. For commercial purposes only with written authorization of Delft University of Technology. Requests for consult are only taken into consideration under the condition that the applicant denies all legal rights on liabilities concerning
Specialization: Production Engineering and Logistics
Report number: 2012.TEL.7765
Title:
Creating a standard component
for Automated Storage and
Retrieval Systems in Tomas Delphi
Author:
J.B.L. Schornagel
Title (in Dutch) Het creëeren van een standard component voor Automated Storage and Retrieval Systems in Tomas Delphi
Delft University of Technology
FACULTY MECHANICAL, MARITIME AND MATERIALS ENGINEERING
Department Marine and Transport Technology Mekelweg 2 2628 CD Delft the Netherlands Phone +31 (0)15-2782889 Fax +31 (0)15-2781397 www.mtt.tudelft.nl
This report consists of 74 pages and 2 appendices. It may only be reproduced literally and as a whole. For commercial purposes only with written authorization of Delft University of Technology. Requests for consult are only taken into consideration under the condition that the applicant denies all legal rights on liabilities concerning Assignment: Computer
Confidential: No
Initiator (university): Dr.Ir. H.P.M. Veeke
Delft University of Technology
FACULTY OF MECHANICAL, MARITIME AND MATERIALS ENGINEERING
Department of Marine and Transport Technology Mekelweg 2 2628 CD Delft the Netherlands Phone +31 (0)15-2782889 Fax +31 (0)15-2781397 www.mtt.tudelft.nl
Student: J.B.L. Schornagel Assignment type: Computer Supervisor (TUD): Dr.Ir. H.P.M. Veeke Creditpoints (EC): 10
Specialization: PEL
Report number: 2013.TL.7765 Confidential: No
Subject:
Creating a standard component for Automated Storage and Retrieval
Systems in Tomas Delphi
Samenvatting
De software-ontwikkelomgeving Delphi biedt gebruikers de mogelijkheid om zelf componenten te creëren. Dit simulatieonderzoek behandelt de creatie van een standaard component waarmee het mogelijk is om Automated Storage and Retrieval Systems (ASRS) te simuleren en te visualiseren. De permanente elementen van het systeem zijn:
Storage and Retrieval Machine (SRM): deze kan heen en weer bewegen tussen stellingen en pallets in en uitladen
Stellingen: deze kunnen aan één zijde of aan beide zijden aanwezig zijn Input Point waar pallets binnenkomen
Output Point waar vrijgegeven pallets in geplaatst worden door de ASRS De tijdelijke elementen van het systeem zijn:
Pallets: deze kunnen worden in- en uitgeladen door de SRM en opgeslagen worden in de stellingen, dit kunnen ook kratten zijn, maar dit maakt voor de simulatie niet uit
Orders: dit zijn verzoeken aan de ASRS om een bepaald pallet vrij te geven
Zie Figuur 1 voor een schematische weergave van het systeem. Om de opstelling met stellingen aan beide zijden van de SRM correct weer te geven in 2D is deze als het ware „opengeklapt‟. Het
zijaanzicht is hoe het component uiteindelijk gevisualiseerd wordt.
Figuur 1: Boven- en zijaanzicht ASRS met aan beide zijden stellingen
Het component bevat de informatiebronnen, berekeningen en visualisatiemogelijkheden om het component te laten functioneren. Daarnaast moet het component ook worden aangestuurd middels een beslisstrategie die bepaalt welke operatie wanneer en hoe wordt uitgevoerd. De beslisstrategie is onderdeel van het programma wat door de gebruiker geschreven wordt, zoals weergegeven in Figuur 2. 1,0 2,0 3,0 4,0 1,1 2,1 3,1 4,1 1,2 2,2 3,2 4,2 5,0 OutputX ShelveSlots ShelveLevels SRM Input Output Zijaanzicht (simulatie) 5,0 6,0 7,0 8,0 5,1 6,1 7,1 8,1 5,2 6,2 7,2 8,2 0,0 5,0 Output ShelveSlots InputX SR M H ei gh t y x x InputX OutputX 5 6 7 8 0 9 ShelveSlots SRM Bovenaanzicht Input Output OutputX InputX x 4 3 2 1 Beslisstrategie Informatiebronnen Calculations Paint Programma Component
Naast het definiëren van de beslisstrategie kan de gebruiker tevens in de Object Inspector de parameters van de ASRS aanpassen, bijvoorbeeld de dimensies van de stellingen en snelheden van de SRM.
Deze aanpak biedt het beste van twee werelden; de gebruiker is vrij om zich te richten op het logistieke vraagstuk en de beslisstrategie van de ASRS, terwijl het component de berekeningen uitvoert, voorziet in de informatie om deze beslissingen te nemen en de werking van het systeem visualiseert.
De SRM kan grofweg 3 verschillende operaties uitvoeren:
Storing: een pallet wat binnenkomt bij het Input Point wordt opgeslagen in een stelling
Retrieving: n.a.v. een order voor een pallet wordt een pallet gezocht, en naar het Output Point gebracht
Waiting: indien het systeem passief is
Het ASRS programma beschikt over de volgende bronnen waaruit het informatie kan putten: MyInputQueue waar binnengekomen pallets in geplaatst worden
MyOrderQueue waar orders voor opgeslagen pallets binnenkomen MyOutputQueue waar uitgegeven pallets in geplaatst worden MyShelveQueue wat de pallets bevat die in de stellingen staan
ShelveMatrix[slot,level] houdt bij welk pallet waar op welke locatie staat
ShelveMatrixX en ShelveMatrixY welke de horizontale en verticale afstanden tussen de stellingen bewaren
CalculateDuration is een functie waarmee de verplaatsingsduur tussen twee punten kan worden berekend
CountEmptySlots geeft het aantal lege ShelveSlots
Pallets komen binnen via de MyInputQueue, waarna de SRM afhankelijk van de beslisstrategie kan besluiten om naar het InputPoint te bewegen om het pallet in te laden ergens in de stelling op te slaan. Indien het pallet wordt vrijgegeven door het ASRS systeem komt het in de MyOutputQueue.
Het component is in staat om naar aanleiding van de opdracht van het programma te berekenen hoelang de SRM erover doet om naar een bepaalde positie te bewegen. Vervolgens kan berekend worden waar de SRM zich bevindt op een bepaald moment en kan het component dit weergeven op het canvas.
Summary
The software design package Delphi allows users to create their own components. This simulation research discusses the creation of a standard component capable of simulating and visualizing an Automated Storage and Retrieval Systems (ASRS).
Permanent elements of such a system are:
Storage and Retrieval Machine (SRM): a platform capable of moving back and forth between shelves and able to load or unload pallets
Shelves: these can be either shelves on only one side, or both sides of the SRM Input Point: this is where pallets enter the system
Output Point: this is where handled pallets exit the system
The temporary elements of the system are:
Pallets: the can be loaded or unloaded by the SRM and stored in the shelves, these could also be crates, however this is not relevant to the simulation
Orders: this is a request from the environment for a certain stored pallet
Figure 1 is a schematical representation of the system. To correctly display the emplacement with a shelve on each side of the SRM, the emplacement is sort of ´unfolded´. The sideview in de figure is how the component will be displayed in the simulation.
Figuur 1: Top and side view of the ASRS with shelves on both sides
The component contains all the information resources, calculations and visualization capabilities to let if function properly. It is required the the component must be controlled by a decision strategy that determines which operation is performed when and how. The decision strategy is free to be picked by the user, because it is part of the program that the user can write for the component, as visualized in Figure 2. 1,0 2,0 3,0 4,0 1,1 2,1 3,1 4,1 1,2 2,2 3,2 4,2 5,0 OutputX ShelveSlots ShelveLevels SRM Input Output Zijaanzicht (simulatie) 5,0 6,0 7,0 8,0 5,1 6,1 7,1 8,1 5,2 6,2 7,2 8,2 0,0 5,0 Output ShelveSlots InputX SR M H ei gh t y x x InputX OutputX 5 6 7 8 0 9 ShelveSlots SRM Bovenaanzicht Input Output OutputX InputX x 4 3 2 1 Beslisstrategie Informatiebronnen Calculations Paint Programma Component
Apart from defining the decision strategy, the user is also free to adjust the components parameters in the Object Inspector, for example the dimensions of the shelves and the movement characteristics of the SRM.
This approach offers best of both worlds; the user is free to focus on the logistical characteristics and decision strategy of the ASRS, while the component handles all calculations, supplies the program with the information required to take these decisions and is able to visualize the whole system. The ASRS possesses the following Queues that can be accessed by the program:
MyInputQueue where incoming pallets are placed
MyOrderQueue where orders for stored pallets enter the system MyOutputQueue where the issued pallets are placed
MyShelveQueue contains all pallets stored in the shelves
Roughly, the SRM can perform three different operations:
Storing: an incoming pallet at the Input Point will be stored in a shelve
Retrieving: after an order has been issued, the concerning pallet is looked up and transported to the Output Point
Waiting: when the system is idle
Pallets enter the system through the MyInputQueue. After this the SRM can determine, depending on its decision strategy, to move to the Input Point to load the pallet and store it in one of the sheves. If an order is issued for a pallet in the MyOrderQueue, the SRM can decide to execute this order, after which it looks up the position of the concerning pallet, loads it and the unloads the pallet at the Output Point, making the pallet enter the MyOutputQueue
Based on the operation the component is performing declared by the program, the component is able to calculate the movement duration of the component to a certain position. This also allows the component to calculate the exact whereabouts of the SRM at a certain moment, so the component can draw the SRM on the proper location on the component‟s canvas.
Components can also be connected to each other. This can be done in two ways; i) the pallet places itself from the MyOutputQueue of the first component in the MyInputQueue of the next component or ii) the component itself moves the pallet upon issueing a pallet in the MyOutputQueue automatically to the MyInputQueue of the next component.
Afkortingen
DTC Design Time Component
ASRS Automated Storage and Retrieval System SRM Storage Retrieval Machine
Inhoudsopgave
Samenvatting ... 4
Afkortingen ... 5
Inhoudsopgave ... 8
1 Introductie... 9
2 Inleiding ASRS en parameters ...10
2.1 Inleiding ASRS ...10
2.2 Parameters ASRS ...11
2.3 Weergave ASRS component ...12
2.4 Interactie component met programma ...14
3 Basisregels voor het creëren en installeren van een custom component ...16
3.1 Creëren van een component in een Package ...16
3.2 Component installeren ...19
3.3 Het component gebruiken in een formulier applicatie ...20
4 Uitwerken onderdelen ASRS component ...21
4.1 Implementeren properties ...21
4.2 Filteren gebruikersinvoer ...26
4.3 Aanpassen Create procedure ...27
4.4 Predrawing ...28
4.5 Ingebouwde procedures component ...29
4.6 Positie bepalende functies ...31
4.6.1 Situatie 1: Vmax wordt niet bereikt ...31
4.6.2 Situatie 2: Vmax wordt wel bereikt ...33
4.6.3 Implementatie code positiebepaling ...35
4.7 Paint ...38
5 Programma ASRS component ...41
5.1 Uitdagingen bij het creëren van een ASRS component ...42
5.1.1 Tomascode gebruiken in een Custom Component ...42
5.1.2 Verdeling code tussen component en unit file ...42
5.1.3 Interactie component en unit file ...43
5.1.4 Foutmeldingen tijdens schrijven component ...43
6 Conclusie...44
7 Referenties ...45
Bijlage A: Volledige code ASRSComponent ...46
Introductie
Voor het simuleren van complexe logistieke systemen is Tomas Delphi een uitstekend softwarepakket. Hoewel de software een gebruiksvriendelijke manier is om complexe logistieke systemen te simuleren, komt het helaas wel vaak voor dat deze systemen vaak vanuit het niets moeten worden opgebouwd. Het hergebruik van code komt erg weinig voor, terwijl tegelijkertijd verschillende logistieke systemen veelal dezelfde elementen bevatten. Het hergebruiken van code voor veelvoorkomende
(sub)systemen zou de efficiency van het gebruik van het programma dus ten goede komen.
Delphi biedt gebruikers de mogelijkheid om zelf een DTC (Design Time Component, hierna component genoemd) te creëren. Eerdere simulatiestudies (Crooijmans, 2010) (Hartsink, 2011) hebben aangetoond dat het mogelijk is om eenvoudige componenten te creëren en deze te gebruiken voor simulaties. Op dit onderzoek wordt nu voortgebouwd door te onderzoeken of het ook mogelijk is om een complex component als een ASRS systeem te maken wat ook bruikbaar is in een simulatie.
Bij het creëren van een ASRS component is gekeken vanuit het perspectief van de gebruiker.
Hiermee wordt bedoeld dat het voor de gebruiker zo eenvoudig mogelijk moet zijn om het component te gebruiken en dat er zoveel mogelijk „standaard berekeningen‟ door het component zelf kunnen worden verricht, zodat de gebruiker van het component zich volledig met het logistieke vraagstuk kan bezighouden. Daarnaast moet de gebruiker ook in voldoende mate de beslisstrategie van het
component kunnen beïnvloeden. Hieruit volgt de onderzoeksvraag:
Hoe is het mogelijk om een standaard component voor een ASRS systeem te implementeren in Tomas Delphi, waarbij de gebruiker aan de hand van een door hem gekozen beslisstrategie het component kan aansturen?
Het hebben van een beslisstrategie vormt tevens de grootste uitdaging bij het creëren van dit component. Een ASRS systeem handelt namelijk niet passief, zoals een lopende band, waar iets op gaat en er na een vaste tijd weer af komt. Een ASRS systeem neemt beslissingen, bijvoorbeeld de beslissing waar een pallet tijdelijk wordt opgeslagen. De strategie die het systeem volgt heeft grote invloed op het uiteindelijke gedrag van het systeem en het is een eis dat deze aansturing door de gebruiker te beïnvloeden is.
Om een antwoord te geven op de hoofdvraag zal in sectie 1 uiteengezet worden wat een ASRS precies is en welke parameters van belang zijn voor het component. Sectie 2 behandeld hoe de basis van het component gecreëerd kan worden, waarna in sectie 3 de verschillende onderdelen van het component worden belicht. Sectie 4 behandelt nog kort de eigenschappen van het programma welke het component aanstuurt, waarna in sectie 5 de uitdagingen die bij het ontwerpen kwamen kijken worden behandeld. Uiteindelijk wordt de hoofdvraag van het rapport in sectie 6 beantwoord.
1
Inleiding ASRS en parameters
1.1 Inleiding ASRS
Het ontwerpen van een component voor een ASRS begint met de vraag; „Wat is een ASRS?‟ Een ASRS wordt gebruikt om automatisch goederen, die op pallets staan of in kratten liggen, tijdelijk op te slaan en weer uit te geven als daar behoefte aan is.
De voordelen van het gebruik van een ASRS voor het tijdelijke opslaan en distribueren zijn (Loudin, 2005):
- Lager risico op ongevallen voor het personeel - Efficiënt ruimtegebruik
- Minder personeel nodig vergeleken met handmatige opslag/vorkheftrucks
- Geschikt om te werken bij lage temperaturen (voedsel), daarnaast indien van toepassing, kleinere koeling noodzakelijk
- Beter overzicht inventaris
- Betere controle over tijdige distributie van goederen - Hogere doorvoersnelheden
Een ASRS bestaat uit één of meerdere stellingen en een SRM (Storage Retrieval Machine). De SRM is in staat om tussen de stellingen heen en weer te rijden over een rechte lijn en tevens ook omhoog en omlaag te bewegen. Daarnaast kan de SRM pallets inladen en uitladen. Belangrijk is dat alle pallets binnen de afmeting limieten blijven, zodat deze altijd in de stellingen passen. Daarnaast heeft het systeem een vast invoerpunt. Het uitvoerpunt van de pallets kan tevens het invoerpunt zijn of een apart uitvoerpunt. Zie Figuur 1 voor een schematisch overzicht.
Hiermee zijn enkele de kritieke onderdelen van het systeem bepaald. Dit zijn tevens de permanente elementen: Stelling(en) SRM Inputpunt Outputpunt (optioneel)
Naast de permanente elementen worden er ook tijdelijke elementen uitgewisseld met de omgeving. Dit zijn:
Pallets (dit kunnen ook kratten zijn, echter wordt hierna de term pallets aangehouden) Orders
Pallets komen het systeem binnen via het invoerpunt. Vervolgens worden deze in de stellingen geplaatst in een ShelveSlot. Ieder ShelveSlot is een positie in een stelling waar één pallet kan worden opgeslagen.
Indien de omgeving behoefte heeft aan een pallet wordt er bij de ASRS een order voor een pallet geplaatst. De ASRS kan deze order vervolgens in behandeling nemen en een pallet uitvoeren.
1.2 Parameters ASRS
Voor het systeem zijn een aantal parameters geïdentificeerd welke door de gebruiker moeten kunnen worden veranderd. Deze parameters zijn weergegeven in Tabel 1.
Type Omschrijving Parameter Eenheid
Stellingen 1: eenzijdige stelling, 2: dubbelzijdige stelling ShelveSides [-] Aantal kolommen per stelling ShelveSlots [-] Aantal levels per stelling ShelveLevels [-]
Slot breedte SlotWidth [m]
Slot hoogte (level hoogte) SlotHeight [m]
Pallets Pallet breedte PalletWidth [m]
Pallet hoogte PalletHeight [m]
Input Point Afstand tot stelling(en) InputX [m]
Afstand tot vloerniveau (kan ook negatief zijn) InputY [m]
Output Point Afstand tot Input Point OutputX [m]
Afstand tot vloerniveau (kan ook negatief zijn) OutputY [m]
SRM Horizontale acceleratie AccX [m/s2]
Horizontale deceleratie DecX [m/s2]
Maximale horizontale snelheid VmaxX [m/s]
Verticale acceleratie AccY [m/s2]
Verticale deceleratie DecY [m/s2]
Maximale verticale snelheid VmaxY [m/s]
Tijdsduur inladen pallet LoadDuration [s]
Tijdsduur uitladen pallet UnloadDuration [s] Tabel 1: Parameters ASRS component
Globaal gezien kan een ASRS drie verschillende type operaties uitvoeren: Storing: Er wordt een binnenkomend pallet opgeslagen in een ShelveSlot
Iedere operatie kan weer verder worden onderverdeeld in sub-operaties: Storing:
o Vind lege opslag locatie FindStoreLoc o Beweeg naar het Input Point MoveTo Input Point o Laad pallet in Load Pallet
o Beweeg naar het opslag locatie MoveTo Store Location o Laad pallet uit Unload Pallet
o Wacht Retrieving:
o Vind pallet in stellingen FindRetrievalLoc
o Beweeg naar opslag locatie MoveTo Retrieval Location o Laad pallet in Load Pallet
o Beweeg naar Output Point MoveTo Output Point o Laad pallet uit Unload Pallet
o Wacht Suspend
1.3 Weergave ASRS component
De manier waarop het component zal worden weergegeven staat los van het grootste deel van de code. Toch is het voor de beeldvorming over het uiteindelijke functioneren van het component zinvol om dit onderwerp te belichten alvorens de daadwerkelijke code zal worden behandeld.
Belangrijk voor de opstelling van de ASRS is het aantal stellingen. Er is hierin onderscheid te maken tussen een ASRS met een enkele stelling, welke eigenlijk vrij zelden voorkomt, en de vaker
voorkomende dubbele stellingen.
Figuur 1 is een schematische weergave van zowel het zijaanzicht als het bovenaanzicht van een ASRS met een enkele stelling. Zoals te zien is is er een apart Input Point en een Output Point. Tussen deze punten zijn de stellingen, welke bestaan uit ShelveLevels en ShelveSlots. Iedere ShelveSlot is een vaste locatie in een stelling waar mogelijk een pallet kan worden geplaatst.
De x-as is geplaatst in het horizontale vlak en de y-as in het verticale vlak. De oorsprong bevindt zich op grondniveau in het midden van het Input Point en alle overige elementen worden bepaald ten opzichte van dit punt.
De afstand tussen het midden van het Input Point en het midden van het eerste ShelveSlot is InputX. De afstand tussen het midden van het Input Point en het midden van het Output Point is OutputX.
Tevens wordt gewerkt met een systeem om duidelijk de positie aan te geven van de verschillende elementen. Zo is de input altijd 0,0. Voor de stellingen wordt verder de syntaxis
ShelveSlot,ShelveLevel aangehouden. Bijvoorbeeld 3,1 betekend het 3e ShelveSlot op het 1e ShelveLevel. Het Output Point wordt altijd aangegeven met ShelveSlots+1,0
Figuur 1: Zij- en bovenaanzicht ASRS enkele stelling
Het onderste deel van Figuur 2 is het bovenaanzicht van een ASRS met aan beide zijden een stelling. Om tot een 2D weergave van de zijkant te komen is geredeneerd vanuit het punt x=0, waarbij de beide kanten van het systeem als het ware worden „opengeklapt‟. Zo zijn bij twee rijen van 4 Slots elk, Slots 4 en 5 het dichtst bij het Input Point en Slots 1 en 8 er het verst vandaan. Het positienummer van het Output Point is nu altijd 2 x ShelveSlots + 1,0
1,0 2,0 3,0 4,0 1,1 2,1 3,1 4,1 1,2 2,2 3,2 4,2 0,0 5,0 OutputX ShelveSlots ShelveLevels SRM Input Output 1 2 3 4 0 5 ShelveSlots SRM
Zijaanzicht (simulatie)
Bovenaanzicht
Input Output OutputX InputX SR M H ei gh t SlotHeight SlotWidth y x x InputX 1,0 2,0 3,0 4,0 1,1 2,1 3,1 4,1 1,2 2,2 3,2 4,2 5,0 OutputX ShelveSlots ShelveLevels SRM Input Output
Zijaanzicht (simulatie)
5,0 6,0 7,0 8,0 5,1 6,1 7,1 8,1 5,2 6,2 7,2 8,2 0,0 5,0 Output ShelveSlots InputX SR M H ei gh t y x x InputX OutputX 5 6 7 8 0 9 ShelveSlots SRMBovenaanzicht
Input Output OutputX InputX x 4 3 2 11.4 Interactie component met programma
Voordat wordt begonnen met programmeren wordt eerst gekeken naar de functies die het component moet kunnen uitvoeren en de interactie met het programma wat het component zal gaan gebruiken. Hierbij is gekozen voor een component wat alle gegevens van de ASRS beheerd. Deze gegevens kunnen door het programma worden opgevraagd. Op basis hiervan wordt middels een beslisstrategie bepaald welke operatie uitgevoerd wordt. Deze informatie wordt weer terug naar het component gecommuniceerd, waarna het component de nieuwe staat van het systeem berekend. Met deze informatie kan vervolgens de toestand getekend worden. Zie voor een schematische weergave van dit proces Figuur 3.
Figuur 3: Schematische weergave interactie component met programma, globaal
Het doel van deze indeling is dat het component hierdoor beschikt over alle noodzakelijke code om te kunnen functioneren, maar dat de gebruiker vrij laat om een beslisstrategie voor het systeem te creëren in het programma.
Het globale ontwerp kan vervolgens verder gedetailleerd worden. Zo beschikt de beslisfunctie over informatie uit de volgende bronnen:
ShelveMatrix: deze weet van iedere ShelveSlot of, en welk pallet hierin staat
ShelveMatrixDistX: deze bevat de horizontale afstand tussen zowel de ShelveSlots als de in- en output
ShelveMatrixDistY: deze bevat de verticale afstand tussen zowel de ShelveSlots als de in- en output
CalculateDuration: hiermee kan voor elke willekeurige begin- en eindlocatie de verplaatsingsduur worden berekend
CountEmptySlots: geeft het aantal lege slots Queues:
o MyInputQueue: Alle binnenkomende pallets worden in deze Queue geplaatst o MyOutputQueue: Uitgevoerde pallets n.a.v. een order komen in deze Queue o MyShelveQueue: Alle pallets die in shelves zijn opgeslagen zitten in deze Queue o MyOrderQueue: Alle uitstaande orders zitten in deze Queue
Beslisstrategie
Informatiebronnen
Calculations
Paint
o MyPalletQueue: In deze Queue zit het pallet wat op dat moment verplaatst of in/uitgeladen wordt
Op grond van deze informatie neemt het programma een beslissing, zoals MoveTo, Load/Unload of Suspend (doe niets). Het component gebruikt deze informatie vervolgens om per tijdseenheid de positie van de elementen in het systeem weer te geven en deze uiteindelijk ook te tekenen. Een schematische weergave van dit proces is weergegeven in Figuur 4.
Figuur 4: Schematische weergave interactie component met programma, gedetailleerd
Beslisstrategie
ShelveMatrix
MoveTo
Load / Unload
SheleMatrixDistX
ShelveMatrixDistY
CalculateDuration
CountEmptySlots
CalculatePosition
[m]
[m]
pallet
itemnumbers
[s]
emptyslots
NewX,NewY
Load / Unload
Paint
Programma
Component
Suspend
set passive
MyQueues
input,output, etc.
2
Basisregels voor het creëren en installeren van een
component
2.1 Creëren van een component in een Package
Dit deel van het verslag is puur om de lezer bekend te maken met het creëren van een eenvoudig component. Dit is wel eens eerder behandeld in een voorgaand verslag, echter was het resulterende component van deze handleiding niet erg gebruiksvriendelijk met programmeren doordat constant geswitchte moest worden tussen de package en het programma en traden er foutmeldingen op als de componenten niet toegevoegd waren aan de library path.
De eerste stap die komt kijken bij het creëren van een component is de keuze van de Base Class. Een component wordt namelijk altijd afgeleid van een bestaand component. Doordat het component is afgeleid van een bestaand component erft (inherit) het ook de methoden en events van het reeds bestaande component. Het is dus belangrijk om een geschikt bestaand component als Base Class te kiezen die al zoveel mogelijk beschikt over de gewenste standaard procedures.
Er zijn vele verschillende Base Classes mogelijk om een nieuw component op te baseren. In het geval van het ASRS component is ervoor gekozen om dit te baseren op TGraphicControl omdat
TGraphicControl al over een Paint procedure beschikt (het is in staat om te tekenen), welke zowel in Run Time als in Design Time functioneert. Hierdoor kan de gebruiker voordat de simulatie wordt gestart in Design Time al zien wat het resultaat is van veranderde parameters.
De volgende stap is het plaatsen van het component in een Package, waarmee het ook kan worden geïnstalleerd. Het is mogelijk om meerdere componenten in één Package te plaatsen.
Middels de volgende stappen kan eenvoudig een component worden gecreëerd: 1. Creëer mappen voor de onderdelen
Maak 3 nieuwe mappen, bijvoorbeeld op het bureaublad en noem ze: a. ASRSPackage
b. ASRSProject c. ASRSProjectGroup
2. Creëer een package waarin de unit file van het component komt Open Embarcadero en klik op File > New > Package, zie Figuur 5a.
Als het goed is verschijnt er nu rechts bij de Project Manager een nieuwe ProjectGroup („ProjectGroup1‟) met hierin een package
3. Voeg een VCL Forms Application toe
Klik met rechts op de nieuwe ProjectGroup en selecteer Add new project.. > VCL Forms Application zie Figuur 5b.
4. Geef de bestanden de juist naam
Klik met rechts op „Package1‟ en verander de naam in „ASRSPackage‟ Klik met rechts op „Project1‟ en verander de naam in „ASRSProject‟ Klik met rechts op ´Unit1´ en verander de naam in ´ASRSUnit´ zie Figuur 5c.
5. Voeg de unit file van het component toe
Klik met rechts op de map „Contains‟ van „ASRSPackage‟ en kies Add new.. > Other zie Figuur 5d.
6. Kies nu Delphi Files > Component zie Figuur 5e.
7. Kies uit de lijst „TGraphicControl en druk op Next zie Figuur 5f. 8. Vul in:
a. Class name: TASRS b. Palette page: ASRS
c. Unit name: klik op de knop „…‟ en sla de unit op in de map op het bureaublad „ASRSPackage‟, noem de unit „ASRSComponent‟
Zie Figuur 5g. Klik Finish
9. Sla vervolgens nogmaals (nog onduidelijk waarom dit nogmaals gevraagd wordt) het bestand „ASRSComponent‟ op in de map op het bureaublad „ASRSPackage‟
10. Voeg de directories toe aan de library path Voeg nu de mappen toe aan de library:
Klik op Tools > Options en vervolgens op Library – Win 32 en daarna bij „Library Path‟ op de knop „…‟ Zoek nu met de knop Browse folder (met het map symbool) iedere map op uit stap 1 en klik telkens op Add zie Figuur 5h
Figuur 5: Screenshots component creëren
(a)
(b)
(c)
(d)
(e)
(f)
(h)
(g)
Het component „ASRSComponent‟ is nu gemaakt in een Package, waardoor het ook geïnstalleerd kan worden. Daarnaast is er een VCL Forms Application „ASRSUnit‟ aan de ProjectGroup toegevoegd, waardoor het gemaakte component eenvoudig kan worden getest en gedebugged, zonder dat telkens geswitchte hoeft te worden tussen de Package en de Project file.
Door op „ASRSComponent‟ te klikken kan de code van het component worden bekeken. In eerste instantie genereerd Delphi altijd de basis code, een soort van ruggengraat, voor het component.
unit ASRSComponent;
interface uses
SysUtils, Classes, Controls;
type
TASRS = class(TGraphicControl) private { Private declarations } protected { Protected declarations } public { Public declarations } published { Published declarations } end; procedure Register; implementation procedure Register; begin
RegisterComponents('ASRS', [TASRS]);
end;
end.
Code deel 1: Standaard code component
2.2 Component installeren
Klik met rechts op „ASRSPackage‟ > Install om het component te installeren Als alle voorgaande stappen correct zijn uitgevoerd is het component nu geïnstalleerd en verschijnt het scherm:
2.3 Het component gebruiken in een formulier applicatie
Om het geïnstalleerde component te gebruiken in een formulier applicatie, ga naar „ASRSUnit.dfm‟ en scrol rechtsonder in de Tool Palette naar ASRS, klap het venster uit en sleep het component TASRS naar het formulier.
Zie Figuur 7a.
Figuur 7: Het component gebruiken
Vervolgens wordt het component weergegeven op het formulier, zie Figuur 7b. Doordat er nog geen code is ingevoerd voor de Paint procedure wordt er nog niets getekend.
Door het component te selecteren kan de gebruiker linksonder in de Object Inspector de
eigenschappen (properties) van het component bekijken en aanpassen, zie Figuur 7c. Omdat er nog geen extra properties gedefinieerd zijn worden op dit moment alleen de basisproperties weergegeven.
3
Onderdelen ASRS component
Nadat de eerste stappen van sectie 2 zijn gezet om een basis component te creëren en te installeren, kan worden begonnen met het daadwerkelijke schrijven van de code van het component.
3.1 Implementeren properties
De eerste stap is om het component de juiste properties te geven. Wat erg belangrijk is voor het creëren van componenten zijn de properties en de manier waarop Delphi deze properties gebruikt. Het Engelse woord hiervoor is „encapsulation‟, wat zoveel betekent als inkapseling. Door properties in bepaalde secties te zetten, kan de gebruiker aangeven wanneer deze toegankelijk zijn.
Sectie Toegankelijkheid
Private Methods, Properties en Events die in deze sectie gedeclareerd worden zijn alleen
toegankelijk voor de unit waarin het component zit. Componenten in dezelfde unit hebben toegang tot elkaars Private variabelen.
Protected Methods, Properties en Events gedeclareerd in deze sectie zijn daarnaast ook toegankelijk voor iedere afgeleide class van deze class.
Public Methods, Properties en Events gedeclaereerd in deze sectie zijn overall toegankelijk. Published De properties / events in deze sectie zullen in de Object Inspector toegankelijk zijn. Deze
instellingen zijn Design Time warden die met het project opgeslagen worden.
Dit betekend dat alle properties, waarvan de gebruiker wil dat deze toegankelijk zijn voor het programma, in de sectie Public moeten staan. Wanneer de gebruiker daarnaast wenst dat ze ook in de Object Inspector worden weergegeven, staan ze in Published.
In Tabel 2 staan alle properties met een korte uitleg en of deze properties published zijn of niet. Een groot deel van de properties komt rechtstreeks overeen met de parameters uit sectie 1.2. Het overige deel is noodzakelijk voor de interactie met het programma wat het component aanstuurt.
Onderdeel Naam Soort Eenheid Published Omschrijving
Simulation TimeInterval Integer [-] Nee Teken acties per beweging
Visible Boolean [-] Ja Geeft aan of de animatie zichtbaar is
Dimensions Shelvesides Integer [-] Ja 1 in het geval van enkele stelling, 2 in het geval van een dubbele ShelveSlots Integer [-] Ja Aantal ShelveSlots per kant
ShelveLevels Integer [-] Ja Aantal ShelveLevels per kant
SlotWidth Double [m] Ja Breedte van een slot
SlotHeight Double [m] Ja Hoogte van een slot
PalletWidth Double [m] Ja Breedte van een pallet PalletHeight Double [m] Ja Hoogte van een pallet
InputX Double [m] Ja Afstand tussen midden Input Point en midden eerste ShelveSlot InputY Double [m] Ja Hoogte Input Point ten opzichte van vloerniveau
OutputX Double [m] Ja Afstand tussen midden Input Point en midden Output Point OutputY Double [m] Ja Hoogte Output Point ten opzichte van vloerniveau
ShelveMatrix[X,Y] Array (2 dimensies)
[-] Nee Bevat voor Input en Output Point en iedere ShelveSlot de itemnumber van het pallet, en anders een 0
ShelveMatrixDistX[X,Y] Array (2 dimensies)
[m] Nee Bevat voor Input en Output Point en iedere ShelveSlot de horizontale afstand tot de oorsprong
ShelveMatrixDistY[X,Y] Array (2 dimensies)
[m] Nee Bevat voor Input en Output Point en iedere ShelveSlot de verticale afstand tot de oorsprong
SRM AccX Double [m/s2] Ja SRM acceleratie in X richting
DecX Double [m/s2] Ja SRM vertraging in X richting
VmaxX Double [m/s] Ja SRM maximale snelheid in X richting AccY Double [m/s2] Ja SRM acceleratie in Y richting
DecY Double [m/s2] Ja SRM vertraging in Y richting
VmaxY Double [m/s] Ja SRM maximale snelheid in Y richting
MovingNumber Integer [-] Nee Geeft samen met TimeInterval aan hoever de beweging gevorderd is
MovingDuration Double [s] Nee Tijdsduur van een bepaalde verplaatsing van de SRM op basis van CurX, CurY, NewX, NewY
LoadDuration Double [s] Ja Tijdsduur van het laden van een pallet UnloadDuration Double [s] Ja Tijdsduur van het uitladen van een pallet
CurX Integer [-] Nee Huidige Slot
CurY Integer [-] Nee Huidige Level
TargetX Integer [-] Nee Mogelijk nieuwe Slot
TargetY Integer [-] Nee Mogelijk nieuwe Level
NewX Integer [-] Nee Het Slot waar de SRM naartoe moet bewegen NewY Integer [-] Nee Het Level waar de SRM naartoe moet bewegen
Operation String [-] Nee Operatie die de ASRS uitvoert, „Retrieving‟, „Storing‟ of „Waiting‟(Suspend) CurOrder String [-] Nee De huidige order die de ASRS aan het retrieven is
Inventory String [-] Nee Het Pallet ItemNumber wat de SRM aan het verplaatsen of laden is Action String [-] Nee De huidige actie die de ASRS uitvoerd
Om een property toe te voegen aan de code worden de volgende stappen uitgevoerd:
1. Plaats in het Protected gedeelte de variabele, voorafgegaan door de letter „F‟ (dit is niet noodzakelijk, maar standaard om niet in de war te raken met de property zelf)
2. Plaats in het protected gedeelte de procedure SetVariabele, zodat er later gefilterd kan worden op mogelijke onjuiste invoerwaarden van de gebruiker
3. Plaats in de Published sectie de naam van de property en hoe deze gelezen en verwijs voor het schrijven naar de SetVariabele procedure
4. Zorg dat de variabele, indien de door de gebruiker gegeven waarde in orde is, wordt aangepast
Om een voorbeeld te geven is in Code deel 2 de basiscode van het component te zien, waarbij de Published property TestValue is toegevoegd.
Code deel 2: Basiscode component met de voorbeeldvariabele TestValue toegevoegd
unitASRSComponent;
interface uses
SysUtils,Classes,Controls;
type
TASRS=class(TGraphicControl)
private
{ Private declarations }
protected
{ Protected declarations }
FTestValue:Integer;
procedureSetTestValue(constValue:Integer);
public
{ Public declarations }
published
propertyTestValue:IntegerreadFTestValuewriteSetTestValue;
{ Published declarations } end; procedureRegister; implementation procedureRegister; begin
RegisterComponents('ASRS',[TASRS]);
end;
{ TASRS }
procedureTASRS.SetTestValue(constValue:Integer);
begin FTestValue:=Value; end; end.
1. Fparameter
2. Set procedure
3. property in published sectie
Naast de properties beschikt ieder component ook over een aantal TomasQueues. Deze Queues worden gedeclareerd in het Public gedeelte, aangezien ze ook toegankelijk moeten zijn voor de programma welke het component aanstuurt.
Queue: Beschrijving:
MyInputQueue Alle binnenkomende pallets verblijven in deze Queue totdat de ASRS ze uit het Input Point laad
MyOutputQueue Zodra een pallet uitgevoerd wordt (na een retrieval operatie) komt deze in de MyOutputQueue
MyOrderQueue Bevat alle orders voor pallets
MyShelveQueue Bevat alle pallets die in de stellingen zijn opgeslagen
MyCurOrderQueue Zodra de ASRS een nieuwe order (voor een retrieval) aanneemt komt die in deze Queue
MyPalletQueue Bevat een het pallet wat de ASRS aan het verplaatsen of aan het in/uitladen is
Zoals gezegd is het component afgeleid van TGraphicControl. Hiermee erft het echter ook een aantal standaard procedures die we willen aanpassen.
De functie Create wordt aangeroepen indien een nieuw component gemaakt wordt. In dit geval is het wenselijk om alvast een aantal standaardwaarden aan het component mee te geven. Resize is een procedure die aangeroepen wordt als de afmetingen (Width, Height) van het component worden gewijzigd. Aangezien het component als het ware moet mee krimpen of meestrekken met eventuele veranderingen moet deze procedure ook worden aangepast. Dit geldt uiteraard ook voor de Paint procedure, aangezien er ook veel aandacht zal worden besteed aan de manier waarop het component zichzelf tekent.
Om dit te bereiken worden deze procedures in het Public gedeelte geplaatst en wordt „Override‟ gebruikt na deze procedures. Override zorgt ervoor dat de oorspronkelijke code voor deze procedures kan worden vervangen door nieuwe code. Code deel 3 geeft weer hoe dit uiteindelijk
geïmplementeerd is.
Protected
...
//Other component required procedures
constructor Create(AOwner: TComponent); Override; procedure Paint; override;
procedure Resize; override; procedure PreDrawing;
Code deel 3: Aangepaste standaard procedures
Alle properties uit Code deel 1 zijn toegevoegd aan de standaardcode, net zoals dat gebeurd is volgens het voorbeeld in Code deel 2. Daarnaast zijn alle overige variabelen en TomasQueues toegevoegd. Voor de uiteindelijke code, zie Bijlage A: Volledige code ASRScomponent.
3.2 Filteren gebruikersinvoer
Volgende stap is ervoor zorgen dat de SetValue procedures van de published properties dusdanig functioneren dat voorkomen wordt dat eventuele onjuiste invoer van de gebruiker in de Object Inspector voor foutmeldingen zorgt.
Een voorbeeld hiervan zijn de twee properties SlotWidth en PalletWidth. Een pallet moet altijd in een Slot kunnen passen. Daarom is het logisch dat te allen tijde PalletWidth < SlotWidth. Code deel 4 laat zien hoe middels if-then statements dit gecorrigeerd wordt, zodra de gebruiker conflicterende waarden invoert.
procedure TASRS.SetSlotHeight(const Value: Double);
begin
if FSlotHeight <> Value then FSlotHeight := Value; if FPalletHeight > Value then
begin
Showmessage('PalletHeight cannot be bigger than SlotHeight');
FPalletHeight := Value;
end;
PreDrawing; Invalidate;
end;
procedure TASRS.SetPalletHeight(const Value: Double);
begin
if Value > FSlotHeight then
begin
ShowMessage('PalletHeight cannot be bigger than SlotHeight' + #13#10
+ 'Current SlotHeight is '+floattostr(SlotHeight) + ' m');
FPalletHeight := SlotHeight;
end
else if FPalletHeight <> Value then FPalletHeight := Value; PreDrawing;
Invalidate;
end
Code deel 4: Procedures SetSlotWidth en SetPalletWidth
Voor de uiteindelijke SetProcedures voor alle properties, kan Bijlage A: Volledige code ASRScomponent geraadpleegd worden.
3.3 Aanpassen Create procedure
Door de procedure Create te Overriden, zoals in sectie 3.1 is uitgelegd, is het mogelijk om: Een standaard waarde te geven voor de Published properties
De TomasQueues van het component te creëren
Eenmalig de waarden te berekenen welke constant blijven tijdens de simulatie, „PreDrawing (hierover later meer)
constructor TASRS.Create(AOwner: TComponent);
var i,j: Integer; begin inherited; //Basic properties Height := 200; // [pix] Width := 400; // [pix] FVisible := True; //Shelve properties FShelveSides := 2; FShelveLevels := 3; FShelveSlots := 4; //Create MyQueues
MyInputQueue := TomasQueue.Create('MyInputQueue'); MyOutputQueue := TomasQueue.Create('MyOutputQueue'); MyOrderQueue := TomasQueue.Create('MyOrderQueue'); MyShelveQueue := TomasQueue.Create('MyShelveQueue'); MyCurOrderQueue := TomasQueue.Create('MyCurOrderQueue'); MyPalletQueue := TomasQueue.Create('MyPalletQueue');
//Dimensions FSlotWidth := 2; // [m] FSlotHeight := 3; // [m] FPalletWidth := 1.5; // [m] FPalletHeight := 2; // [m] FVLMHeight := 0.5; // [m] FInputX := SlotWidth + 2; // [m] FInputY := 1; // [m]
FOutputX := ShelveSlots * SlotWidth + InputX + 1; // [m]
FOutputY := 0; // [m] //Speed properties FAccX := 5; // [m/s2] acceleration X FDecX := -5; // [m/s2] deceleration X FVmaxX := 10; // [m/s2] FAccY := 5; // [m/s2] acceleration Y FDecY := -5; // [m/s2] deceleration Y FVmaxY := 10; // [m/s2] //Load properties FLoadDuration := 1; // [s] FUnloadDuration := 0.5; // [s]
//Reset other properties
FAction := 'Waiting: '+inttostr(CurX)+','+inttostr(CurY); FInventory := '';
PreDrawing;
end;
3.4 Predrawing
Deze procedure wordt enkel uitgevoerd in Design Time, en wel als het component gecreëerd wordt of als de gebruiker een Published property aanpast. Zie Code deel 6.
De reden dat hiervoor een aparte procedure gemaakt is, is snelheid. Indien deze regels onderdeel waren van de Paint procedure zou dit extra onnodige reken capaciteit van de processor vragen.
De volgende taken worden door de procedure PreDrawing uitgevoerd:
Het berekenen van de tekenschaal (noodzakelijk voor het op schaal tekenen verderop) Het berekenen van de specifieke afstanden (meer hierover in sectie 3.6)
Het dimensioneren van de matrices
procedure TASRS.PreDrawing;
var
i,j : Integer;
WidthRange, HeightRange : Double;
begin
//Calculate X and Y scale for conversions from m to pix
WidthRange := Max(ShelveSides * OutputX + SlotWidth,ShelveSides * (InputX + SlotWidth * (ShelveSlots - 1))+SlotWidth);
HeightRange := Max(ShelveLevels * SlotHeight + VLMHeight,
Max(InputY+SlotHeight,OutputY+SlotHeight)) - Min(0,Min(InputY,OutputY)); ScaleX := Width / (WidthRange+0.1); // [pix / m]
ScaleY := Height / (HeightRange+0.1); // [pix / m]
//Prevent div 0 calculations
if AccX = 0 then AccX := 1;
if DecX = 0 then DecX := 1;
if AccY = 0 then AccY := 1;
if DecY = 0 then DecY := 1;
//Calculate specific distances (distance before the VLM reaches Vmax)
s1X := 0.5*AccX*power(VmaxX/AccX,2); //Acc distance before VmaxX
s2X := -0.5*DecX*power(VmaxX/-DecX,2); //Dec distance after VmaxX
s1Y := 0.5*AccY*power(VmaxY/AccY,2); //Acc distance before VmaxY
s2Y := -0.5*DecY*power(VmaxY/-DecY,2); //Dec distance after VmaxY
//Set array dimensions before starting calculations
SetLength(FShelveMatrix,ShelveSides*ShelveSlots+2,ShelveLevels); SetLength(FShelveMatrixDistX,ShelveSides*ShelveSlots+2,ShelveLevels); SetLength(FShelveMatrixDistY,ShelveSides*ShelveSlots+2,ShelveLevels);
end;
Code deel 6: PreDrawing procedure welke slechts eenmalig wordt uitgevoerd, voordat de simulatie start
3.5 Ingebouwde procedures component
Sectie 1.4 behandelde de verdeling van taken tussen het component en het programma waar het component in zat. Aangezien ervoor gekozen is om functies die betrekking hebben op de
beslisstrategie van het component zelf door de gebruiker in het programma kunnen worden geplaatst, betekend dit dat functies die hier niet direct bij betrokken zijn prima door het component zelf kunnen worden afgehandeld.
FindRetrievalLoc is een functie die een pallet kan zoeken in de ShelveMatrix en vervolgens is gesplitst in een functie die de X en een die de Y waarde geeft. Zie Code deel 7. Indien de functies het pallet niet in de matrix kunnen vinden genereren ze een -1, welke een niet bestaande plek in de
ShelveMatrix is, waardoor het programma weet dat het pallet niet aanwezig is in de ShelveMatrix. Deze functie is eenduidig en voert een simpele taak uit die niet onderdeel kan zijn van een beslisstrategie, vandaar dat deze prima door het component zelf kan worden uitgevoerd.
function TASRS.FindRetrievalLocX(PalletItemNumber: Integer) : Integer;
var
i,j : Integer;
begin
for i := 1 to ShelveSlots * ShelveSides do
for j := 0 to ShelveLevels -1 do
if ShelveMatrix[i,j] = PalletItemNumber then
begin
Result := i;
Exit; //Exit loop upon finding pallet
end;
Result := -1; //Return -1 when pallet cannot be found
end;
function TASRS.FindRetrievalLocY(PalletItemNumber: Integer) : Integer;
var
i,j : Integer;
begin
for i := 1 to ShelveSlots * ShelveSides do
for j := 0 to ShelveLevels -1 do
if ShelveMatrix[i,j] = PalletItemNumber then
begin
Result := j;
Exit; //Exit loop upon finding pallet
end;
Result := -1; //Return -1 when pallet cannot be found
end;
Code deel 7: FindRetrievelLoc functies
Een functie die tevens niet betrokken is bij de beslisstrategie is CountEmptySlots wat eigenlijk al precies doet wat het zegt; het telt het lege aantal ShelveSlots in de ShelveMatrix.
function TASRS.CountEmptySlots; var EmptySlots : Integer; i,j: Integer; begin EmptySlots := 0;
for i := 1 to ShelveSlots * ShelveSides do
begin
for j := 0 to ShelveLevels -1 do
begin
if ShelveMatrix[i,j] = 0 then EmptySlots := EmptySlots + 1;
end;
end;
Result := EmptySlots;
end;
t
1t
21
2
v
v
maxt
3.6 Positie bepalende functies
Om het component juist te kunnen tekenen is het belangrijk te weten op welk moment het zich waar bevindt. Cruciaal hiervoor is de functie CalculateMovingDuration, welke op grond van een begin X en Y positie en een eind X en Y positie bepaald hoelang het zal duren voordat de SRM op nieuwe positie is.
Op grond van deze gegevens gaat de procedure CalculatePositions vervolgens aan de hand van deze verstreken tijd en het MovingNumber (de waarde gedicteerd door het programma welke aangeeft in hoeverre de beweging is gevorderd) berekenen waar de SRM zich exact bevind.
Om dit te kunnen bereiken moeten de afgelegde afstanden berekend worden. Voor het bewegen van de SRM is uitgegaan van een vaste versnelling (Acc) totdat een maximumsnelheid (Vmax) bereikt is, waarna de SRM vertraagt (Dec) totdat het tot stilstand komt op de gewenste positie.
Belangrijk is dat hierin twee verschillende situaties te onderscheiden zijn, namelijk 1) de situatie waarbij de afstand dusdanig kort is dat Vmax niet bereikt wordt, omdat de SRM alweer moet beginnen met afremmen om tijdig tot stilstand te komen en 2) de situatie waarbij de afstand voldoende is voor de SRM om Vmax wel te bereiken. In de sectie 3.6.1 en 3.6.2 worden de berekeningen waarmee de afstand berekend wordt uiteengezet, waarna het mogelijk is om dit ook als code aan het component toe te voegen, wat gebeurt in sectie 3.6.3.
Gegeven waarden Aanduiding Eenheid
Totaal afgelegde afstand stotaal [m]
Acceleratie (Acc) a1 [m/s
2
] Deceleratie (Dec) : altijd een negatieve waarde! a2 [m/s
2
]
Maximum snelheid vmax [m/s]
3.6.1 Situatie 1: Vmax wordt niet bereikt
In dit geval zal de SRM onvoldoende afstand afleggen om de maximumsnelheid (vmax) te kunnen
bereiken, zie Figuur 8. Het eerste deel van de beweging bestaat uit het accelereren met a1, gedurende
t1. Het tweede deel van de beweging zal de SRM afremmen met a2 gedurende t2, alvorens tot stilstand
Variabelen Aanduiding Eenheid
Verstreken tijd t [s]
Duur acceleratie t1 [s]
Duur deceleratie t2 [s]
Duur totale beweging ttotaal [s]
Afgelegde afstand acceleratie s1 [m]
Afgelegde afstand deceleratie s2 [m]
Snelheid tijdens acceleratie v1(t) [m/s]
Snelheid tijdens deceleratie v2(t) [m/s]
1. t2 uitdrukken in t1 1 1
v (t) = a t
2 1 1 2 1v (t) = a t + a (t- t )
2 1 2 1 1 2 1 2 1v (t = t + t ) = a t + a (t + t - t )
0
2 1 2 1 1 2 2v (t = t + t ) = a t + a t
0
2 1 1 2a
t
t
a
2. Berekenen t1 en ttotal Voor 0 < t < t1 t t t 2 2 1 1 1 1 1 0 0 01
1
s (t) = v dt = a t dt =
a t
=
a t
2
2
Berekenens (t = t )
1 1s (t = t ) =
1 11
a t
1 122
Voor t1 ≤ t 1 1 1 1 t-t t-t 2 2 1 1 2 1 t ts (t) =
v dt =
a t + a (t- t ) dt
Gebruik makende van 1
2 1 2
a
t
t
a
en berekenen voors (t = t )
2 2 2 2 2 2 21
s (t = t ) =
a t
2
2 2 total 1 1 2 1 2 1 1 2 21
1
s
= s (t = t ) + s (t = t + t ) =
a t -
a t
2
2
gebruik makende van1 2 1 2
a
t
t
a
2 2 1 total 1 1 2 1 2 1 1 2 1 2a
1
1
s
= s (t = t ) + s (t = t + t ) =
a t -
a
-
t
2
2
a
Oplossen geeft 1 total2 1 1 2
2 s
=
a
a
a
t
Gebruik makende van 1
2 1
2
a
t
t
a
ent
total= t + t
1 2resulteert dit in total 1 total2 1 2 1 22s
a
t
=
1-a
a
a
-a
3. Afleiden stotal(t) als t > t1
Een formule moet worden afgeleid voor stotal(t) als t > t1
Tijdelijke waarde td=t-t1 wordt gebruikt voor simplificatie
Voor t > t1 : d d 1 1 1 t t t t 2 2 total 1 2 1 1 1 1 2 d 1 1 1 1 2 d 0 t 0 0
1
1
s
(t) = v dt+ v dt = a t + a t + a t dt
a t
a t t
a t
2
d2
Terug converteren naar td=t-t1
Voor t > t1 :
2 2 total 1 1 1 1 1 2 11
1
s
(t) =
a t + a t t- t
+
a
t- t
2
2
4. Complete formule voor afstanden
2 1 total 1 total 2 2 1 total 1 1 1 1 1 2 11
for t<t : s
(t)=
a t
2
s
(t)=
1
1
for t>t : s
(t)=
a t +a t t-t +
a
t-t
2
2
3.6.2 Situatie 2: Vmax wordt wel bereikt
In dit geval legt de SRM voldoende afstand af zodat vmax wel wordt bereikt, zie Figuur 9. Het eerste
deel van de beweging bestaat uit het accelereren met a1, gedurende t1, totdat vmax bereikt is. Het
tweede deel van de beweging, t3, zal de SRM met constante snelheid vmax bewegen. Het derde en
laatste deel van de beweging zal de SRM afremmen met a2 gedurende t2, alvorens tot stilstand te
komen op gewenste locatie.
Figuur 9: Situatie 2, vmax wordt wel bereikt
1 1
v (t) = a t
v (t) = v
3 maxv (t) = v
2 max+ a t
2In dit geval zullen t1 en t2 vaste tijden zijn, aangezien het feit dat vmax altijd bereikt wordt en vmax een
constante waarde heeft max 1 1
v
t =
a
max 2 2v
t =
a
t
1t
31
2
v
v
maxt
3
t
21. Berekenen s1, s2 en s3 2 2 2 max max 1 1 1 1 1 1
v
v
1
1
=
2
2
a
2 a
s
a t
a
2 2 2 max max 2 2 2 2 2 2v
v
1
1
=
2
2
a
2 a
s
a t
a
2 2 max max 3 1 2 1 2v
v
=
(
)
2 a
2 a
totaal totaals
s
s
s
s
2. Berekenen s1(t), s2(t) en s3(t) t t t 2 2 1 1 1 1 1 0 0 01
1
s (t) = v dt = a t dt =
a t
=
a t
2
2
1 t 2 3 1 max 1 1 max 01
s (t) = v dt+ v
t ==
a t + v
t
2
d 1 t t 2 22 1 max 3 max 2 d 1 1 max 3 max 1 3 2 1 3
0 0
1
1
s (t) = v dt+ v
t + v
+ a t dt =
a t + v
t
v
(
t
t )
t
t
2
t
2
a t
3. Complete formule voor afstanden 2 1 total 1
2 total 1 1 3 total 1 1 max
1 3 total 1
1
for t<t : s
(t)=
a t
2
1
s
(t)= for t>t and t<t +t : s
(t)=
a t +v
t
2
1
for t>t +t : s
(t)=
a t
2
2 2 1 max 3 max 1 3 2 1 31
+v
t +v
(t-t -t )+
a
t-t -t
2
3.6.3 Implementatie code positiebepaling
Gebruik makende van de formules uit secties 3.6.1 en 3.6.2 berekent de functie CalculateDuration de tijd die het kost om van een begin naar een eindlocatie te verplaatsen, zie Code deel 9
function TASRS.CalculateMovingDuration(TempCurX, TempCurY,
TempNewX,TempNewY: Integer): Double; //Does what the name says:)
begin
//Calculate total distances
s_totX := abs(ShelveMatrixDistX[TempCurX,CurY] -ShelveMatrixDistX[TempNewX,NewY]);
s_totY := abs(ShelveMatrixDistY[TempCurX,CurY] -ShelveMatrixDistY[TempNewX,NewY]);
//Determine MovingDuration X
if s_totX >= (s1X+s2X) then //In this case VmaxX is attained
begin
t3X := (s_totX - (s1X + s2X)) / VmaxX;
t_totX := VmaxX/AccX + t3X - VmaxX/DecX;
end;
if (s_totX >= 0) AND (s_totX < (s1X + s2X)) then //VmaxX Not attained
begin
t1X := sqrt((2 * s_totX)/(AccX - (power(AccX,2)/DecX)));
t_totX := (1-(AccX/DecX))*t1X;
end;
//Determine MovingDuration Y
if s_totY >= (s1Y+s2Y) then //In this case VmaxY is attained
begin
t3Y := (s_totY - (s1Y + s2Y)) / VmaxY;
t_totY := VmaxY/AccY + t3Y - VmaxY/DecY;
end;
if (s_totY >= 0) AND (s_totY < (s1Y + s2Y)) then //VmaxY is NOT attained
begin
t1Y := sqrt((2 * s_totY)/(AccY - (power(AccY,2)/DecY)));
t_totY := (1-(AccY/DecY))*t1Y;
end;
Result := Max(t_totX,t_totY);
end;
Code deel 9: CalculateDuration
De informatie van CalculateDuration wordt doorgegeven aan de programma, waarna deze de
beslissing kan nemen om naar een bepaalde locatie te bewegen of een andere operatie uit te voeren. Het programma past hierop de properties NewX en NewY aan en begint met MovingNumber 0 tot en met de waarde TimeInterval naar deze nieuwe locatie te bewegen.
Hierop berekend de functie CalculatePositions hoeveel afstand de SRM in de tussentijd heeft afgelegd, gebaseerd op de berekeningen uit secties 3.6.1 en 3.6.2. Tevens bevat deze procedure de mogelijkheid om de bewegingsrichting om te keren indien de SRM naar links toe beweegt. Middels de uiteindelijke afgegeven waarden TravelX en TravelY is de paint procedure vervolgens in staat om de SRM ook op de juiste plek te tekenen.
procedure TASRS.CalculatePositions;
//Uses elapsed time and prior calculations to generate SRM position
var
i,j : Integer; Time : Double;
begin
//Use the function CalculateMovingDuration
MovingDuration := CalculateMovingDuration(CurX,CurY,NewX,NewY);; Time := (MovingDuration/TimeInterval)*MovingNumber;
//Calculate total and specific distances
s_totX := abs(ShelveMatrixDistX[CurX,CurY] -ShelveMatrixDistX[NewX,NewY]);
s_totY := abs(ShelveMatrixDistY[CurX,CurY] -ShelveMatrixDistY[NewX,NewY]);
//Determine covered X distance
if s_totX >= (s1X+s2X) then //In this case VmaxX is attained
begin
if Time < VmaxX/AccX then
begin
TravelX := 0.5*AccX*power(Time,2)
end;
if (Time >= VmaxX/AccX) AND (Time < (VmaxX/AccX + t3X)) then
begin
TravelX := 0.5*AccX*power(VmaxX/AccX,2)+VmaxX*(Time-VmaxX/AccX)
end;
if Time >= (VmaxX/AccX + t3X) then
begin TravelX := 0.5*AccX*power(VmaxX/AccX,2 )+VmaxX*t3X+AccX*(VmaxX/AccX)*(Time-VmaxX/AccX-t3X)+0.5*DecX*power((Time-VmaxX/AccX-t3X),2); end; end;
if (s_totX >= 0) AND (s_totX < (s1X+s2X)) then //In this case VmaxX is NOT attained
begin
if Time < t1X then TravelX := 0.5*AccX*power(Time,2)
else if Time >= t1X then TravelX :=
0.5*AccX*power(t1X,2)+AccX*t1X*(Time-t1X)+0.5*DecX *(power((Time-t1X),2));
end;
//Reverse X direction if necessary and stop after specific X movingtime
has passed
if (Time < t_totX) AND (ShelveMatrixDistX[NewX,NewY] -ShelveMatrixDistX[CurX,CurY] >= 0) then TravelX := TravelX; if (Time < t_totX) AND (ShelveMatrixDistX[NewX,NewY] -ShelveMatrixDistX[CurX,CurY] < 0) then TravelX := -TravelX; if (Time >= t_totX) AND (ShelveMatrixDistX[NewX,NewY] -ShelveMatrixDistX[CurX,CurY] >= 0) then TravelX := s_totX; if (Time >= t_totX) AND (ShelveMatrixDistX[NewX,NewY] -ShelveMatrixDistX[CurX,CurY] < 0) then TravelX := -s_totX;
//Determine covered Y distance
if s_totY >= (s1Y+s2Y) then //In this case VmaxY is attained
begin
if Time < VmaxY/AccY then
begin
TravelY := 0.5*AccY*power(Time,2)
end;
if (Time >= VmaxY/AccY) AND (Time < (VmaxY/AccY + t3Y)) then
begin
TravelY := 0.5*AccY*power(VmaxY/AccY,2)+VmaxY*(Time-VmaxY/AccY)
begin TravelY := 0.5*AccY*power(VmaxY/AccY,2 )+VmaxY*t3Y+AccY*(VmaxY/AccY)*(Time-VmaxY/AccY-t3Y)+0.5*DecY*power((Time-VmaxY/AccY-t3Y),2); end; end;
if (s_totY >= 0) AND (s_totY < (s1Y+s2Y)) then //VmaxY is NOT attained
begin
if Time < t1Y then TravelY := 0.5*AccY*power(Time,2)
else if Time >= t1Y then TravelY :=
0.5*AccY*power(t1Y,2)+AccY*t1Y*(Time-t1Y)+0.5*DecY*(power((Time-t1Y),2));
end;
//Reverse Y direction if necessary and stop after specific Y movingtime
has passed
if (Time < t_totY) AND (ShelveMatrixDistY[NewX,NewY] -ShelveMatrixDistY[CurX,CurY] >= 0) then TravelY := TravelY; if (Time < t_totY) AND (ShelveMatrixDistY[NewX,NewY] -ShelveMatrixDistY[CurX,CurY] < 0) then TravelY := -TravelY; if (Time >= t_totY) AND (ShelveMatrixDistY[NewX,NewY] -ShelveMatrixDistY[CurX,CurY] >= 0) then TravelY := s_totY; if (Time >= t_totY) AND (ShelveMatrixDistY[NewX,NewY] -ShelveMatrixDistY[CurX,CurY] < 0) then TravelY := -s_totY;
end;
3.7 Paint
De Paint procedure zorgt voor de animatie van het complete component. Voordat dieper ingegaan zal worden op de Paint procedure wordt eerst het framewerk opgezet waarmee deze procedure effectief in staat zal zijn om te tekenen.
De methode die gekozen is voor de grafische weergave van de processen is tekenen op schaal. Dit betekend dat 1 pixel van het component een bepaalde afstand in meters vertegenwoordigt. Hier is voor gekozen, omdat de bewegingen van de SRM volgens deze methode soepel en realistisch verlopen. Een mogelijk nadeel van deze aanpak kan overigens wel zijn dat bij grote afstanden, bijvoorbeeld tussen het Input Point en de stellingen (InputX) door te tekenen op schaal, sommige elementen erg smal worden weergegeven. De gebruiker kan dit verhinderen door in Design Time de vorm van het component aan te passen (uit te rekken) zodat dergelijke elementen wel correct worden weergegeven.
Om het tekenen op schaal te faciliteren wordt eerst berekend wat de totale afstand is die getekend moet worden en hoeveel pixels hiervoor beschikbaar zijn. Beide schalen, ScaleX en ScaleY worden met deze gegevens berekend in de procedure PreDrawing in sectie 3.4, aangezien dit slechts eenmalig hoeft te gebeuren.
Vervolgens is de functie DrawBlock in staat om op schaal een rechthoek te tekenen op het Canvas en eventueel nog een tekst toe te voegen, zie Figuur 10. De functie DrawBlock is in staat om de
oorsprong aan te passen op basis van het aantal stellingen, enkelzijdig of dubbelzijdig, van de ASRS. De oorsprong echter, blijft altijd liggen in het midden van het Input Point op vloerniveau. Een blok wordt altijd getekend, uitgegaan van het midden van de onderste rand. Als vloerniveau wordt de onderkant van de stellingen aangehouden.
Figuur 10: Enkel- en dubbelzijdige weergave componenten met oorsprong en tekenpunten blokken