Skip to content

Recover from being blocked by a static obstacle during fieldwork - #1287

Draft
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery
Draft

Recover from being blocked by a static obstacle during fieldwork#1287
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery

Conversation

@helgehelge123

Copy link
Copy Markdown

Problem

The ProximityController stops the vehicle in front of any obstacle and already fires onBlockingObject / onBlockingVehicle after ~5/7 seconds of blockade - but during normal fieldwork no listener is registered (only AITurn registers one during turns). A vehicle blocked mid-course by a tree, a pole or a parked vehicle stands there forever, showing BLOCKED_BY_OBJECT.

Solution

AIDriveStrategyFieldWorkCourse now registers both blocking listeners and recovers, reusing existing building blocks (Course.createStraightReverseCourse, startPathfindingToNextWaypoint):

  1. raise implements, back up 10 m (new REVERSING_AFTER_BLOCKED state, added to the implement controllers' default disabled states),
  2. pathfind around the obstacle to the first course waypoint at least 20 m away and resume there via the existing work starter (the strip the obstacle occupies cannot be worked anyway),
  3. after 3 failed attempts in the same area, stop the job with AIMessageErrorBlockedByObject instead of looping.

Notes:

  • Blocking vehicles are only treated like a static obstacle when they are stationary (< 1 km/h) - moving vehicles are still waited for. This also covers AI-driven vehicles that stand still while blocking (e.g. a harvester standing bent across the path). The combine strategy keeps its own onBlockingVehicle handling, as it registers its listener after this one.
  • AITurn unregisters the blocking object listener at the end of every turn (single-slot registration), so the listener is re-registered in the WORKING branch of getDriveData.
  • Tunables are class constants (blockedRecoveryReverseDistance, blockedRecoverySkipDistance, blockedRecoveryMaxAttempts).

Testing

Tested in singleplayer with obstacles placed mid-row and on headlands. Feedback on edge cases (convoys, vine fields) is very welcome.

🤖 Generated with Claude Code

The ProximityController stops the vehicle in front of any obstacle and
already fires onBlockingObject/onBlockingVehicle after a few seconds,
but no listener was registered while working, so a vehicle blocked by
a tree, a pole or a parked vehicle simply stood there forever with the
BLOCKED_BY_OBJECT info text.
AIDriveStrategyFieldWorkCourse now registers both listeners. When
blocked in the WORKING state it raises the implements, backs up 10m
(new REVERSING_AFTER_BLOCKED state) and then uses the existing
startPathfindingToNextWaypoint() to find a way around the obstacle,
resuming the course at the first waypoint at least 20m away (the strip
the obstacle occupies cannot be worked anyway).
Blocking vehicles are only treated like a static obstacle when they
are stationary; moving vehicles are still waited for, and the combine
strategy keeps its own blocking-vehicle handling. Since AITurn
unregisters the blocking object listener at the end of each turn, the
listener is re-registered while working.
After 3 failed attempts in the same area the job is stopped with
AIMessageErrorBlockedByObject instead of looping forever.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tensuko
Tensuko requested a review from pvaikoJuly 4, 2026 22:29

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there
--- clears the obstacle (the strip the obstacle occupies can't be worked anyway)
function AIDriveStrategyFieldWorkCourse:getWaypointToContinueBeyondObstacle()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use the existing Course:getNextWaypointIxWithinDistance() instead.

-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)
self.proximityController:registerBlockingVehicleListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByVehicle)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be overwritten in AIDriveStrategyCombineCourse for combines.

self.fieldWorkerProximityController = FieldWorkerProximityController(self.vehicle, self.workWidth)
-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets the listener in all modes, such as DRIVING_TO_WORK_START_WAYPOINT, and incorrectly result in starting to work (lower implements) after driving around the obstacle. Would be cleaner to only register in the WORKING state.

self:onBlockedByObject(isBack)
end

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could lead to all kinds of colorful scenarios whenever there is a special waypoint within the skip distance, such as a turn, or a connecting path transition.

-- turns and the other states have their own blocked handling
return
end
-- limit the number of attempts in the same area so we do not bounce between obstacles forever

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With 50 meters, what happens when we meet the same object in the following up/down rows?

@Tensuko
Tensuko marked this pull request as draft July 16, 2026 07:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@helgehelge123@pvaiko
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Recover from being blocked by a static obstacle during fieldwork by helgehelge123 · Pull Request #1287 · Courseplay/Courseplay_FS25 · GitHub
Skip to content

Recover from being blocked by a static obstacle during fieldwork - #1287

Draft
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery
Draft

Recover from being blocked by a static obstacle during fieldwork#1287
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery

Conversation

@helgehelge123

Copy link
Copy Markdown

Problem

The ProximityController stops the vehicle in front of any obstacle and already fires onBlockingObject / onBlockingVehicle after ~5/7 seconds of blockade - but during normal fieldwork no listener is registered (only AITurn registers one during turns). A vehicle blocked mid-course by a tree, a pole or a parked vehicle stands there forever, showing BLOCKED_BY_OBJECT.

Solution

AIDriveStrategyFieldWorkCourse now registers both blocking listeners and recovers, reusing existing building blocks (Course.createStraightReverseCourse, startPathfindingToNextWaypoint):

  1. raise implements, back up 10 m (new REVERSING_AFTER_BLOCKED state, added to the implement controllers' default disabled states),
  2. pathfind around the obstacle to the first course waypoint at least 20 m away and resume there via the existing work starter (the strip the obstacle occupies cannot be worked anyway),
  3. after 3 failed attempts in the same area, stop the job with AIMessageErrorBlockedByObject instead of looping.

Notes:

  • Blocking vehicles are only treated like a static obstacle when they are stationary (< 1 km/h) - moving vehicles are still waited for. This also covers AI-driven vehicles that stand still while blocking (e.g. a harvester standing bent across the path). The combine strategy keeps its own onBlockingVehicle handling, as it registers its listener after this one.
  • AITurn unregisters the blocking object listener at the end of every turn (single-slot registration), so the listener is re-registered in the WORKING branch of getDriveData.
  • Tunables are class constants (blockedRecoveryReverseDistance, blockedRecoverySkipDistance, blockedRecoveryMaxAttempts).

Testing

Tested in singleplayer with obstacles placed mid-row and on headlands. Feedback on edge cases (convoys, vine fields) is very welcome.

🤖 Generated with Claude Code

The ProximityController stops the vehicle in front of any obstacle and
already fires onBlockingObject/onBlockingVehicle after a few seconds,
but no listener was registered while working, so a vehicle blocked by
a tree, a pole or a parked vehicle simply stood there forever with the
BLOCKED_BY_OBJECT info text.
AIDriveStrategyFieldWorkCourse now registers both listeners. When
blocked in the WORKING state it raises the implements, backs up 10m
(new REVERSING_AFTER_BLOCKED state) and then uses the existing
startPathfindingToNextWaypoint() to find a way around the obstacle,
resuming the course at the first waypoint at least 20m away (the strip
the obstacle occupies cannot be worked anyway).
Blocking vehicles are only treated like a static obstacle when they
are stationary; moving vehicles are still waited for, and the combine
strategy keeps its own blocking-vehicle handling. Since AITurn
unregisters the blocking object listener at the end of each turn, the
listener is re-registered while working.
After 3 failed attempts in the same area the job is stopped with
AIMessageErrorBlockedByObject instead of looping forever.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tensuko
Tensuko requested a review from pvaikoJuly 4, 2026 22:29

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there
--- clears the obstacle (the strip the obstacle occupies can't be worked anyway)
function AIDriveStrategyFieldWorkCourse:getWaypointToContinueBeyondObstacle()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use the existing Course:getNextWaypointIxWithinDistance() instead.

-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)
self.proximityController:registerBlockingVehicleListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByVehicle)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be overwritten in AIDriveStrategyCombineCourse for combines.

self.fieldWorkerProximityController = FieldWorkerProximityController(self.vehicle, self.workWidth)
-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets the listener in all modes, such as DRIVING_TO_WORK_START_WAYPOINT, and incorrectly result in starting to work (lower implements) after driving around the obstacle. Would be cleaner to only register in the WORKING state.

self:onBlockedByObject(isBack)
end

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could lead to all kinds of colorful scenarios whenever there is a special waypoint within the skip distance, such as a turn, or a connecting path transition.

-- turns and the other states have their own blocked handling
return
end
-- limit the number of attempts in the same area so we do not bounce between obstacles forever

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With 50 meters, what happens when we meet the same object in the following up/down rows?

@Tensuko
Tensuko marked this pull request as draft July 16, 2026 07:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@helgehelge123@pvaiko
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Recover from being blocked by a static obstacle during fieldwork by helgehelge123 · Pull Request #1287 · Courseplay/Courseplay_FS25 · GitHub
Skip to content

Recover from being blocked by a static obstacle during fieldwork - #1287

Draft
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery
Draft

Recover from being blocked by a static obstacle during fieldwork#1287
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery

Conversation

@helgehelge123

Copy link
Copy Markdown

Problem

The ProximityController stops the vehicle in front of any obstacle and already fires onBlockingObject / onBlockingVehicle after ~5/7 seconds of blockade - but during normal fieldwork no listener is registered (only AITurn registers one during turns). A vehicle blocked mid-course by a tree, a pole or a parked vehicle stands there forever, showing BLOCKED_BY_OBJECT.

Solution

AIDriveStrategyFieldWorkCourse now registers both blocking listeners and recovers, reusing existing building blocks (Course.createStraightReverseCourse, startPathfindingToNextWaypoint):

  1. raise implements, back up 10 m (new REVERSING_AFTER_BLOCKED state, added to the implement controllers' default disabled states),
  2. pathfind around the obstacle to the first course waypoint at least 20 m away and resume there via the existing work starter (the strip the obstacle occupies cannot be worked anyway),
  3. after 3 failed attempts in the same area, stop the job with AIMessageErrorBlockedByObject instead of looping.

Notes:

  • Blocking vehicles are only treated like a static obstacle when they are stationary (< 1 km/h) - moving vehicles are still waited for. This also covers AI-driven vehicles that stand still while blocking (e.g. a harvester standing bent across the path). The combine strategy keeps its own onBlockingVehicle handling, as it registers its listener after this one.
  • AITurn unregisters the blocking object listener at the end of every turn (single-slot registration), so the listener is re-registered in the WORKING branch of getDriveData.
  • Tunables are class constants (blockedRecoveryReverseDistance, blockedRecoverySkipDistance, blockedRecoveryMaxAttempts).

Testing

Tested in singleplayer with obstacles placed mid-row and on headlands. Feedback on edge cases (convoys, vine fields) is very welcome.

🤖 Generated with Claude Code

The ProximityController stops the vehicle in front of any obstacle and
already fires onBlockingObject/onBlockingVehicle after a few seconds,
but no listener was registered while working, so a vehicle blocked by
a tree, a pole or a parked vehicle simply stood there forever with the
BLOCKED_BY_OBJECT info text.
AIDriveStrategyFieldWorkCourse now registers both listeners. When
blocked in the WORKING state it raises the implements, backs up 10m
(new REVERSING_AFTER_BLOCKED state) and then uses the existing
startPathfindingToNextWaypoint() to find a way around the obstacle,
resuming the course at the first waypoint at least 20m away (the strip
the obstacle occupies cannot be worked anyway).
Blocking vehicles are only treated like a static obstacle when they
are stationary; moving vehicles are still waited for, and the combine
strategy keeps its own blocking-vehicle handling. Since AITurn
unregisters the blocking object listener at the end of each turn, the
listener is re-registered while working.
After 3 failed attempts in the same area the job is stopped with
AIMessageErrorBlockedByObject instead of looping forever.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tensuko
Tensuko requested a review from pvaikoJuly 4, 2026 22:29

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there
--- clears the obstacle (the strip the obstacle occupies can't be worked anyway)
function AIDriveStrategyFieldWorkCourse:getWaypointToContinueBeyondObstacle()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use the existing Course:getNextWaypointIxWithinDistance() instead.

-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)
self.proximityController:registerBlockingVehicleListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByVehicle)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be overwritten in AIDriveStrategyCombineCourse for combines.

self.fieldWorkerProximityController = FieldWorkerProximityController(self.vehicle, self.workWidth)
-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets the listener in all modes, such as DRIVING_TO_WORK_START_WAYPOINT, and incorrectly result in starting to work (lower implements) after driving around the obstacle. Would be cleaner to only register in the WORKING state.

self:onBlockedByObject(isBack)
end

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could lead to all kinds of colorful scenarios whenever there is a special waypoint within the skip distance, such as a turn, or a connecting path transition.

-- turns and the other states have their own blocked handling
return
end
-- limit the number of attempts in the same area so we do not bounce between obstacles forever

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With 50 meters, what happens when we meet the same object in the following up/down rows?

@Tensuko
Tensuko marked this pull request as draft July 16, 2026 07:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@helgehelge123@pvaiko
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Recover from being blocked by a static obstacle during fieldwork by helgehelge123 · Pull Request #1287 · Courseplay/Courseplay_FS25 · GitHub
Skip to content

Recover from being blocked by a static obstacle during fieldwork - #1287

Draft
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery
Draft

Recover from being blocked by a static obstacle during fieldwork#1287
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery

Conversation

@helgehelge123

Copy link
Copy Markdown

Problem

The ProximityController stops the vehicle in front of any obstacle and already fires onBlockingObject / onBlockingVehicle after ~5/7 seconds of blockade - but during normal fieldwork no listener is registered (only AITurn registers one during turns). A vehicle blocked mid-course by a tree, a pole or a parked vehicle stands there forever, showing BLOCKED_BY_OBJECT.

Solution

AIDriveStrategyFieldWorkCourse now registers both blocking listeners and recovers, reusing existing building blocks (Course.createStraightReverseCourse, startPathfindingToNextWaypoint):

  1. raise implements, back up 10 m (new REVERSING_AFTER_BLOCKED state, added to the implement controllers' default disabled states),
  2. pathfind around the obstacle to the first course waypoint at least 20 m away and resume there via the existing work starter (the strip the obstacle occupies cannot be worked anyway),
  3. after 3 failed attempts in the same area, stop the job with AIMessageErrorBlockedByObject instead of looping.

Notes:

  • Blocking vehicles are only treated like a static obstacle when they are stationary (< 1 km/h) - moving vehicles are still waited for. This also covers AI-driven vehicles that stand still while blocking (e.g. a harvester standing bent across the path). The combine strategy keeps its own onBlockingVehicle handling, as it registers its listener after this one.
  • AITurn unregisters the blocking object listener at the end of every turn (single-slot registration), so the listener is re-registered in the WORKING branch of getDriveData.
  • Tunables are class constants (blockedRecoveryReverseDistance, blockedRecoverySkipDistance, blockedRecoveryMaxAttempts).

Testing

Tested in singleplayer with obstacles placed mid-row and on headlands. Feedback on edge cases (convoys, vine fields) is very welcome.

🤖 Generated with Claude Code

The ProximityController stops the vehicle in front of any obstacle and
already fires onBlockingObject/onBlockingVehicle after a few seconds,
but no listener was registered while working, so a vehicle blocked by
a tree, a pole or a parked vehicle simply stood there forever with the
BLOCKED_BY_OBJECT info text.
AIDriveStrategyFieldWorkCourse now registers both listeners. When
blocked in the WORKING state it raises the implements, backs up 10m
(new REVERSING_AFTER_BLOCKED state) and then uses the existing
startPathfindingToNextWaypoint() to find a way around the obstacle,
resuming the course at the first waypoint at least 20m away (the strip
the obstacle occupies cannot be worked anyway).
Blocking vehicles are only treated like a static obstacle when they
are stationary; moving vehicles are still waited for, and the combine
strategy keeps its own blocking-vehicle handling. Since AITurn
unregisters the blocking object listener at the end of each turn, the
listener is re-registered while working.
After 3 failed attempts in the same area the job is stopped with
AIMessageErrorBlockedByObject instead of looping forever.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tensuko
Tensuko requested a review from pvaikoJuly 4, 2026 22:29

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there
--- clears the obstacle (the strip the obstacle occupies can't be worked anyway)
function AIDriveStrategyFieldWorkCourse:getWaypointToContinueBeyondObstacle()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use the existing Course:getNextWaypointIxWithinDistance() instead.

-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)
self.proximityController:registerBlockingVehicleListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByVehicle)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be overwritten in AIDriveStrategyCombineCourse for combines.

self.fieldWorkerProximityController = FieldWorkerProximityController(self.vehicle, self.workWidth)
-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets the listener in all modes, such as DRIVING_TO_WORK_START_WAYPOINT, and incorrectly result in starting to work (lower implements) after driving around the obstacle. Would be cleaner to only register in the WORKING state.

self:onBlockedByObject(isBack)
end

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could lead to all kinds of colorful scenarios whenever there is a special waypoint within the skip distance, such as a turn, or a connecting path transition.

-- turns and the other states have their own blocked handling
return
end
-- limit the number of attempts in the same area so we do not bounce between obstacles forever

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With 50 meters, what happens when we meet the same object in the following up/down rows?

@Tensuko
Tensuko marked this pull request as draft July 16, 2026 07:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@helgehelge123@pvaiko
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Recover from being blocked by a static obstacle during fieldwork by helgehelge123 · Pull Request #1287 · Courseplay/Courseplay_FS25 · GitHub
Skip to content

Recover from being blocked by a static obstacle during fieldwork - #1287

Draft
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery
Draft

Recover from being blocked by a static obstacle during fieldwork#1287
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery

Conversation

@helgehelge123

Copy link
Copy Markdown

Problem

The ProximityController stops the vehicle in front of any obstacle and already fires onBlockingObject / onBlockingVehicle after ~5/7 seconds of blockade - but during normal fieldwork no listener is registered (only AITurn registers one during turns). A vehicle blocked mid-course by a tree, a pole or a parked vehicle stands there forever, showing BLOCKED_BY_OBJECT.

Solution

AIDriveStrategyFieldWorkCourse now registers both blocking listeners and recovers, reusing existing building blocks (Course.createStraightReverseCourse, startPathfindingToNextWaypoint):

  1. raise implements, back up 10 m (new REVERSING_AFTER_BLOCKED state, added to the implement controllers' default disabled states),
  2. pathfind around the obstacle to the first course waypoint at least 20 m away and resume there via the existing work starter (the strip the obstacle occupies cannot be worked anyway),
  3. after 3 failed attempts in the same area, stop the job with AIMessageErrorBlockedByObject instead of looping.

Notes:

  • Blocking vehicles are only treated like a static obstacle when they are stationary (< 1 km/h) - moving vehicles are still waited for. This also covers AI-driven vehicles that stand still while blocking (e.g. a harvester standing bent across the path). The combine strategy keeps its own onBlockingVehicle handling, as it registers its listener after this one.
  • AITurn unregisters the blocking object listener at the end of every turn (single-slot registration), so the listener is re-registered in the WORKING branch of getDriveData.
  • Tunables are class constants (blockedRecoveryReverseDistance, blockedRecoverySkipDistance, blockedRecoveryMaxAttempts).

Testing

Tested in singleplayer with obstacles placed mid-row and on headlands. Feedback on edge cases (convoys, vine fields) is very welcome.

🤖 Generated with Claude Code

The ProximityController stops the vehicle in front of any obstacle and
already fires onBlockingObject/onBlockingVehicle after a few seconds,
but no listener was registered while working, so a vehicle blocked by
a tree, a pole or a parked vehicle simply stood there forever with the
BLOCKED_BY_OBJECT info text.
AIDriveStrategyFieldWorkCourse now registers both listeners. When
blocked in the WORKING state it raises the implements, backs up 10m
(new REVERSING_AFTER_BLOCKED state) and then uses the existing
startPathfindingToNextWaypoint() to find a way around the obstacle,
resuming the course at the first waypoint at least 20m away (the strip
the obstacle occupies cannot be worked anyway).
Blocking vehicles are only treated like a static obstacle when they
are stationary; moving vehicles are still waited for, and the combine
strategy keeps its own blocking-vehicle handling. Since AITurn
unregisters the blocking object listener at the end of each turn, the
listener is re-registered while working.
After 3 failed attempts in the same area the job is stopped with
AIMessageErrorBlockedByObject instead of looping forever.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tensuko
Tensuko requested a review from pvaikoJuly 4, 2026 22:29

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there
--- clears the obstacle (the strip the obstacle occupies can't be worked anyway)
function AIDriveStrategyFieldWorkCourse:getWaypointToContinueBeyondObstacle()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use the existing Course:getNextWaypointIxWithinDistance() instead.

-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)
self.proximityController:registerBlockingVehicleListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByVehicle)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be overwritten in AIDriveStrategyCombineCourse for combines.

self.fieldWorkerProximityController = FieldWorkerProximityController(self.vehicle, self.workWidth)
-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets the listener in all modes, such as DRIVING_TO_WORK_START_WAYPOINT, and incorrectly result in starting to work (lower implements) after driving around the obstacle. Would be cleaner to only register in the WORKING state.

self:onBlockedByObject(isBack)
end

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could lead to all kinds of colorful scenarios whenever there is a special waypoint within the skip distance, such as a turn, or a connecting path transition.

-- turns and the other states have their own blocked handling
return
end
-- limit the number of attempts in the same area so we do not bounce between obstacles forever

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With 50 meters, what happens when we meet the same object in the following up/down rows?

@Tensuko
Tensuko marked this pull request as draft July 16, 2026 07:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@helgehelge123@pvaiko
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Recover from being blocked by a static obstacle during fieldwork by helgehelge123 · Pull Request #1287 · Courseplay/Courseplay_FS25 · GitHub
Skip to content

Recover from being blocked by a static obstacle during fieldwork - #1287

Draft
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery
Draft

Recover from being blocked by a static obstacle during fieldwork#1287
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery

Conversation

@helgehelge123

Copy link
Copy Markdown

Problem

The ProximityController stops the vehicle in front of any obstacle and already fires onBlockingObject / onBlockingVehicle after ~5/7 seconds of blockade - but during normal fieldwork no listener is registered (only AITurn registers one during turns). A vehicle blocked mid-course by a tree, a pole or a parked vehicle stands there forever, showing BLOCKED_BY_OBJECT.

Solution

AIDriveStrategyFieldWorkCourse now registers both blocking listeners and recovers, reusing existing building blocks (Course.createStraightReverseCourse, startPathfindingToNextWaypoint):

  1. raise implements, back up 10 m (new REVERSING_AFTER_BLOCKED state, added to the implement controllers' default disabled states),
  2. pathfind around the obstacle to the first course waypoint at least 20 m away and resume there via the existing work starter (the strip the obstacle occupies cannot be worked anyway),
  3. after 3 failed attempts in the same area, stop the job with AIMessageErrorBlockedByObject instead of looping.

Notes:

  • Blocking vehicles are only treated like a static obstacle when they are stationary (< 1 km/h) - moving vehicles are still waited for. This also covers AI-driven vehicles that stand still while blocking (e.g. a harvester standing bent across the path). The combine strategy keeps its own onBlockingVehicle handling, as it registers its listener after this one.
  • AITurn unregisters the blocking object listener at the end of every turn (single-slot registration), so the listener is re-registered in the WORKING branch of getDriveData.
  • Tunables are class constants (blockedRecoveryReverseDistance, blockedRecoverySkipDistance, blockedRecoveryMaxAttempts).

Testing

Tested in singleplayer with obstacles placed mid-row and on headlands. Feedback on edge cases (convoys, vine fields) is very welcome.

🤖 Generated with Claude Code

The ProximityController stops the vehicle in front of any obstacle and
already fires onBlockingObject/onBlockingVehicle after a few seconds,
but no listener was registered while working, so a vehicle blocked by
a tree, a pole or a parked vehicle simply stood there forever with the
BLOCKED_BY_OBJECT info text.
AIDriveStrategyFieldWorkCourse now registers both listeners. When
blocked in the WORKING state it raises the implements, backs up 10m
(new REVERSING_AFTER_BLOCKED state) and then uses the existing
startPathfindingToNextWaypoint() to find a way around the obstacle,
resuming the course at the first waypoint at least 20m away (the strip
the obstacle occupies cannot be worked anyway).
Blocking vehicles are only treated like a static obstacle when they
are stationary; moving vehicles are still waited for, and the combine
strategy keeps its own blocking-vehicle handling. Since AITurn
unregisters the blocking object listener at the end of each turn, the
listener is re-registered while working.
After 3 failed attempts in the same area the job is stopped with
AIMessageErrorBlockedByObject instead of looping forever.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tensuko
Tensuko requested a review from pvaikoJuly 4, 2026 22:29

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there
--- clears the obstacle (the strip the obstacle occupies can't be worked anyway)
function AIDriveStrategyFieldWorkCourse:getWaypointToContinueBeyondObstacle()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use the existing Course:getNextWaypointIxWithinDistance() instead.

-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)
self.proximityController:registerBlockingVehicleListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByVehicle)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be overwritten in AIDriveStrategyCombineCourse for combines.

self.fieldWorkerProximityController = FieldWorkerProximityController(self.vehicle, self.workWidth)
-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets the listener in all modes, such as DRIVING_TO_WORK_START_WAYPOINT, and incorrectly result in starting to work (lower implements) after driving around the obstacle. Would be cleaner to only register in the WORKING state.

self:onBlockedByObject(isBack)
end

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could lead to all kinds of colorful scenarios whenever there is a special waypoint within the skip distance, such as a turn, or a connecting path transition.

-- turns and the other states have their own blocked handling
return
end
-- limit the number of attempts in the same area so we do not bounce between obstacles forever

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With 50 meters, what happens when we meet the same object in the following up/down rows?

@Tensuko
Tensuko marked this pull request as draft July 16, 2026 07:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@helgehelge123@pvaiko
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Recover from being blocked by a static obstacle during fieldwork by helgehelge123 · Pull Request #1287 · Courseplay/Courseplay_FS25 · GitHub
Skip to content

Recover from being blocked by a static obstacle during fieldwork - #1287

Draft
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery
Draft

Recover from being blocked by a static obstacle during fieldwork#1287
helgehelge123 wants to merge 1 commit into
Courseplay:mainfrom
helgehelge123:feature/fieldwork-blocked-recovery

Conversation

@helgehelge123

Copy link
Copy Markdown

Problem

The ProximityController stops the vehicle in front of any obstacle and already fires onBlockingObject / onBlockingVehicle after ~5/7 seconds of blockade - but during normal fieldwork no listener is registered (only AITurn registers one during turns). A vehicle blocked mid-course by a tree, a pole or a parked vehicle stands there forever, showing BLOCKED_BY_OBJECT.

Solution

AIDriveStrategyFieldWorkCourse now registers both blocking listeners and recovers, reusing existing building blocks (Course.createStraightReverseCourse, startPathfindingToNextWaypoint):

  1. raise implements, back up 10 m (new REVERSING_AFTER_BLOCKED state, added to the implement controllers' default disabled states),
  2. pathfind around the obstacle to the first course waypoint at least 20 m away and resume there via the existing work starter (the strip the obstacle occupies cannot be worked anyway),
  3. after 3 failed attempts in the same area, stop the job with AIMessageErrorBlockedByObject instead of looping.

Notes:

  • Blocking vehicles are only treated like a static obstacle when they are stationary (< 1 km/h) - moving vehicles are still waited for. This also covers AI-driven vehicles that stand still while blocking (e.g. a harvester standing bent across the path). The combine strategy keeps its own onBlockingVehicle handling, as it registers its listener after this one.
  • AITurn unregisters the blocking object listener at the end of every turn (single-slot registration), so the listener is re-registered in the WORKING branch of getDriveData.
  • Tunables are class constants (blockedRecoveryReverseDistance, blockedRecoverySkipDistance, blockedRecoveryMaxAttempts).

Testing

Tested in singleplayer with obstacles placed mid-row and on headlands. Feedback on edge cases (convoys, vine fields) is very welcome.

🤖 Generated with Claude Code

The ProximityController stops the vehicle in front of any obstacle and
already fires onBlockingObject/onBlockingVehicle after a few seconds,
but no listener was registered while working, so a vehicle blocked by
a tree, a pole or a parked vehicle simply stood there forever with the
BLOCKED_BY_OBJECT info text.
AIDriveStrategyFieldWorkCourse now registers both listeners. When
blocked in the WORKING state it raises the implements, backs up 10m
(new REVERSING_AFTER_BLOCKED state) and then uses the existing
startPathfindingToNextWaypoint() to find a way around the obstacle,
resuming the course at the first waypoint at least 20m away (the strip
the obstacle occupies cannot be worked anyway).
Blocking vehicles are only treated like a static obstacle when they
are stationary; moving vehicles are still waited for, and the combine
strategy keeps its own blocking-vehicle handling. Since AITurn
unregisters the blocking object listener at the end of each turn, the
listener is re-registered while working.
After 3 failed attempts in the same area the job is stopped with
AIMessageErrorBlockedByObject instead of looping forever.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tensuko
Tensuko requested a review from pvaikoJuly 4, 2026 22:29

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there
--- clears the obstacle (the strip the obstacle occupies can't be worked anyway)
function AIDriveStrategyFieldWorkCourse:getWaypointToContinueBeyondObstacle()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use the existing Course:getNextWaypointIxWithinDistance() instead.

-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)
self.proximityController:registerBlockingVehicleListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByVehicle)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be overwritten in AIDriveStrategyCombineCourse for combines.

self.fieldWorkerProximityController = FieldWorkerProximityController(self.vehicle, self.workWidth)
-- instead of standing in front of a static obstacle forever, try to recover
-- (subclasses like the combine strategy may overwrite the vehicle listener with their own)
self.proximityController:registerBlockingObjectListener(self, AIDriveStrategyFieldWorkCourse.onBlockedByObject)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets the listener in all modes, such as DRIVING_TO_WORK_START_WAYPOINT, and incorrectly result in starting to work (lower implements) after driving around the obstacle. Would be cleaner to only register in the WORKING state.

self:onBlockedByObject(isBack)
end

--- First waypoint of the fieldwork course that is far enough from the vehicle so that resuming there

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could lead to all kinds of colorful scenarios whenever there is a special waypoint within the skip distance, such as a turn, or a connecting path transition.

-- turns and the other states have their own blocked handling
return
end
-- limit the number of attempts in the same area so we do not bounce between obstacles forever

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With 50 meters, what happens when we meet the same object in the following up/down rows?

@Tensuko
Tensuko marked this pull request as draft July 16, 2026 07:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@helgehelge123@pvaiko