37 | function AITurnStrategyBulb1:startTurn(driveStrategyStraight) |
38 | if not AITurnStrategyBulb1:superClass().startTurn(self, driveStrategyStraight) then |
39 | return false |
40 | end |
41 | local turnData = driveStrategyStraight.turnData |
42 | |
43 | local sideOffset |
44 | if self.turnLeft then |
45 | sideOffset = turnData.sideOffsetLeft |
46 | else |
47 | sideOffset = turnData.sideOffsetRight |
48 | end |
49 | |
50 | --# |
51 | --self.usePredictionToSkipToNextSegment = true |
52 | |
53 | -- center of first circle |
54 | local c1X,c1Y,c1Z |
55 | if sideOffset >= 0 then |
56 | c1X,c1Y,c1Z = self:getVehicleToWorld(-turnData.radius,0,turnData.zOffsetTurn) |
57 | else |
58 | c1X,c1Y,c1Z = self:getVehicleToWorld(turnData.radius,0,turnData.zOffsetTurn) |
59 | end |
60 | |
61 | -- center of second circle |
62 | local a = turnData.radius+math.abs(sideOffset) |
63 | local z = math.sqrt( 2*turnData.radius*2*turnData.radius - a*a ) |
64 | local c2X,c2Y,c2Z = self:getVehicleToWorld(sideOffset,0,z+turnData.zOffsetTurn) |
65 | |
66 | -- center of third circle |
67 | local c3X,c3Y,c3Z |
68 | if sideOffset >= 0 then |
69 | c3X,c3Y,c3Z = self:getVehicleToWorld(2*sideOffset+turnData.radius,0,turnData.zOffsetTurn) |
70 | else |
71 | c3X,c3Y,c3Z = self:getVehicleToWorld(2*sideOffset-turnData.radius,0,turnData.zOffsetTurn) |
72 | end |
73 | |
74 | -- |
75 | local alpha = math.atan( z / a ) |
76 | local rvX,rvY,rvZ = getWorldRotation(self.vehicle:getAIDirectionNode(), 0,0,0) |
77 | |
78 | self:addNoFullCoverageSegment(self.turnSegments) |
79 | |
80 | --# first straight |
81 | local segment = {} |
82 | segment.isCurve = false |
83 | segment.moveForward = true |
84 | segment.slowDown = true |
85 | segment.startPoint = self:getVehicleToWorld(0,0,0, true) |
86 | segment.endPoint = self:getVehicleToWorld(0,0,turnData.zOffsetTurn, true) |
87 | table.insert(self.turnSegments, segment) |
88 | |
89 | --# first curve |
90 | local segment = {} |
91 | segment.isCurve = true |
92 | segment.moveForward = true |
93 | segment.radius = turnData.radius |
94 | segment.o = createTransformGroup("segment1") |
95 | link(getRootNode(), segment.o) |
96 | setTranslation(segment.o, c1X,c1Y,c1Z) |
97 | setRotation(segment.o, rvX,rvY,rvZ) |
98 | if sideOffset >= 0 then |
99 | segment.startAngle = 0 |
100 | segment.endAngle = alpha |
101 | else |
102 | segment.startAngle = math.rad(180) |
103 | segment.endAngle = math.rad(180) - alpha |
104 | end |
105 | table.insert(self.turnSegments, segment) |
106 | |
107 | --# second curve |
108 | local segment = {} |
109 | segment.isCurve = true |
110 | segment.moveForward = true |
111 | segment.radius = turnData.radius |
112 | segment.o = createTransformGroup("segment2") |
113 | link(getRootNode(), segment.o) |
114 | setTranslation(segment.o, c2X,c2Y,c2Z) |
115 | setRotation(segment.o, rvX,rvY,rvZ) |
116 | if sideOffset >= 0 then |
117 | segment.startAngle = math.rad(180) + alpha |
118 | segment.endAngle = -alpha |
119 | else |
120 | segment.startAngle = -alpha |
121 | segment.endAngle = math.rad(180) + alpha |
122 | end |
123 | table.insert(self.turnSegments, segment) |
124 | |
125 | --# third curve |
126 | local segment = {} |
127 | segment.isCurve = true |
128 | segment.moveForward = true |
129 | segment.radius = turnData.radius |
130 | --segment.checkForValidArea = not self.vehicle.aiAlignedProcessing --true |
131 | segment.o = createTransformGroup("segment3") |
132 | link(getRootNode(), segment.o) |
133 | setTranslation(segment.o, c3X,c3Y,c3Z) |
134 | setRotation(segment.o, rvX,rvY,rvZ) |
135 | if sideOffset >= 0 then |
136 | segment.startAngle = math.rad(180) - alpha |
137 | segment.endAngle = math.rad(180) |
138 | else |
139 | segment.startAngle = alpha |
140 | segment.endAngle = 0 |
141 | end |
142 | table.insert(self.turnSegments, segment) |
143 | |
144 | --# final straight |
145 | local segment = {} |
146 | segment.isCurve = false |
147 | segment.moveForward = true |
148 | segment.slowDown = true |
149 | --segment.checkForValidArea = true --not self.vehicle.aiAlignedProcessing --true |
150 | local x = 2*sideOffset |
151 | segment.startPoint = self:getVehicleToWorld(x,0,turnData.zOffsetTurn, true) |
152 | segment.endPoint = self:getVehicleToWorld(x,0,math.min(turnData.zOffset, turnData.zOffsetTurn-0.1), true) |
153 | table.insert(self.turnSegments, segment) |
154 | |
155 | self:startTurnFinalization() |
156 | |
157 | return true |
158 | end |
163 | function AITurnStrategyBulb1:updateTurningSizeBox(box, turnLeft, turnData, lookAheadDistance) |
164 | |
165 | local sideOffset |
166 | if turnLeft then |
167 | sideOffset = turnData.sideOffsetLeft |
168 | else |
169 | sideOffset = turnData.sideOffsetRight |
170 | end |
171 | |
172 | --# 2) get turn data, center of circle and radius |
173 | local a = turnData.radius+math.abs(sideOffset) |
174 | local z = math.sqrt( 2*turnData.radius*2*turnData.radius - a*a ) |
175 | |
176 | local c2X,c2Y,c2Z = sideOffset, 0, z+turnData.zOffsetTurn |
177 | |
178 | --# 3) estimate final size of bounding box |
179 | |
180 | local xb = math.max(turnData.toolOverhang.front.xb, turnData.toolOverhang.back.xb) |
181 | --local zb = math.max(turnData.toolOverhang.front.zb, turnData.toolOverhang.back.zb) |
182 | local xt = math.max(turnData.toolOverhang.front.xt, turnData.toolOverhang.back.xt) |
183 | --local zt = math.max(turnData.toolOverhang.front.zt, turnData.toolOverhang.back.zt) |
184 | local delta = math.max(xb, turnData.radius + xt) |
185 | |
186 | local maxX = c2X + xb |
187 | local minX = c2X - xb |
188 | local maxZ = c2Z + delta |
189 | |
190 | --print(" Bulb1 maxZ = "..tostring(maxZ)) |
191 | |
192 | box.center[1], box.center[2], box.center[3] = maxX - (maxX-minX)/2, 0, maxZ/2 + lookAheadDistance/2 |
193 | box.size[1], box.size[2], box.size[3] = (maxX-minX)/2, 5, maxZ/2 + lookAheadDistance/2 |
194 | |
195 | self:adjustHeightOfTurningSizeBox(box) |
196 | end |