Skip to content

Commit

Permalink
feat: async field detection in GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Vaiko committed Jan 20, 2025
1 parent ba28553 commit ef1eb07
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 13 deletions.
4 changes: 4 additions & 0 deletions config/MasterTranslations.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
<Text language="de"><![CDATA[Konnte keinen Kurs generieren. Bitte versuchen es mit anderen Einstellungen.]]></Text>
<Text language="en"><![CDATA[Could not generate course. Please try other settings.]]></Text>
</Translation>
<Translation name="CP_error_field_detection_still_running">
<Text language="de"><![CDATA[Felderkennung läuft noch.]]></Text>
<Text language="en"><![CDATA[Field detection still running.]]></Text>
</Translation>
<Translation name="CP_error_not_on_field">
<Text language="de"><![CDATA[Ziel ist nicht auf einem Feld.]]></Text>
<Text language="en"><![CDATA[Target is not on a field.]]></Text>
Expand Down
31 changes: 19 additions & 12 deletions scripts/ai/jobs/CpAIJobFieldWork.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,35 +109,42 @@ function CpAIJobFieldWork:validateFieldSetup()
if tx == nil or tz == nil then
return false, g_i18n:getText("CP_error_not_on_field")
end
if self.fieldPolygonPosition then
if self.fieldPolygonPosition.x == tx and self.fieldPolygonPosition.z == tz then
self.logger:debug(vehicle, 'Field position still at %.1f/%.1f, do not detect field boundary again', tx, tz)
return true, ''
end
if vehicle:cpIsFieldBoundaryDetectionRunning() then
return false, g_i18n:getText("CP_error_field_detection_still_running")
end
local x, z = vehicle:cpGetFieldPosition()
if x == tx and z == tz then
self.logger:debug(vehicle, 'Field position still at %.1f/%.1f, do not detect field boundary again', tx, tz)
return true, ''
end
self.logger:debug(vehicle, 'Field position changed to %.1f/%.1f, start field boundary detection', tx, tz)
self.hasValidPosition = false
self.foundVines = nil
local fieldPolygon
fieldPolygon, self.isCustomField = CpFieldUtil.getFieldPolygonAtWorldPosition(tx, tz)

vehicle:cpDetectFieldBoundary(tx, tz, self, CpAIJobFieldWork.onFieldBoundaryDetectionFinished)
-- TODO: return false and nothing, as the detection is still running?
end

function CpAIJobFieldWork:onFieldBoundaryDetectionFinished(vehicle, fieldPolygon, islandPolygons)

self:setFieldPolygon(fieldPolygon)
if fieldPolygon then
self.hasValidPosition = true
self.fieldPolygonPosition = { x = tx, z = tz }
self.foundVines = g_vineScanner:findVineNodesInField(fieldPolygon, tx, tz, self.customField ~= nil)
local x, z = vehicle:cpGetFieldPosition()
self.foundVines = g_vineScanner:findVineNodesInField(fieldPolygon, x, z, self.customField ~= nil)
if self.foundVines then
CpUtil.debugVehicle(CpDebug.DBG_FIELDWORK, vehicle, "Found vine nodes, generating a vine field border.")
fieldPolygon = g_vineScanner:getCourseGeneratorVertices(0, tx, tz)
fieldPolygon = g_vineScanner:getCourseGeneratorVertices(0, x, z)
end
self.selectedFieldPlot:setWaypoints(fieldPolygon)
self.selectedFieldPlot:setVisible(true)
self.selectedFieldPlot:setBrightColor(true)
else
self.selectedFieldPlot:setVisible(false)
-- TODO: here we need to tell somehow the frame about the detection success/failure
return false, g_i18n:getText("CP_error_not_on_field")
end

return true, ''
-- TODO: here we need to tell somehow the frame about the detection success/failure
end

function CpAIJobFieldWork:setValues()
Expand Down
4 changes: 4 additions & 0 deletions scripts/field/FieldBoundaryDetector.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ function FieldBoundaryDetector:init(x, z, vehicle)
self.updates, customField:getName(), x, z)
self:_useCustomField(customField)
return
else
self.logger:info('Field boundary detection failed after %d updates and no custom field found at %.1f %.1f',
self.updates, x, z)
return
end
end
end)
Expand Down
28 changes: 27 additions & 1 deletion scripts/specializations/CpCourseGenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,18 @@ end

function CpCourseGenerator.registerFunctions(vehicleType)
SpecializationUtil.registerFunction(vehicleType, 'cpDetectFieldBoundary', CpCourseGenerator.cpDetectFieldBoundary)
SpecializationUtil.registerFunction(vehicleType, 'cpIsFieldBoundaryDetectionRunning', CpCourseGenerator.cpIsFieldBoundaryDetectionRunning)
SpecializationUtil.registerFunction(vehicleType, 'cpGetFieldPosition', CpCourseGenerator.cpGetFieldPosition)
SpecializationUtil.registerFunction(vehicleType, 'cpGetFieldPolygon', CpCourseGenerator.cpGetFieldPolygon)
SpecializationUtil.registerFunction(vehicleType, 'cpDrawFieldPolygon', CpCourseGenerator.cpDrawFieldPolygon)
end

function CpCourseGenerator:onLoad(savegame)
-- create shortcut to this spec
self.spec_cpCourseGenerator = self["spec_" .. CpCourseGenerator.SPEC_NAME]
self.spec_cpCourseGenerator.logger = Logger(CpCourseGenerator.SPEC_NAME, nil, CpDebug.DBG_COURSES)
-- make sure cpGetFieldPosition always returns at least an empty table
self.spec_cpCourseGenerator.position = {}
end

---@param x number world X coordinate to start the detection at
Expand All @@ -39,16 +44,37 @@ end
---@param onFinishedFunc function callback function to call when finished: onFinishedFunc([object,] vehicle, fieldPolygon, islandPolygons)
function CpCourseGenerator:cpDetectFieldBoundary(x, z, object, onFinishedFunc)
local spec = self.spec_cpCourseGenerator
spec.fieldBoundaryDetector = FieldBoundaryDetector(x, z, self)
if spec.isFieldBoundaryDetectionRunning then
self.logger:warning(self, 'Not starting field boundary detection for %.1f/%.1f, previous for %.1f/%.1f is still running',
x, z, spec.position.x, spec.position.z)
return
end
spec.position = { x = x, z = z }
spec.object = object
spec.onFinishedFunc = onFinishedFunc
spec.fieldBoundaryDetector = FieldBoundaryDetector(x, z, self)
spec.isFieldBoundaryDetectionRunning = true
end

---@return boolean true if field boundary detection is running. Field and island polygons returned while running may
--- be nil or invalid.
function CpCourseGenerator:cpIsFieldBoundaryDetectionRunning()
return self.spec_cpCourseGenerator.isFieldBoundaryDetectionRunning
end

---@return number|nil, number|nil world X and Z coordinates of the last field boundary detection start position, nil
--- if no previous detection was started
function CpCourseGenerator:cpGetFieldPosition()
local spec = self.spec_cpCourseGenerator
return spec.position.x, spec.position.z
end

function CpCourseGenerator:onUpdate(dt)
local spec = self.spec_cpCourseGenerator
if spec.fieldBoundaryDetector then
if not spec.fieldBoundaryDetector:update(dt) then
-- done
spec.isFieldBoundaryDetectionRunning = false
spec.fieldPolygon = spec.fieldBoundaryDetector:getFieldPolygon()
spec.islandPolygons = spec.fieldBoundaryDetector:getIslandPolygons()
spec.fieldBoundaryDetector = nil
Expand Down

0 comments on commit ef1eb07

Please sign in to comment.