forked from Courseplay/courseplay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TriggerShovelModeAIDriver.lua
179 lines (157 loc) · 6.32 KB
/
TriggerShovelModeAIDriver.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
--[[
handles "mode9": Fill and empty shovel at normal loading trigger, not at bunkersilo
--------------------------------------
0) Course setup:
a) Start in front of silo
b) drive forwards to bunker or unloading position for trailer, set waiting point #1 and unload
c) drive backwards, turn, drive forwards until before start
1) drive course until trigger is found, let triggerHandler handle the loading : STATE_TRANSPORT
2) if triggerHandler is finished drive until waiting point is reached : STATE_TRANSPORT
3) do a raycast and wait until we find a unloading trigger or trailer : STATE_WAIT_FOR_TARGET
4) drive to the trigger and unload there : STATE_START_UNLOAD, STATE_WAIT_FOR_UNLOADREADY, STATE_GO_BACK_FROM_EMPTYPOINT
5) if unloading is finished drive the course until 1) is active : STATE_TRANSPORT
NOTE: although lx and lz are passed in as parameters, they are never used.
]]
TriggerShovelModeAIDriver = CpObject(ShovelModeAIDriver)
TriggerShovelModeAIDriver.MAX_SPEED_IN_LOADING_TRIGGER = 5
function TriggerShovelModeAIDriver:setHudContent()
AIDriver.setHudContent(self)
courseplay.hud:setTriggerHandlerShovelModeAIDriverContent(self.vehicle)
end
function TriggerShovelModeAIDriver:isAlignmentCourseNeeded(ix)
-- never use alignment course for TriggerShovelModeAIDriver
return false
end
function TriggerShovelModeAIDriver:start(startingPoint)
--no shovel was found so return
self:findShovel(self.vehicle)
if not self.shovel then
self:error("Error: shovel not found!!")
courseplay:stop(self.vehicle)
return
end
self:setShovelState(self.states.STATE_TRANSPORT, 'setup');
self:validateWaitpoints()
AIDriver.start(self,startingPoint)
self:disableCollisionDetection()
end
function TriggerShovelModeAIDriver:shouldStopAtEndOfCourse()
return false
end
-- get the needed waitPoint
function TriggerShovelModeAIDriver:validateWaitpoints()
self.shovelEmptyPoint = nil
local numWaitPoints = 0
for i,wp in pairs(self.vehicle.Waypoints) do
if wp.wait then
numWaitPoints = numWaitPoints + 1;
end;
if numWaitPoints == 1 and self.shovelEmptyPoint == nil then
self.shovelEmptyPoint = i;
end;
end
end
function TriggerShovelModeAIDriver:drive(dt)
-- are shovel positions okay and we have one waitpoint ?
local notAllowedToDrive = false
if not self:checkShovelPositionsValid() or not self:checkWaypointsValid() then
self:setSpeed(0)
end
if self:getSiloSelectedFillTypeSetting():isEmpty() then
-- no filltype selected => wait until we have one
self:setSpeed(0)
self:setInfoText('NO_SELECTED_FILLTYPE')
else
self:clearInfoText('NO_SELECTED_FILLTYPE')
end
-- drive the course normally and let triggerHandler do all the loading stuff
if self.shovelState == self.states.STATE_TRANSPORT then
self.triggerHandler:enableFillTypeLoading()
-- near trigger reduce the speed so we don't miss the trigger
if self.triggerHandler:isInTrigger() then
self:setSpeed(self.MAX_SPEED_IN_LOADING_TRIGGER)
else
-- we are close to the unload waitpoint and are behind the loading trigger
if self.course:getDistanceBetweenVehicleAndWaypoint(self.vehicle, self.shovelEmptyPoint) < 15 and self:iAmBeforeEmptyPoint() and self:iAmBehindFillPoint() then
self:setShovelState(self.states.STATE_WAIT_FOR_TARGET)
end
end
--backup for starting somewhere in between
if not self:setShovelToPositionFinshed(self.SHOVEL_POSITIONS.TRANSPORT,dt) then
self:hold()
end
-- close to the unload waitpoint, so set pre unload shovel position and do a raycast for unload triggers, trailers
elseif self.shovelState == self.states.STATE_WAIT_FOR_TARGET then
self:driveWaitForTarget(dt)
self.triggerHandler:disableFillTypeLoading()
-- drive to the unload trigger
elseif self.shovelState == self.states.STATE_START_UNLOAD then
notAllowedToDrive = self:driveStartUnload(dt)
-- handle unloading at trigger
elseif self.shovelState == self.states.STATE_WAIT_FOR_UNLOADREADY then
self:driveWaitForUnloadReady(dt)
-- drive to the unload at trailer
elseif self.shovelState == self.states.STATE_START_UNLOAD_TRAILER then
notAllowedToDrive = self:driveStartUnloadTrailer(dt)
-- handle unloading at trailer
elseif self.shovelState == self.states.STATE_WAIT_FOR_UNLOADREADY_TRAILER then
self:driveWaitForUnloadReadyTrailer(dt)
-- reverse back to the course
elseif self.shovelState == self.states.STATE_GO_BACK_FROM_EMPTYPOINT then
self:driveGoBackFromEmptyPoint(dt)
end
if not notAllowedToDrive then
AIDriver.drive(self,dt)
end
end
function TriggerShovelModeAIDriver:onDraw()
if self:isDebugActive() and self.shovel then
local y = 0.5
y = self:renderText(y,"state: "..tostring(self.shovelState.name),0.4)
y = self:renderText(y,"isShovelFull: "..tostring(self:getIsShovelFull() == true),0.4)
y = self:renderText(y,"isShovelEmpty: "..tostring(self:getIsShovelEmpty() == true),0.4)
y = self:renderText(y,"iAmBehindFillPoint: "..tostring(self:iAmBehindFillPoint() == true),0.4)
y = self:renderText(y,"iAmBeforeEmptyPoint: "..tostring(self:iAmBeforeEmptyPoint() == true),0.4)
end
AIDriver.onDraw(self)
end
function TriggerShovelModeAIDriver:getSiloSelectedFillTypeSetting()
return self.vehicle.cp.settings.siloSelectedFillTypeShovelModeDriver
end
-- the same as AIDriver:onWaypointPassed without the wait msg
function TriggerShovelModeAIDriver:onWaypointPassed(ix)
if self.course:isWaitAt(ix+1) then
elseif ix == self.course:getNumberOfWaypoints() then
self:onLastWaypoint()
end
end
-- disable ShovelModeAIDriver override
function TriggerShovelModeAIDriver:onWaypointChange(ix)
AIDriver.onWaypointChange(self,ix)
end
--check for a needed waitpoint
function TriggerShovelModeAIDriver:checkWaypointsValid()
if self.shovelEmptyPoint == nil then
courseplay:setInfoText(self.vehicle, 'COURSEPLAY_NO_VALID_COURSE');
return false;
end;
return true
end
function TriggerShovelModeAIDriver:iAmBehindFillPoint()
return self.ppc and self.ppc:getCurrentWaypointIx() > 5
end
function TriggerShovelModeAIDriver:iAmBeforeEmptyPoint()
return self.ppc and self.ppc:getCurrentWaypointIx() < self.shovelEmptyPoint
end
-- disable ShovelModeAIDriver override
function TriggerShovelModeAIDriver:getSpeed()
if self:getCanGoWithStreetSpeed() then
return AIDriver.getSpeed(self)
else
return self.refSpeed
end
end
--slow speed to make sure small trigger,like the potato sorter gets hit correctly
function TriggerShovelModeAIDriver:getDriveStartUnloadRefSpeed()
return 3
end