๐งช [Challenge #02 – ํด์คํธ] AGV๋ ๋ช ๋๊ฐ ์ ๋นํ์๊น?
์์ฐ์ฑ๊ณผ ํจ์จ ์ฌ์ด, ์ต์ ์ AGV ์๋ฅผ ์ฐพ์๊ฐ๋ ์๋ฎฌ๋ ์ด์ ๋ถ์
โ๏ธ ๋ชจ๋ธ๋ง ์งํ ๊ณผ์
1๏ธโฃ ๋ ์ด์์ ๋ฐฐ์น ๋ฐ ๊ธฐ๋ณธ ์ธํ
- ๊ณต์ ํ๋ฆ: Start → B zone (Station B) → A zone (Station A) → End
- ๊ฐ ๊ณต์ ์์ Marker ๊ฐ์ฒด ๋ฐฐ์น → AGV์ Pick/Drop ์์น ์ง์
- ์ด์ก ๊ฒฝ๋ก:
- Track ๋๋ Line ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ AGV์ ์ด๋ ๊ฒฝ๋ก ๊ตฌ์ฑ
- AGVPool์์ ์ถ๋ฐ → Marker → ๋ค์ Marker → ๋ณต๊ท ์ํ
- ๊ณต๊ฐ ๊ตฌ์กฐ:
- ํ์ ๋ฐ๊ฒฝ 0m → AGV๊ฐ ์ ์๋ฆฌ ํ์ ๊ฐ๋ฅ
- ์ข์ ๊ณต๊ฐ ๋ด ์ต๋จ ๋์ ๊ตฌํ ์ฉ์ด
2๏ธโฃ ๋ก์ง ์ ์
- AGV ์ ์ด ๋ฐฉ์: AGVPool์์ AGV ๋ช ๋ น ๋จ์ผ ๋ฐํ (1ํ์ฑ ๋ช ๋ น)
- ๊ฐ ๊ณต์ ์๋ฃ ์:
- Method ์ฌ์ฉํ์ฌ Source , A , B ์์ ์์ ๋ช ๋ น Queue ์ ๋ ฅ
- Source ์์ Seq Queue ์ถ๊ฐ - B ๊ฐ Source ๋ค์ ๊ณต์ ์ด๊ธฐ ๋๋ฌธ์ ํด๋น Station ์ํ๋ฅผ ๋ณด๊ณ ๋ช ๋ น์ ๋ฃ๋๋ค.
--Source exit ctrl
waituntil B_1.set = false or B_2.set = false or B_3.set = false -- Waituntil B1 Station Empty
if B_1.set = false
B_1.set := true
elseif B_2.set = false
B_2.set := true
else
B_3.set := true
end
seq.push(?.name) -- Set Seq queue
seq.push("")
- B , A ๊ตฌ์ญ Station Logic
waituntil A_1.set = false or A_2.set = false or A_3.set = false -- B only
seq.push(?.name)
seq.push("")
- AMR seq ๋ณ ๋ช ๋ น ์ํ - Queue object , Seq_top variable object , observer ctrl
-- param attribute: string, oldValue, newValue: string
-- param attribute: string, oldValue: string
param newValue: string
var A :object
waituntil AGVPool.NumIdleAGVs > 0
var agv := agvPool.getIdleAGV
seq.pop
switch newValue
case ""
case "Source"
agv.destination := O_M
waituntil agv.destinationwasreached
wait loadunloadTIme
source.mu.move(agv)
if B_1.empty = true
agv.destination := B_1_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(B_1)
elseif B_2.empty = true
agv.destination := B_2_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(B_2)
else
agv.destination := B_3_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(B_3)
end
agv.destination := AGVPool
waituntil agv.destinationwasreached
case "A_1"
agv.destination := A_1_M
waituntil agv.destinationwasreached
wait loadunloadTIme
A_1.mu.move(agv)
agv.destination := Marker
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(Conveyor)
agv.destination := AGVPool
waituntil agv.destinationwasreached
A_1.set := false
case "A_2"
agv.destination := A_2_M
waituntil agv.destinationwasreached
wait loadunloadTIme
A_2.mu.move(agv)
agv.destination := Marker
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(Conveyor)
agv.destination := AGVPool
waituntil agv.destinationwasreached
A_2.set := false
case "A_3"
agv.destination := A_3_M
waituntil agv.destinationwasreached
wait loadunloadTIme
A_3.mu.move(agv)
agv.destination := Marker
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(Conveyor)
agv.destination := AGVPool
waituntil agv.destinationwasreached
A_3.set := false
case "B_1"
if A_1.set = false
A_1.set := True
A := A_1
elseif A_2.set = false
A_2.set := True
A := A_2
else
A_3.set := True
A := A_3
end
agv.destination := B_1_M
waituntil agv.destinationwasreached
wait loadunloadTIme
B_1.mu.move(agv)
if A = A_1
agv.destination := A_1_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(A_1)
elseif A = A_2
A_2.set := True
agv.destination := A_2_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(A_2)
else
A_3.set := True
agv.destination := A_3_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(A_3)
end
B_1.set := false
agv.destination := AGVPool
waituntil agv.destinationwasreached
case "B_2"
if A_1.set = false
A_1.set := True
A := A_1
elseif A_2.set = false
A_2.set := True
A := A_2
else
A_3.set := True
A := A_3
end
agv.destination := B_2_M
waituntil agv.destinationwasreached
wait loadunloadTIme
B_2.mu.move(agv)
if A = A_1
A_1.set := True
agv.destination := A_1_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(A_1)
elseif A = A_2
A_2.set := True
agv.destination := A_2_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(A_2)
else
A_3.set := True
agv.destination := A_3_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(A_3)
end
B_2.set := false
agv.destination := AGVPool
waituntil agv.destinationwasreached
case "B_3"
if A_1.set = false
A_1.set := True
A := A_1
elseif A_2.set = false
A_2.set := True
A := A_2
else
A_3.set := True
A := A_3
end
agv.destination := B_3_M
waituntil agv.destinationwasreached
wait loadunloadTIme
B_3.mu.move(agv)
if A = A_1
A_1.set := True
agv.destination := A_1_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(A_1)
elseif A = A_2
A_2.set := True
agv.destination := A_2_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(A_2)
else
A_3.set := True
agv.destination := A_3_M
waituntil agv.destinationwasreached
wait loadunloadTIme
agv.mu.move(A_3)
end
B_3.set := false
agv.destination := AGVPool
waituntil agv.destinationwasreached
end
agv.isidle := true
- ์กฐ๊ฑด: AMR์ด ์์ ํ ๋ฐ๋์ AGVPool๋ก ๋ณต๊ท
- AMR ์์ฑ:
- Capacity: 1
- HomeLocation: AGVPool
- ๋๊ธฐ ๋ก์ง ๊ณ ๋ ค: AGV๊ฐ ๋ณต๊ท ์ค์ธ ์ํฉ์์ ์๋ก์ด Job์ด ๋๊ธฐํ๋๋ก ์ค๊ณ
3๏ธโฃ ์คํ ๊ณํ๋ฒ - ExperimentManager
- ์คํ ๋ชฉ์ : AGV ์์ ๋ฐ๋ฅธ ์์ฐ์ฑ๊ณผ ํจ์จ์ฑ ๋น๊ต
- ๋ณ์: AGV ์๋ (1, 2, 3, 4 ....)
- ๊ณ ์ ์กฐ๊ฑด:
- ๊ณต์ ์ฒ๋ฆฌ์๊ฐ (60์ด)
- ์๋ฎฌ๋ ์ด์ ๊ธฐ๊ฐ (7์ผ)
- Source ๊ฐ๊ฒฉ (Interval Source, ์์น ๊ณ ์ )
- ์ธก์ ํญ๋ชฉ:
- ์ด ์์ฐ๋ (Units Per Day)
- ์คํ ๋ฐฉ์:
- Experiment Manager
- ๊ฒฐ๊ณผ๋ ํ ํํ๋ก ๋น๊ต ๋ถ์
๐ ์คํ ์กฐ๊ฑด ๋ณต์ต
- ๊ณต์ ํ๋ฆ: Start → B → A → End
- ๊ณต์ ์ฒ๋ฆฌ์๊ฐ:
- B zone: 60์ด
- A zone: 60์ด
- AMR ์ค์ :
- ํ์ ๋ฐ๊ฒฝ 0m (์ ์๋ฆฌ ํ์ )
- ์ฉ๋ 1, ๋ช ๋ น 1ํ ์ํ ํ AGVpool ๋ณต๊ท
- ๋ชฉํ: ์ผ์ผ ์์ฐ๋ 600๊ฐ ์ด์
- ์๋ฎฌ๋ ์ด์ ๊ธฐ๊ฐ: 7์ผ
๐งช ์คํ ๊ฒฐ๊ณผ ์์ฝ
AGV ๋์ ๋ณ ์ผ์ผ ์์ฐ๋ (UPD)
1๋ | 225๊ฐ | ๋ณ๋ชฉ ๋ฐ์ |
2๋ | 433๊ฐ | ์ผ๋ถ ๊ฐ์ |
3๋ | 645๊ฐ | โ ๋ชฉํ ๋ฌ์ฑ |
4๋ | 623๊ฐ | โ ๋ชฉํ ๋ฌ์ฑ Idle ์ฆ๊ฐ, ์ผ๋ถ ๋ณ๋ชฉ ๋ฐ์ |
5๋ | 728๊ฐ | โ ๋ชฉํ ๋ฌ์ฑ Idle ์ฆ๊ฐ, ์ผ๋ถ ๋ณ๋ชฉ ๋ฐ์ ์ต๋ Capa ๋๋ฌ |
โป ์คํ ์์น๋ ์์์ ๋๋ค. ์ค์ ๊ฒฐ๊ณผ์ ๋ง๊ฒ ์์ ํด์ฃผ์ธ์.
๐ ๋ถ์
- AGV 1๋์ผ ๋๋ ๋ช ํํ ๋ณ๋ชฉ์ด ๋ฐ์ํ๋ฉฐ, Waiting Time์ด ๋งค์ฐ ํฝ๋๋ค.
- 2๋๋ก ๋๋ฆฌ๋ฉด ์์ฐ๋์ด ํฌ๊ฒ ์ฆ๊ฐํ์ง๋ง ๋ชฉํ์น์๋ ๋ฏธ๋ฌ
- 3๋์์ ์์ฐ๋ 600๊ฐ ์ด์ ๋ฌ์ฑ, Waiting Time๊ณผ Idle Time๋ ๊ท ํ ์กํ
- 4๋๋ก ๋๋ฆฌ๋ฉด ์์ฐ๋์ ์ํญ ์ฆ๊ฐํ์ง๋ง Idle Time์ด ๊ธ์ฆ → ํจ์จ ์ ํ
- 5๋๋ก ๋๋ฆฌ๋ฉด ํด๋น ๋ผ์ธ ์ต๋ ์์ฐ Capa ๋๋ฌ
๐ ๊ฒฐ๋ก
- ์ต์ AGV ์: 3๋
- ํฌ์ ๋๋น ์์ต ์ธก๋ฉด์์, 3๋๊ฐ ์์ฐ์ฑ๊ณผ ํจ์จ์ ๊ท ํ์
- AGV๋ฅผ ๋ ๋๋ฆฌ๋ฉด ์์ฐ๋์ ์ ์ฒด๋๊ณ Idle๋ง ์ฆ๊ฐ → ๊ณผ์ ํฌ์
- ์ต๋ Capa๊ฐ ์ค์ํ ๊ฒฝ์ฐ 5๋ ๋ฐฐ์น ๊ณ ๋ ค
- ๋ค์ด๋ก๋