LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

CrabSteering

Description
Class for vehicles with variable steering modes (e.g. all wheel steering, crab steering, back wheel steering)
Functions

actionEventSetCrabSteeringMode

Description
Definition
actionEventSetCrabSteeringMode()
Code
638function CrabSteering.actionEventSetCrabSteeringMode(self, actionName, inputValue, callbackState, isAnalog)
639 local isAllowed, warning = self:getCanToggleCrabSteering()
640 if isAllowed then
641 local spec = self.spec_crabSteering
642 local state = spec.state
643
644 for i, mode in pairs(spec.steeringModes) do
645 if mode.inputAction == InputAction[actionName] then
646 state = i
647 break
648 end
649 end
650
651 if state ~= spec.state then
652 self:setCrabSteering(state)
653 end
654 elseif warning ~= nil then
655 g_currentMission:showBlinkingWarning(warning, 2000)
656 end
657end

actionEventToggleCrabSteeringModes

Description
Definition
actionEventToggleCrabSteeringModes()
Code
616function CrabSteering.actionEventToggleCrabSteeringModes(self, actionName, inputValue, callbackState, isAnalog)
617 local isAllowed, warning = self:getCanToggleCrabSteering()
618 if isAllowed then
619 local spec = self.spec_crabSteering
620 local state = spec.state
621 state = state + callbackState
622 if state > spec.stateMax then
623 state = 1
624 elseif state < 1 then
625 state = spec.stateMax
626 end
627
628 if state ~= spec.state then
629 self:setCrabSteering(state)
630 end
631 elseif warning ~= nil then
632 g_currentMission:showBlinkingWarning(warning, 2000)
633 end
634end

dashboardCrabSteeringAttributes

Description
Definition
dashboardCrabSteeringAttributes()
Code
661function CrabSteering.dashboardCrabSteeringAttributes(self, xmlFile, key, dashboard, isActive)
662 dashboard.crabSteeringStates = xmlFile:getValue(key .. "#states", nil, true)
663
664 return true
665end

dashboardCrabSteeringState

Description
Definition
dashboardCrabSteeringState()
Code
669function CrabSteering.dashboardCrabSteeringState(self, dashboard, newValue, minValue, maxValue, isActive)
670 local isStateActive = false
671 if dashboard.crabSteeringStates ~= nil then
672 for _, state in pairs(dashboard.crabSteeringStates) do
673 if self.spec_crabSteering.state == state then
674 isStateActive = true
675 end
676 end
677 end
678
679 Dashboard.defaultDashboardStateFunc(self, dashboard, isStateActive, minValue, maxValue, isActive)
680end

getCanBeSelected

Description
Definition
getCanBeSelected()
Code
567function CrabSteering:getCanBeSelected(superFunc)
568 return self.spec_crabSteering.hasSteeringModes or superFunc(self)
569end

getCanToggleCrabSteering

Description
Returns if it's allowed to toggle crab steering
Definition
getCanToggleCrabSteering()
Return Values
booleanisAllowedis allowed
stringwarningwarning to be displayed
Code
316function CrabSteering:getCanToggleCrabSteering()
317 return true, nil
318end

initSpecialization

Description
Definition
initSpecialization()
Code
26function CrabSteering.initSpecialization()
27 local schema = Vehicle.xmlSchema
28 schema:setXMLSpecializationType("CrabSteering")
29
30 schema:register(XMLValueType.FLOAT, "vehicle.crabSteering#distFromCompJointToCenterOfBackWheels", "Distance from component joint to center of back wheels")
31 schema:register(XMLValueType.FLOAT, "vehicle.crabSteering#aiSteeringModeIndex", "AI steering mode index", 1)
32 schema:register(XMLValueType.FLOAT, "vehicle.crabSteering#toggleSpeedFactor", "Toggle speed factor", 1)
33
34 CrabSteering.registerSteeringModeXMLPaths(schema, "vehicle.crabSteering.steeringMode(?)")
35 CrabSteering.registerSteeringModeXMLPaths(schema, "vehicle.crabSteering.crabSteeringConfiguration(?).steeringMode(?)")
36
37 Dashboard.registerDashboardXMLPaths(schema, "vehicle.crabSteering.dashboards", "state")
38 schema:register(XMLValueType.VECTOR_N, "vehicle.crabSteering.dashboards.dashboard(?)#states", "Crab steering states which activate the dashboard")
39
40 schema:register(XMLValueType.INT, "vehicle.wheels.wheelConfigurations.wheelConfiguration(?).wheels#crabSteeringIndex", "Crab steering configuration index")
41
42 schema:setXMLSpecializationType()
43
44 local schemaSavegame = Vehicle.xmlSchemaSavegame
45 schemaSavegame:register(XMLValueType.INT, "vehicles.vehicle(?).crabSteering#state", "Current steering mode", 1)
46end

loadWheelsFromXML

Description
Definition
loadWheelsFromXML()
Code
573function CrabSteering:loadWheelsFromXML(superFunc, xmlFile, key, wheelConfigurationI)
574 superFunc(self, xmlFile, key, wheelConfigurationI)
575
576 self.spec_crabSteering.configurationIndex = xmlFile:getValue(key .. ".wheels#crabSteeringIndex")
577end

onAIImplementStart

Description
Called on start ai vehicle
Definition
onAIImplementStart()
Code
581function CrabSteering:onAIImplementStart()
582 local spec = self.spec_crabSteering
583 self:setCrabSteering(spec.aiSteeringModeIndex)
584end

onLoad

Description
Called on loading
Definition
onLoad(table savegame)
Arguments
tablesavegamesavegame
Code
99function CrabSteering:onLoad(savegame)
100 local spec = self.spec_crabSteering
101
102 spec.state = 1
103 spec.stateMax = -1
104
105 spec.configurationIndex = spec.configurationIndex or 1
106
107 spec.distFromCompJointToCenterOfBackWheels = self.xmlFile:getValue("vehicle.crabSteering#distFromCompJointToCenterOfBackWheels")
108 spec.aiSteeringModeIndex = self.xmlFile:getValue("vehicle.crabSteering#aiSteeringModeIndex", 1)
109 spec.toggleSpeedFactor = self.xmlFile:getValue("vehicle.crabSteering#toggleSpeedFactor", 1)
110
111 spec.currentArticulatedAxisOffset = 0
112 spec.articulatedAxisOffsetChanged = false
113 spec.articulatedAxisLastAngle = 0
114 spec.articulatedAxisChangingTime = 0
115
116 local baseKey = "vehicle.crabSteering"
117 local configKey = string.format("vehicle.crabSteering.crabSteeringConfiguration(%d)", spec.configurationIndex - 1)
118 if self.xmlFile:hasProperty(configKey) then
119 baseKey = configKey
120 end
121
122 spec.steeringModes = {}
123 local i = 0
124 while true do
125 local key = string.format("%s.steeringMode(%d)", baseKey, i)
126 if not self.xmlFile:hasProperty(key) then
127 break
128 end
129
130 local entry = {}
131 entry.name = self.xmlFile:getValue(key .. "#name", "", self.customEnvironment, false)
132
133 local inputBindingName = self.xmlFile:getValue(key .. "#inputBindingName")
134 if inputBindingName ~= nil then
135 if InputAction[inputBindingName] ~= nil then
136 entry.inputAction = InputAction[inputBindingName]
137 else
138 Logging.xmlWarning(self.xmlFile, "Invalid inputBindingname '%s' for '%s'", tostring(inputBindingName), key)
139 end
140 end
141
142 entry.wheels = {}
143 local j = 0
144 while true do
145 local wheelKey = string.format("%s.wheel(%d)", key, j)
146 if not self.xmlFile:hasProperty(wheelKey) then
147 break
148 end
149 local wheelEntry = {}
150 wheelEntry.wheelIndex = self.xmlFile:getValue(wheelKey .. "#index")
151 wheelEntry.wheelNode = self.xmlFile:getValue(wheelKey .. "#node", nil, self.components, self.i3dMappings)
152 if wheelEntry.wheelNode ~= nil then
153 local wheel = self:getWheelByWheelNode(wheelEntry.wheelNode)
154 if wheel ~= nil then
155 wheelEntry.wheelIndex = wheel.xmlIndex + 1
156 else
157 Logging.xmlError(self.xmlFile, "Invalid wheel node '%s' for '%s'", self.xmlFile:getString(wheelKey .. "#node"), wheelKey)
158 end
159 end
160
161 wheelEntry.offset = self.xmlFile:getValue(wheelKey .. "#offset", 0)
162 wheelEntry.locked = self.xmlFile:getValue(wheelKey .. "#locked", false)
163
164 local wheels = self:getWheels()
165 if wheels[wheelEntry.wheelIndex] ~= nil then
166 wheels[wheelEntry.wheelIndex].steeringOffset = 0
167 wheels[wheelEntry.wheelIndex].forceSteeringAngleUpdate = true
168
169 wheels[wheelEntry.wheelIndex].rotSpeedBackUp = wheels[wheelEntry.wheelIndex].rotSpeed
170 else
171 Logging.xmlError(self.xmlFile, "Invalid wheelIndex '%s' for '%s'", tostring(wheelEntry.wheelIndex), wheelKey)
172 end
173
174 table.insert(entry.wheels, wheelEntry)
175 j = j + 1
176 end
177
178 local specArticulatedAxis = self.spec_articulatedAxis
179 if specArticulatedAxis ~= nil and specArticulatedAxis.componentJoint ~= nil then
180 entry.articulatedAxis = {}
181 entry.articulatedAxis.rotSpeedBackUp = specArticulatedAxis.rotSpeed
182 entry.articulatedAxis.offset = self.xmlFile:getValue(key .. ".articulatedAxis#offset", 0)
183 entry.articulatedAxis.locked = self.xmlFile:getValue(key .. ".articulatedAxis#locked", false)
184 entry.articulatedAxis.wheelIndices = self.xmlFile:getValue(key .. ".articulatedAxis#wheelIndices", nil, true)
185 end
186
187 entry.animations = {}
188 j = 0
189 while true do
190 local animKey = string.format("%s.animation(%d)", key, j)
191 if not self.xmlFile:hasProperty(animKey) then
192 break
193 end
194 local animName = self.xmlFile:getValue(animKey .. "#name")
195 local animSpeed = self.xmlFile:getValue(animKey .. "#speed", 1.0)
196 local stopTime = self.xmlFile:getValue(animKey .. "#stopTime")
197 if animName ~= nil and self:getAnimationExists(animName) then
198 table.insert(entry.animations, {animName=animName, animSpeed=animSpeed, stopTime=stopTime})
199 else
200 Logging.xmlWarning(self.xmlFile, "Invalid animation '%s' for '%s'", tostring(animName), animKey)
201 end
202 j = j + 1
203 end
204
205 table.insert(spec.steeringModes, entry)
206 i = i + 1
207 end
208
209 spec.stateMax = #spec.steeringModes
210 if spec.stateMax > ((2^CrabSteering.STEERING_SEND_NUM_BITS) - 1) then
211 Logging.xmlError(self.xmlFile, "CrabSteering only supports %d steering modes!", (2^CrabSteering.STEERING_SEND_NUM_BITS) - 1)
212 end
213
214 spec.hasSteeringModes = spec.stateMax > 0
215
216 if spec.hasSteeringModes then
217 self.customSteeringAngleFunction = true
218
219 self:setCrabSteering(1, true)
220
221 if self.loadDashboardsFromXML ~= nil then
222 self:loadDashboardsFromXML(self.xmlFile, "vehicle.crabSteering.dashboards", {valueTypeToLoad = "state",
223 valueObject = self.spec_crabSteering,
224 valueFunc = "state",
225 additionalAttributesFunc = CrabSteering.dashboardCrabSteeringAttributes,
226 stateFunc = CrabSteering.dashboardCrabSteeringState})
227 end
228 else
229 SpecializationUtil.removeEventListener(self, "onReadStream", CrabSteering)
230 SpecializationUtil.removeEventListener(self, "onWriteStream", CrabSteering)
231 SpecializationUtil.removeEventListener(self, "onReadUpdateStream", CrabSteering)
232 SpecializationUtil.removeEventListener(self, "onWriteUpdateStream", CrabSteering)
233 SpecializationUtil.removeEventListener(self, "onDraw", CrabSteering)
234 SpecializationUtil.removeEventListener(self, "onAIImplementStart", CrabSteering)
235 SpecializationUtil.removeEventListener(self, "onRegisterActionEvents", CrabSteering)
236 end
237end

onPostLoad

Description
Definition
onPostLoad()
Code
241function CrabSteering:onPostLoad(savegame)
242 if savegame ~= nil and not savegame.resetVehicles then
243 local spec = self.spec_crabSteering
244 if spec.hasSteeringModes then
245 if savegame.xmlFile:hasProperty(savegame.key..".crabSteering") then
246 local state = savegame.xmlFile:getValue(savegame.key..".crabSteering#state", 1)
247 state = MathUtil.clamp(state, 1, spec.stateMax)
248
249 self:setCrabSteering(state, true)
250 AnimatedVehicle.updateAnimations(self, 99999999, true)
251 self:forceUpdateWheelPhysics(99999999)
252 end
253 end
254 end
255end

onReadStream

Description
Called on client side on join
Definition
onReadStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
271function CrabSteering:onReadStream(streamId, connection)
272 local state = streamReadUIntN(streamId, CrabSteering.STEERING_SEND_NUM_BITS)
273
274 self:setCrabSteering(state, true)
275 AnimatedVehicle.updateAnimations(self, 99999999, true)
276 self:forceUpdateWheelPhysics(99999999)
277end

onReadUpdateStream

Description
Called on on update
Definition
onReadUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdstream ID
integertimestamptimestamp
tableconnectionconnection
Code
293function CrabSteering:onReadUpdateStream(streamId, timestamp, connection)
294 local specArticulatedAxis = self.spec_articulatedAxis
295 if specArticulatedAxis ~= nil and specArticulatedAxis.componentJoint ~= nil then
296 specArticulatedAxis.curRot = streamReadFloat32(streamId)
297 end
298end

onRegisterActionEvents

Description
Definition
onRegisterActionEvents()
Code
588function CrabSteering:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
589 if self.isClient then
590 local spec = self.spec_crabSteering
591 if spec.hasSteeringModes then
592 self:clearActionEventsTable(spec.actionEvents)
593
594 if isActiveForInputIgnoreSelection then
595 local _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, InputAction.TOGGLE_CRABSTEERING, self, CrabSteering.actionEventToggleCrabSteeringModes, false, true, false, true, 1)
596 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
597 g_inputBinding:setActionEventText(actionEventId, string.format(g_i18n:getText("action_steeringModeToggle"), spec.steeringModes[spec.state].name))
598
599 for _, mode in pairs(spec.steeringModes) do
600 if mode.inputAction ~= nil then
601 _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, mode.inputAction, self, CrabSteering.actionEventSetCrabSteeringMode, false, true, false, true, nil)
602 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
603 g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
604 end
605 end
606
607 _, actionEventId = self:addPoweredActionEvent(spec.actionEvents, InputAction.TOGGLE_CRABSTEERING_BACK, self, CrabSteering.actionEventToggleCrabSteeringModes, false, true, false, true, -1)
608 g_inputBinding:setActionEventTextVisibility(actionEventId, false)
609 end
610 end
611 end
612end

onWriteStream

Description
Called on server side on join
Definition
onWriteStream(integer streamId, integer connection)
Arguments
integerstreamIdstreamId
integerconnectionconnection
Code
283function CrabSteering:onWriteStream(streamId, connection)
284 local spec = self.spec_crabSteering
285 streamWriteUIntN(streamId, spec.state, CrabSteering.STEERING_SEND_NUM_BITS)
286end

onWriteUpdateStream

Description
Called on on update
Definition
onWriteUpdateStream(integer streamId, table connection, integer dirtyMask)
Arguments
integerstreamIdstream ID
tableconnectionconnection
integerdirtyMaskdirty mask
Code
305function CrabSteering:onWriteUpdateStream(streamId, connection, dirtyMask)
306 local specArticulatedAxis = self.spec_articulatedAxis
307 if specArticulatedAxis ~= nil and specArticulatedAxis.componentJoint ~= nil then
308 streamWriteFloat32(streamId, specArticulatedAxis.curRot)
309 end
310end

prerequisitesPresent

Description
Checks if all prerequisite specializations are loaded
Definition
prerequisitesPresent(table specializations)
Arguments
tablespecializationsspecializations
Return Values
booleanhasPrerequisitetrue if all prerequisite specializations are loaded
Code
18function CrabSteering.prerequisitesPresent(specializations)
19 return SpecializationUtil.hasSpecialization(Drivable, specializations)
20 and SpecializationUtil.hasSpecialization(Wheels, specializations)
21 and SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations)
22end

registerEventListeners

Description
Definition
registerEventListeners()
Code
85function CrabSteering.registerEventListeners(vehicleType)
86 SpecializationUtil.registerEventListener(vehicleType, "onLoad", CrabSteering)
87 SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", CrabSteering)
88 SpecializationUtil.registerEventListener(vehicleType, "onReadStream", CrabSteering)
89 SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", CrabSteering)
90 SpecializationUtil.registerEventListener(vehicleType, "onReadUpdateStream", CrabSteering)
91 SpecializationUtil.registerEventListener(vehicleType, "onWriteUpdateStream", CrabSteering)
92 SpecializationUtil.registerEventListener(vehicleType, "onAIImplementStart", CrabSteering)
93 SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", CrabSteering)
94end

registerFunctions

Description
Definition
registerFunctions()
Code
69function CrabSteering.registerFunctions(vehicleType)
70 SpecializationUtil.registerFunction(vehicleType, "getCanToggleCrabSteering", CrabSteering.getCanToggleCrabSteering)
71 SpecializationUtil.registerFunction(vehicleType, "setCrabSteering", CrabSteering.setCrabSteering)
72 SpecializationUtil.registerFunction(vehicleType, "updateArticulatedAxisRotation", CrabSteering.updateArticulatedAxisRotation)
73end

registerOverwrittenFunctions

Description
Definition
registerOverwrittenFunctions()
Code
77function CrabSteering.registerOverwrittenFunctions(vehicleType)
78 SpecializationUtil.registerOverwrittenFunction(vehicleType, "updateSteeringAngle", CrabSteering.updateSteeringAngle)
79 SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected", CrabSteering.getCanBeSelected)
80 SpecializationUtil.registerOverwrittenFunction(vehicleType, "loadWheelsFromXML", CrabSteering.loadWheelsFromXML)
81end

registerSteeringModeXMLPaths

Description
Definition
registerSteeringModeXMLPaths()
Code
50function CrabSteering.registerSteeringModeXMLPaths(schema, basePath)
51 schema:register(XMLValueType.L10N_STRING, basePath .. "#name", "Steering mode name")
52 schema:register(XMLValueType.STRING, basePath .. "#inputBindingName", "Input action name")
53 schema:register(XMLValueType.INT, basePath .. ".wheel(?)#index", "Wheel Index")
54 schema:register(XMLValueType.NODE_INDEX, basePath .. ".wheel(?)#node", "Wheel Node")
55 schema:register(XMLValueType.ANGLE, basePath .. ".wheel(?)#offset", "Rotation offset", 0)
56 schema:register(XMLValueType.BOOL, basePath .. ".wheel(?)#locked", "Steering is locked", false)
57
58 schema:register(XMLValueType.ANGLE, basePath .. ".articulatedAxis#offset", "Articulated axis offset angle", 0)
59 schema:register(XMLValueType.BOOL, basePath .. ".articulatedAxis#locked", "Articulated axis is locked", false)
60 schema:register(XMLValueType.VECTOR_N, basePath .. ".articulatedAxis#wheelIndices", "Wheel indices")
61
62 schema:register(XMLValueType.STRING, basePath .. ".animation(?)#name", "Change animation name")
63 schema:register(XMLValueType.FLOAT, basePath .. ".animation(?)#speed", "Animation speed", 1)
64 schema:register(XMLValueType.FLOAT, basePath .. ".animation(?)#stopTime", "Animation stop time")
65end

saveToXMLFile

Description
Definition
saveToXMLFile()
Code
259function CrabSteering:saveToXMLFile(xmlFile, key, usedModNames)
260 local spec = self.spec_crabSteering
261 if spec.hasSteeringModes then
262 xmlFile:setValue(key.."#state", spec.state)
263 end
264end

setCrabSteering

Description
Change crap steering mode
Definition
setCrabSteering(integer state, boolean noEventSend)
Arguments
integerstatenew state
booleannoEventSendno event send
Code
324function CrabSteering:setCrabSteering(state, noEventSend)
325 local spec = self.spec_crabSteering
326
327 if noEventSend == nil or noEventSend == false then
328 if g_server ~= nil then
329 g_server:broadcastEvent(SetCrabSteeringEvent.new(self, state), nil, nil, self)
330 else
331 g_client:getServerConnection():sendEvent(SetCrabSteeringEvent.new(self, state))
332 end
333 end
334
335 if state ~= spec.state then
336 local currentMode = spec.steeringModes[spec.state]
337 if currentMode.animations ~= nil then
338 for _,anim in pairs(currentMode.animations) do
339 local curTime = self:getAnimationTime(anim.animName)
340 if anim.stopTime == nil then
341 self:playAnimation(anim.animName, -anim.animSpeed, curTime, noEventSend)
342 end
343 end
344 end
345 local newMode = spec.steeringModes[state]
346 if newMode.animations ~= nil then
347 for _,anim in pairs(newMode.animations) do
348 local curTime = self:getAnimationTime(anim.animName)
349 if anim.stopTime ~= nil then
350 self:setAnimationStopTime(anim.animName, anim.stopTime)
351 local speed = 1.0
352 if curTime > anim.stopTime then
353 speed = -1.0
354 end
355 self:playAnimation(anim.animName, speed, curTime, noEventSend)
356 else
357 self:playAnimation(anim.animName, anim.animSpeed, curTime, noEventSend)
358 end
359 end
360 end
361 end
362
363 spec.state = state
364
365 local actionEvent = spec.actionEvents[InputAction.TOGGLE_CRABSTEERING]
366 if actionEvent ~= nil then
367 g_inputBinding:setActionEventText(actionEvent.actionEventId, string.format(g_i18n:getText("action_steeringModeToggle"), spec.steeringModes[spec.state].name))
368 end
369end

updateArticulatedAxisRotation

Description
Update articulated axis rotation
Definition
updateArticulatedAxisRotation(float steeringAngle, float dt)
Arguments
floatsteeringAnglesteering angle
floatdttime since last call in ms
Return Values
floatsteeringAngleadjusted steering angle
Code
452function CrabSteering:updateArticulatedAxisRotation(steeringAngle, dt)
453 local spec = self.spec_crabSteering
454 local specArticulatedAxis = self.spec_articulatedAxis
455 local specDriveable = self.spec_drivable
456
457 if spec.stateMax == 0 then
458 return steeringAngle
459 end
460
461 if not self.isServer then
462 return specArticulatedAxis.curRot
463 end
464
465 local currentMode = spec.steeringModes[spec.state]
466 if currentMode.articulatedAxis == nil then
467 return steeringAngle
468 end
469
470 --
471 local rotScale = math.min(1.0/(self.lastSpeed*specDriveable.speedRotScale+specDriveable.speedRotScaleOffset), 1)
472 local delta = dt*0.001*self.autoRotateBackSpeed*rotScale * spec.toggleSpeedFactor
473
474 if spec.currentArticulatedAxisOffset < currentMode.articulatedAxis.offset then
475 spec.currentArticulatedAxisOffset = math.min(currentMode.articulatedAxis.offset, spec.currentArticulatedAxisOffset + delta)
476 elseif spec.currentArticulatedAxisOffset > currentMode.articulatedAxis.offset then
477 spec.currentArticulatedAxisOffset = math.max(currentMode.articulatedAxis.offset, spec.currentArticulatedAxisOffset - delta)
478 end
479
480 -- adjust rotSpeed
481 if currentMode.articulatedAxis.locked then
482 if specArticulatedAxis.rotSpeed > 0 then
483 specArticulatedAxis.rotSpeed = math.max(0, specArticulatedAxis.rotSpeed - delta)
484 elseif specArticulatedAxis.rotSpeed < 0 then
485 specArticulatedAxis.rotSpeed = math.min(0, specArticulatedAxis.rotSpeed + delta)
486 end
487 else
488 if specArticulatedAxis.rotSpeed > currentMode.articulatedAxis.rotSpeedBackUp then
489 specArticulatedAxis.rotSpeed = math.max(currentMode.articulatedAxis.rotSpeedBackUp, specArticulatedAxis.rotSpeed - delta)
490 elseif specArticulatedAxis.rotSpeed < currentMode.articulatedAxis.rotSpeedBackUp then
491 specArticulatedAxis.rotSpeed = math.min(currentMode.articulatedAxis.rotSpeedBackUp, specArticulatedAxis.rotSpeed + delta)
492 end
493 end
494
495 local rotSpeed
496 if (self.rotatedTime) * (currentMode.articulatedAxis.rotSpeedBackUp) > 0 then
497 rotSpeed = (specArticulatedAxis.rotMax - spec.currentArticulatedAxisOffset) / self.wheelSteeringDuration
498 else
499 rotSpeed = (specArticulatedAxis.rotMin - spec.currentArticulatedAxisOffset) / self.wheelSteeringDuration
500 end
501
502 local f = math.abs(specArticulatedAxis.rotSpeed) / math.abs(currentMode.articulatedAxis.rotSpeedBackUp)
503 rotSpeed = rotSpeed * f
504
505 steeringAngle = spec.currentArticulatedAxisOffset + (math.abs(self.rotatedTime) * rotSpeed)
506
507 -- change rotation just if wheels are moving (so you don't have to steer in the opposite direction while turning on crab steering)
508 if table.getn(currentMode.articulatedAxis.wheelIndices) > 0 and spec.distFromCompJointToCenterOfBackWheels ~= nil and self.movingDirection >= 0 then
509 local wheels = self:getWheels()
510
511 local curRot = MathUtil.sign(currentMode.articulatedAxis.rotSpeedBackUp) * specArticulatedAxis.curRot
512
513 local alpha = 0
514 local count = 0
515 for _,wheelIndex in pairs(currentMode.articulatedAxis.wheelIndices) do
516 alpha = alpha + wheels[wheelIndex].steeringAngle
517 count = count + 1
518 end
519 alpha = alpha / count
520 alpha = alpha - curRot
521
522 local v = 0
523 count = 0
524 for _,wheelIndex in pairs(currentMode.articulatedAxis.wheelIndices) do
525 local wheel = wheels[wheelIndex]
526 local axleSpeed = getWheelShapeAxleSpeed(wheel.node, wheel.wheelShape) -- rad/sec
527 if wheel.hasGroundContact then
528 local longSlip, _ = getWheelShapeSlip(wheel.node, wheel.wheelShape)
529 local fac = 1.0 - math.min(1.0, longSlip)
530 v = v + fac * axleSpeed * wheel.radius
531 count = count + 1
532 end
533 end
534 v = v / count
535 local h = v * 0.001 * dt
536 local g = math.sin(alpha) * h
537 local a = math.cos(alpha) * h
538 local ls = spec.distFromCompJointToCenterOfBackWheels
539 local beta = math.atan2(g, ls - a)
540
541 steeringAngle = MathUtil.sign(currentMode.articulatedAxis.rotSpeedBackUp) * (curRot + beta)
542
543 spec.articulatedAxisOffsetChanged = true
544 spec.articulatedAxisLastAngle = steeringAngle
545 else
546 local changingTime = spec.articulatedAxisChangingTime
547 if spec.articulatedAxisOffsetChanged then
548 changingTime = 2500
549 spec.articulatedAxisOffsetChanged = false
550 end
551
552 --smooth blending if steering change is from crab to normal
553 if changingTime > 0 then
554 local pos = changingTime / 2500
555 steeringAngle = steeringAngle * (1-pos) + spec.articulatedAxisLastAngle * pos
556 spec.articulatedAxisChangingTime = changingTime - dt
557 end
558 end
559
560 steeringAngle = math.max(specArticulatedAxis.rotMin, math.min(specArticulatedAxis.rotMax, steeringAngle))
561
562 return steeringAngle
563end

updateSteeringAngle

Description
Update steering angle depending of the selected steering mode
Definition
updateSteeringAngle(table wheel, float dt, float steeringAngle)
Arguments
tablewheelwheel
floatdttime since last call in ms
floatsteeringAnglesteering angle
Return Values
floatsteeringAngleadjusted steering angle
Code
377function CrabSteering:updateSteeringAngle(superFunc, wheel, dt, steeringAngle)
378 local spec = self.spec_crabSteering
379 local specDriveable = self.spec_drivable
380
381 if spec.stateMax == 0 then
382 return superFunc(self, wheel, dt, steeringAngle)
383 end
384
385 local currentMode = spec.steeringModes[spec.state]
386 for i=1, #currentMode.wheels do
387 local wheelProperties = currentMode.wheels[i]
388 if wheelProperties.wheelIndex == wheel.xmlIndex + 1 then
389 local rotScale = math.min(1.0/(self.lastSpeed*specDriveable.speedRotScale+specDriveable.speedRotScaleOffset), 1)
390 local delta = dt*0.001*self.autoRotateBackSpeed*rotScale * spec.toggleSpeedFactor
391
392 if wheel.steeringOffset < wheelProperties.offset then
393 wheel.steeringOffset = math.min(wheelProperties.offset, wheel.steeringOffset + delta)
394 elseif wheel.steeringOffset > wheelProperties.offset then
395 wheel.steeringOffset = math.max(wheelProperties.offset, wheel.steeringOffset - delta)
396 end
397
398 if not wheelProperties.locked then
399 local rotSpeed
400 if self.rotatedTime > 0 then
401 rotSpeed = (wheel.rotMax - wheel.steeringOffset) / self.wheelSteeringDuration
402 if wheel.rotSpeedBackUp < 0 then
403 rotSpeed = (wheel.rotMin - wheel.steeringOffset) / self.wheelSteeringDuration
404 end
405 else
406 rotSpeed = -(wheel.rotMin - wheel.steeringOffset) / self.wheelSteeringDuration
407 if wheel.rotSpeedBackUp < 0 then
408 rotSpeed = -(wheel.rotMax - wheel.steeringOffset) / self.wheelSteeringDuration
409 end
410 end
411
412 if wheel.rotSpeed < wheel.rotSpeedBackUp then
413 wheel.rotSpeed = math.min(wheel.rotSpeedBackUp, wheel.rotSpeed + delta)
414 elseif wheel.rotSpeed > wheel.rotSpeedBackUp then
415 wheel.rotSpeed = math.max(wheel.rotSpeedBackUp, wheel.rotSpeed - delta)
416 end
417 local f = wheel.rotSpeed / wheel.rotSpeedBackUp
418
419 steeringAngle = wheel.steeringOffset + (self.rotatedTime * f * rotSpeed)
420 else
421 if wheel.steeringAngle > wheel.steeringOffset or steeringAngle > wheel.steeringOffset then
422 steeringAngle = math.max(wheel.steeringOffset, math.min(wheel.steeringAngle, steeringAngle) - delta)
423 elseif wheel.steeringAngle < wheel.steeringOffset or steeringAngle < wheel.steeringOffset then
424 steeringAngle = math.min(wheel.steeringOffset, math.max(wheel.steeringAngle, steeringAngle) + delta)
425 end
426
427 if steeringAngle == wheel.steeringOffset then
428 wheel.rotSpeed = 0
429 else
430 if wheel.rotSpeed < 0 then
431 wheel.rotSpeed = math.min(0, wheel.rotSpeed + delta)
432 elseif wheel.rotSpeed > 0 then
433 wheel.rotSpeed = math.max(0, wheel.rotSpeed - delta)
434 end
435 end
436 end
437
438 steeringAngle = MathUtil.clamp(steeringAngle, wheel.rotMin, wheel.rotMax)
439
440 break
441 end
442 end
443
444 return steeringAngle
445end