Adding 'problems' module - #269

Merged
j-atkins merged 87 commits into
mainfrom
problems
Feb 13, 2026
Merged

Adding 'problems' module#269
j-atkins merged 87 commits into
mainfrom
problems

Conversation

@j-atkins

@j-atkinsj-atkins commented Jan 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds a 'problems' module to VirtualShip, whereby as expeditions are run users are faced with authentic problems which may happen on a real-life research vessel. These can be "general" problems (e.g. delayed food/fuel deliveries, unplanned safety drills), or "instrument" problems (e.g. CTD winch breaks down).

Features & implementation

All problems are associated with a delay duration. There are checks of whether there is already enough contingency time built into the schedule to still reach the next waypoint in time. If there is then the simulation is allowed to continue. However, if the next waypoint would be missed, users are prompted to account for the delay in their schedules and the expedition cannot proceed until the scheduling is resolved.

The problems module interacts with Checkpoint objects to test that the scheduling issues have been resolved. A unique record of the problems is also cached to keep track of and determine whether they've been resolved etc. It may be that dealing with a problem at one waypoint causes more scheduling issues way down the chain of waypoints. This is by design (as similar headaches would be experienced in real life!) and the schedule/checkpoint verification methods should capture this and prompt further changes.

The selection of problems and their execution in the main virtualship run workflow is handled by a new ProblemSimulator class. Specific problem scenarios are housed in scenarios.py as problem classes, which are themselves sub-classes of GeneralProblem and InstrumentProblem base classes (to establish a structure for building complexity in further PRs).

When propagated through virtualship run, a selection of all the problems for the expedition is first created but the individual problems are only raised at the right time. For example, a pre-departure problem will occur before any instrument simulations and a CTD related problem only when the CTD instrument is being simulated.

A new 'prob-level' argument is now added to the virtualship run CLI command. There are three options to choose from:

  • Level 0 = No problems encountered during the expedition (i.e. turn off problems module).
  • Level 1 = 1-2 problems encountered across the expedition [DEFAULT].
  • Level 2 = 1 or more problems encountered, depending on expedition length and complexity, where longer and more complex expeditions will encounter more problems.

N.B. I have set the default to prob_level = 1 for now, as this is best for upcoming in-class VirtualShip use.

Additional notes

I have set up the logic so that if waypoints are added/removed from the expedition, if a waypoint location changes or the instruments employed changes, this will prompt a new set of problems for the expedition. I see this as the expedition having materially changed and it being a 'new' expedition. This also prevents just re-running the same expedition until you get a 'nicer' set of problems (without manually removing the problems cache!).


  • Tests

Closes#120

@j-atkins
j-atkins marked this pull request as draft January 15, 2026 13:31
@j-atkinsj-atkins changed the title ProblemsAdding 'problems' moduleJan 15, 2026
@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I've now changed "prob-level" to "difficulty-level" (as suggested by @VeckoTheGecko) and set the default to "easy". For in-class applications where we want to use problems then we can point to a custom installation with default set to e.g. "medium" instead.

Let me know when you're happy with the PR (cc @ammedd and @erikvansebille) and we'll get this merged 🚢

@ammedd

Copy link
Copy Markdown
Collaborator

I run into the same issue as #281
Good to check/fix before merging this PR?

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I run into the same issue as #281 Good to check/fix before merging this PR?

To understand this better, are you encountering this problem because you have indeed made changes to the timings at waypoints before the waypoint affected by the problem? If so I would say this is the expected behaviour...as we only want users to make changes to waypoint timings after the problem waypoint?

@ammedd

Copy link
Copy Markdown
Collaborator

No, the message is "Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00."
I've only changed waypoint 5 and that is the last waypoint in the expedition.

@erikvansebille

Copy link
Copy Markdown
Member

I don't have time to carefully go through the code again myself, but I think that the issue that Emma raised above is very important to get fixed before merging. Please keep me updated how you are progressing

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

If I understand this correctly, @ammedd your point is about the first part of #281 (waypoint not reached in time) rather than the second part (warning about not re-scheduling previous waypoints)?

In any case, I've asked for the expedition.yaml from @VeckoTheGecko in #281 so that I can investigate this further. In the meantime, and regarding the message:

Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00.
Have you ensured that your schedule includes sufficient time for taking measurements, e.g. CTD casts (in addition to the time it takes to sail between waypoints)?
Hint: previous schedule verification checks (e.g. in the `virtualship plan` tool or after dealing with unexpected problems during the expedition) will not account for measurement times, only the time it takes to sail between waypoints.

This alone is not necessarily unexpected behaviour in the code's existing form. It is possible that a user fixes a scheduling issue as a result of a problem, which passes the schedule.verify() checks (no knowledge of instrument deployment timings, only sailing time) but then the simulate_schedule methods identify that the instrument deployment timings would mean it's late to the following waypoint, so it throws another message saying the waypoint still cannot be reached. I would expect in the case above even adding a few minutes to the waypoint will solve the problem.

If indeed this is what's happening (I will check this thoroughly though using Nick's expedition.yaml), I do appreciate that this is quite clunky from the user's perspective. It reflects the existing workflow in run though where we have a schedule.verify() check and further checks in simulate_schedule. I'll have a look if this can be tidied up.

@j-atkins

j-atkins commented Feb 13, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Update: Schedule.verify() now also takes the instrument deployment times into account when calculating whether the next waypoint can be reached in time. This should avoid situations where Schedule.verify() passes but simulate_measurements fails because instrument deployment timings have since been added to the calculation.

@j-atkins
j-atkins merged commit 8c900a3 into mainFeb 13, 2026
10 checks passed
@j-atkins
j-atkins deleted the problems branch February 13, 2026 14:40
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.

Adding problems during expedition

4 participants

@j-atkins@VeckoTheGecko@ammedd@erikvansebille
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n 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;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Adding 'problems' module - #269

Merged
j-atkins merged 87 commits into
mainfrom
problems
Feb 13, 2026
Merged

Adding 'problems' module#269
j-atkins merged 87 commits into
mainfrom
problems

Conversation

@j-atkins

@j-atkinsj-atkins commented Jan 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds a 'problems' module to VirtualShip, whereby as expeditions are run users are faced with authentic problems which may happen on a real-life research vessel. These can be "general" problems (e.g. delayed food/fuel deliveries, unplanned safety drills), or "instrument" problems (e.g. CTD winch breaks down).

Features & implementation

All problems are associated with a delay duration. There are checks of whether there is already enough contingency time built into the schedule to still reach the next waypoint in time. If there is then the simulation is allowed to continue. However, if the next waypoint would be missed, users are prompted to account for the delay in their schedules and the expedition cannot proceed until the scheduling is resolved.

The problems module interacts with Checkpoint objects to test that the scheduling issues have been resolved. A unique record of the problems is also cached to keep track of and determine whether they've been resolved etc. It may be that dealing with a problem at one waypoint causes more scheduling issues way down the chain of waypoints. This is by design (as similar headaches would be experienced in real life!) and the schedule/checkpoint verification methods should capture this and prompt further changes.

The selection of problems and their execution in the main virtualship run workflow is handled by a new ProblemSimulator class. Specific problem scenarios are housed in scenarios.py as problem classes, which are themselves sub-classes of GeneralProblem and InstrumentProblem base classes (to establish a structure for building complexity in further PRs).

When propagated through virtualship run, a selection of all the problems for the expedition is first created but the individual problems are only raised at the right time. For example, a pre-departure problem will occur before any instrument simulations and a CTD related problem only when the CTD instrument is being simulated.

A new 'prob-level' argument is now added to the virtualship run CLI command. There are three options to choose from:

  • Level 0 = No problems encountered during the expedition (i.e. turn off problems module).
  • Level 1 = 1-2 problems encountered across the expedition [DEFAULT].
  • Level 2 = 1 or more problems encountered, depending on expedition length and complexity, where longer and more complex expeditions will encounter more problems.

N.B. I have set the default to prob_level = 1 for now, as this is best for upcoming in-class VirtualShip use.

Additional notes

I have set up the logic so that if waypoints are added/removed from the expedition, if a waypoint location changes or the instruments employed changes, this will prompt a new set of problems for the expedition. I see this as the expedition having materially changed and it being a 'new' expedition. This also prevents just re-running the same expedition until you get a 'nicer' set of problems (without manually removing the problems cache!).


  • Tests

Closes#120

@j-atkins
j-atkins marked this pull request as draft January 15, 2026 13:31
@j-atkinsj-atkins changed the title ProblemsAdding 'problems' moduleJan 15, 2026
@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I've now changed "prob-level" to "difficulty-level" (as suggested by @VeckoTheGecko) and set the default to "easy". For in-class applications where we want to use problems then we can point to a custom installation with default set to e.g. "medium" instead.

Let me know when you're happy with the PR (cc @ammedd and @erikvansebille) and we'll get this merged 🚢

@ammedd

Copy link
Copy Markdown
Collaborator

I run into the same issue as #281
Good to check/fix before merging this PR?

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I run into the same issue as #281 Good to check/fix before merging this PR?

To understand this better, are you encountering this problem because you have indeed made changes to the timings at waypoints before the waypoint affected by the problem? If so I would say this is the expected behaviour...as we only want users to make changes to waypoint timings after the problem waypoint?

@ammedd

Copy link
Copy Markdown
Collaborator

No, the message is "Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00."
I've only changed waypoint 5 and that is the last waypoint in the expedition.

@erikvansebille

Copy link
Copy Markdown
Member

I don't have time to carefully go through the code again myself, but I think that the issue that Emma raised above is very important to get fixed before merging. Please keep me updated how you are progressing

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

If I understand this correctly, @ammedd your point is about the first part of #281 (waypoint not reached in time) rather than the second part (warning about not re-scheduling previous waypoints)?

In any case, I've asked for the expedition.yaml from @VeckoTheGecko in #281 so that I can investigate this further. In the meantime, and regarding the message:

Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00.
Have you ensured that your schedule includes sufficient time for taking measurements, e.g. CTD casts (in addition to the time it takes to sail between waypoints)?
Hint: previous schedule verification checks (e.g. in the `virtualship plan` tool or after dealing with unexpected problems during the expedition) will not account for measurement times, only the time it takes to sail between waypoints.

This alone is not necessarily unexpected behaviour in the code's existing form. It is possible that a user fixes a scheduling issue as a result of a problem, which passes the schedule.verify() checks (no knowledge of instrument deployment timings, only sailing time) but then the simulate_schedule methods identify that the instrument deployment timings would mean it's late to the following waypoint, so it throws another message saying the waypoint still cannot be reached. I would expect in the case above even adding a few minutes to the waypoint will solve the problem.

If indeed this is what's happening (I will check this thoroughly though using Nick's expedition.yaml), I do appreciate that this is quite clunky from the user's perspective. It reflects the existing workflow in run though where we have a schedule.verify() check and further checks in simulate_schedule. I'll have a look if this can be tidied up.

@j-atkins

j-atkins commented Feb 13, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Update: Schedule.verify() now also takes the instrument deployment times into account when calculating whether the next waypoint can be reached in time. This should avoid situations where Schedule.verify() passes but simulate_measurements fails because instrument deployment timings have since been added to the calculation.

@j-atkins
j-atkins merged commit 8c900a3 into mainFeb 13, 2026
10 checks passed
@j-atkins
j-atkins deleted the problems branch February 13, 2026 14:40
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.

Adding problems during expedition

4 participants

@j-atkins@VeckoTheGecko@ammedd@erikvansebille
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Adding 'problems' module - #269

Merged
j-atkins merged 87 commits into
mainfrom
problems
Feb 13, 2026
Merged

Adding 'problems' module#269
j-atkins merged 87 commits into
mainfrom
problems

Conversation

@j-atkins

@j-atkinsj-atkins commented Jan 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds a 'problems' module to VirtualShip, whereby as expeditions are run users are faced with authentic problems which may happen on a real-life research vessel. These can be "general" problems (e.g. delayed food/fuel deliveries, unplanned safety drills), or "instrument" problems (e.g. CTD winch breaks down).

Features & implementation

All problems are associated with a delay duration. There are checks of whether there is already enough contingency time built into the schedule to still reach the next waypoint in time. If there is then the simulation is allowed to continue. However, if the next waypoint would be missed, users are prompted to account for the delay in their schedules and the expedition cannot proceed until the scheduling is resolved.

The problems module interacts with Checkpoint objects to test that the scheduling issues have been resolved. A unique record of the problems is also cached to keep track of and determine whether they've been resolved etc. It may be that dealing with a problem at one waypoint causes more scheduling issues way down the chain of waypoints. This is by design (as similar headaches would be experienced in real life!) and the schedule/checkpoint verification methods should capture this and prompt further changes.

The selection of problems and their execution in the main virtualship run workflow is handled by a new ProblemSimulator class. Specific problem scenarios are housed in scenarios.py as problem classes, which are themselves sub-classes of GeneralProblem and InstrumentProblem base classes (to establish a structure for building complexity in further PRs).

When propagated through virtualship run, a selection of all the problems for the expedition is first created but the individual problems are only raised at the right time. For example, a pre-departure problem will occur before any instrument simulations and a CTD related problem only when the CTD instrument is being simulated.

A new 'prob-level' argument is now added to the virtualship run CLI command. There are three options to choose from:

  • Level 0 = No problems encountered during the expedition (i.e. turn off problems module).
  • Level 1 = 1-2 problems encountered across the expedition [DEFAULT].
  • Level 2 = 1 or more problems encountered, depending on expedition length and complexity, where longer and more complex expeditions will encounter more problems.

N.B. I have set the default to prob_level = 1 for now, as this is best for upcoming in-class VirtualShip use.

Additional notes

I have set up the logic so that if waypoints are added/removed from the expedition, if a waypoint location changes or the instruments employed changes, this will prompt a new set of problems for the expedition. I see this as the expedition having materially changed and it being a 'new' expedition. This also prevents just re-running the same expedition until you get a 'nicer' set of problems (without manually removing the problems cache!).


  • Tests

Closes#120

@j-atkins
j-atkins marked this pull request as draft January 15, 2026 13:31
@j-atkinsj-atkins changed the title ProblemsAdding 'problems' moduleJan 15, 2026
@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I've now changed "prob-level" to "difficulty-level" (as suggested by @VeckoTheGecko) and set the default to "easy". For in-class applications where we want to use problems then we can point to a custom installation with default set to e.g. "medium" instead.

Let me know when you're happy with the PR (cc @ammedd and @erikvansebille) and we'll get this merged 🚢

@ammedd

Copy link
Copy Markdown
Collaborator

I run into the same issue as #281
Good to check/fix before merging this PR?

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I run into the same issue as #281 Good to check/fix before merging this PR?

To understand this better, are you encountering this problem because you have indeed made changes to the timings at waypoints before the waypoint affected by the problem? If so I would say this is the expected behaviour...as we only want users to make changes to waypoint timings after the problem waypoint?

@ammedd

Copy link
Copy Markdown
Collaborator

No, the message is "Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00."
I've only changed waypoint 5 and that is the last waypoint in the expedition.

@erikvansebille

Copy link
Copy Markdown
Member

I don't have time to carefully go through the code again myself, but I think that the issue that Emma raised above is very important to get fixed before merging. Please keep me updated how you are progressing

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

If I understand this correctly, @ammedd your point is about the first part of #281 (waypoint not reached in time) rather than the second part (warning about not re-scheduling previous waypoints)?

In any case, I've asked for the expedition.yaml from @VeckoTheGecko in #281 so that I can investigate this further. In the meantime, and regarding the message:

Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00.
Have you ensured that your schedule includes sufficient time for taking measurements, e.g. CTD casts (in addition to the time it takes to sail between waypoints)?
Hint: previous schedule verification checks (e.g. in the `virtualship plan` tool or after dealing with unexpected problems during the expedition) will not account for measurement times, only the time it takes to sail between waypoints.

This alone is not necessarily unexpected behaviour in the code's existing form. It is possible that a user fixes a scheduling issue as a result of a problem, which passes the schedule.verify() checks (no knowledge of instrument deployment timings, only sailing time) but then the simulate_schedule methods identify that the instrument deployment timings would mean it's late to the following waypoint, so it throws another message saying the waypoint still cannot be reached. I would expect in the case above even adding a few minutes to the waypoint will solve the problem.

If indeed this is what's happening (I will check this thoroughly though using Nick's expedition.yaml), I do appreciate that this is quite clunky from the user's perspective. It reflects the existing workflow in run though where we have a schedule.verify() check and further checks in simulate_schedule. I'll have a look if this can be tidied up.

@j-atkins

j-atkins commented Feb 13, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Update: Schedule.verify() now also takes the instrument deployment times into account when calculating whether the next waypoint can be reached in time. This should avoid situations where Schedule.verify() passes but simulate_measurements fails because instrument deployment timings have since been added to the calculation.

@j-atkins
j-atkins merged commit 8c900a3 into mainFeb 13, 2026
10 checks passed
@j-atkins
j-atkins deleted the problems branch February 13, 2026 14:40
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.

Adding problems during expedition

4 participants

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

Adding 'problems' module - #269

Merged
j-atkins merged 87 commits into
mainfrom
problems
Feb 13, 2026
Merged

Adding 'problems' module#269
j-atkins merged 87 commits into
mainfrom
problems

Conversation

@j-atkins

@j-atkinsj-atkins commented Jan 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds a 'problems' module to VirtualShip, whereby as expeditions are run users are faced with authentic problems which may happen on a real-life research vessel. These can be "general" problems (e.g. delayed food/fuel deliveries, unplanned safety drills), or "instrument" problems (e.g. CTD winch breaks down).

Features & implementation

All problems are associated with a delay duration. There are checks of whether there is already enough contingency time built into the schedule to still reach the next waypoint in time. If there is then the simulation is allowed to continue. However, if the next waypoint would be missed, users are prompted to account for the delay in their schedules and the expedition cannot proceed until the scheduling is resolved.

The problems module interacts with Checkpoint objects to test that the scheduling issues have been resolved. A unique record of the problems is also cached to keep track of and determine whether they've been resolved etc. It may be that dealing with a problem at one waypoint causes more scheduling issues way down the chain of waypoints. This is by design (as similar headaches would be experienced in real life!) and the schedule/checkpoint verification methods should capture this and prompt further changes.

The selection of problems and their execution in the main virtualship run workflow is handled by a new ProblemSimulator class. Specific problem scenarios are housed in scenarios.py as problem classes, which are themselves sub-classes of GeneralProblem and InstrumentProblem base classes (to establish a structure for building complexity in further PRs).

When propagated through virtualship run, a selection of all the problems for the expedition is first created but the individual problems are only raised at the right time. For example, a pre-departure problem will occur before any instrument simulations and a CTD related problem only when the CTD instrument is being simulated.

A new 'prob-level' argument is now added to the virtualship run CLI command. There are three options to choose from:

  • Level 0 = No problems encountered during the expedition (i.e. turn off problems module).
  • Level 1 = 1-2 problems encountered across the expedition [DEFAULT].
  • Level 2 = 1 or more problems encountered, depending on expedition length and complexity, where longer and more complex expeditions will encounter more problems.

N.B. I have set the default to prob_level = 1 for now, as this is best for upcoming in-class VirtualShip use.

Additional notes

I have set up the logic so that if waypoints are added/removed from the expedition, if a waypoint location changes or the instruments employed changes, this will prompt a new set of problems for the expedition. I see this as the expedition having materially changed and it being a 'new' expedition. This also prevents just re-running the same expedition until you get a 'nicer' set of problems (without manually removing the problems cache!).


  • Tests

Closes#120

@j-atkins
j-atkins marked this pull request as draft January 15, 2026 13:31
@j-atkinsj-atkins changed the title ProblemsAdding 'problems' moduleJan 15, 2026
@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I've now changed "prob-level" to "difficulty-level" (as suggested by @VeckoTheGecko) and set the default to "easy". For in-class applications where we want to use problems then we can point to a custom installation with default set to e.g. "medium" instead.

Let me know when you're happy with the PR (cc @ammedd and @erikvansebille) and we'll get this merged 🚢

@ammedd

Copy link
Copy Markdown
Collaborator

I run into the same issue as #281
Good to check/fix before merging this PR?

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I run into the same issue as #281 Good to check/fix before merging this PR?

To understand this better, are you encountering this problem because you have indeed made changes to the timings at waypoints before the waypoint affected by the problem? If so I would say this is the expected behaviour...as we only want users to make changes to waypoint timings after the problem waypoint?

@ammedd

Copy link
Copy Markdown
Collaborator

No, the message is "Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00."
I've only changed waypoint 5 and that is the last waypoint in the expedition.

@erikvansebille

Copy link
Copy Markdown
Member

I don't have time to carefully go through the code again myself, but I think that the issue that Emma raised above is very important to get fixed before merging. Please keep me updated how you are progressing

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

If I understand this correctly, @ammedd your point is about the first part of #281 (waypoint not reached in time) rather than the second part (warning about not re-scheduling previous waypoints)?

In any case, I've asked for the expedition.yaml from @VeckoTheGecko in #281 so that I can investigate this further. In the meantime, and regarding the message:

Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00.
Have you ensured that your schedule includes sufficient time for taking measurements, e.g. CTD casts (in addition to the time it takes to sail between waypoints)?
Hint: previous schedule verification checks (e.g. in the `virtualship plan` tool or after dealing with unexpected problems during the expedition) will not account for measurement times, only the time it takes to sail between waypoints.

This alone is not necessarily unexpected behaviour in the code's existing form. It is possible that a user fixes a scheduling issue as a result of a problem, which passes the schedule.verify() checks (no knowledge of instrument deployment timings, only sailing time) but then the simulate_schedule methods identify that the instrument deployment timings would mean it's late to the following waypoint, so it throws another message saying the waypoint still cannot be reached. I would expect in the case above even adding a few minutes to the waypoint will solve the problem.

If indeed this is what's happening (I will check this thoroughly though using Nick's expedition.yaml), I do appreciate that this is quite clunky from the user's perspective. It reflects the existing workflow in run though where we have a schedule.verify() check and further checks in simulate_schedule. I'll have a look if this can be tidied up.

@j-atkins

j-atkins commented Feb 13, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Update: Schedule.verify() now also takes the instrument deployment times into account when calculating whether the next waypoint can be reached in time. This should avoid situations where Schedule.verify() passes but simulate_measurements fails because instrument deployment timings have since been added to the calculation.

@j-atkins
j-atkins merged commit 8c900a3 into mainFeb 13, 2026
10 checks passed
@j-atkins
j-atkins deleted the problems branch February 13, 2026 14:40
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.

Adding problems during expedition

4 participants

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

Adding 'problems' module - #269

Merged
j-atkins merged 87 commits into
mainfrom
problems
Feb 13, 2026
Merged

Adding 'problems' module#269
j-atkins merged 87 commits into
mainfrom
problems

Conversation

@j-atkins

@j-atkinsj-atkins commented Jan 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds a 'problems' module to VirtualShip, whereby as expeditions are run users are faced with authentic problems which may happen on a real-life research vessel. These can be "general" problems (e.g. delayed food/fuel deliveries, unplanned safety drills), or "instrument" problems (e.g. CTD winch breaks down).

Features & implementation

All problems are associated with a delay duration. There are checks of whether there is already enough contingency time built into the schedule to still reach the next waypoint in time. If there is then the simulation is allowed to continue. However, if the next waypoint would be missed, users are prompted to account for the delay in their schedules and the expedition cannot proceed until the scheduling is resolved.

The problems module interacts with Checkpoint objects to test that the scheduling issues have been resolved. A unique record of the problems is also cached to keep track of and determine whether they've been resolved etc. It may be that dealing with a problem at one waypoint causes more scheduling issues way down the chain of waypoints. This is by design (as similar headaches would be experienced in real life!) and the schedule/checkpoint verification methods should capture this and prompt further changes.

The selection of problems and their execution in the main virtualship run workflow is handled by a new ProblemSimulator class. Specific problem scenarios are housed in scenarios.py as problem classes, which are themselves sub-classes of GeneralProblem and InstrumentProblem base classes (to establish a structure for building complexity in further PRs).

When propagated through virtualship run, a selection of all the problems for the expedition is first created but the individual problems are only raised at the right time. For example, a pre-departure problem will occur before any instrument simulations and a CTD related problem only when the CTD instrument is being simulated.

A new 'prob-level' argument is now added to the virtualship run CLI command. There are three options to choose from:

  • Level 0 = No problems encountered during the expedition (i.e. turn off problems module).
  • Level 1 = 1-2 problems encountered across the expedition [DEFAULT].
  • Level 2 = 1 or more problems encountered, depending on expedition length and complexity, where longer and more complex expeditions will encounter more problems.

N.B. I have set the default to prob_level = 1 for now, as this is best for upcoming in-class VirtualShip use.

Additional notes

I have set up the logic so that if waypoints are added/removed from the expedition, if a waypoint location changes or the instruments employed changes, this will prompt a new set of problems for the expedition. I see this as the expedition having materially changed and it being a 'new' expedition. This also prevents just re-running the same expedition until you get a 'nicer' set of problems (without manually removing the problems cache!).


  • Tests

Closes#120

@j-atkins
j-atkins marked this pull request as draft January 15, 2026 13:31
@j-atkinsj-atkins changed the title ProblemsAdding 'problems' moduleJan 15, 2026
@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I've now changed "prob-level" to "difficulty-level" (as suggested by @VeckoTheGecko) and set the default to "easy". For in-class applications where we want to use problems then we can point to a custom installation with default set to e.g. "medium" instead.

Let me know when you're happy with the PR (cc @ammedd and @erikvansebille) and we'll get this merged 🚢

@ammedd

Copy link
Copy Markdown
Collaborator

I run into the same issue as #281
Good to check/fix before merging this PR?

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I run into the same issue as #281 Good to check/fix before merging this PR?

To understand this better, are you encountering this problem because you have indeed made changes to the timings at waypoints before the waypoint affected by the problem? If so I would say this is the expected behaviour...as we only want users to make changes to waypoint timings after the problem waypoint?

@ammedd

Copy link
Copy Markdown
Collaborator

No, the message is "Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00."
I've only changed waypoint 5 and that is the last waypoint in the expedition.

@erikvansebille

Copy link
Copy Markdown
Member

I don't have time to carefully go through the code again myself, but I think that the issue that Emma raised above is very important to get fixed before merging. Please keep me updated how you are progressing

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

If I understand this correctly, @ammedd your point is about the first part of #281 (waypoint not reached in time) rather than the second part (warning about not re-scheduling previous waypoints)?

In any case, I've asked for the expedition.yaml from @VeckoTheGecko in #281 so that I can investigate this further. In the meantime, and regarding the message:

Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00.
Have you ensured that your schedule includes sufficient time for taking measurements, e.g. CTD casts (in addition to the time it takes to sail between waypoints)?
Hint: previous schedule verification checks (e.g. in the `virtualship plan` tool or after dealing with unexpected problems during the expedition) will not account for measurement times, only the time it takes to sail between waypoints.

This alone is not necessarily unexpected behaviour in the code's existing form. It is possible that a user fixes a scheduling issue as a result of a problem, which passes the schedule.verify() checks (no knowledge of instrument deployment timings, only sailing time) but then the simulate_schedule methods identify that the instrument deployment timings would mean it's late to the following waypoint, so it throws another message saying the waypoint still cannot be reached. I would expect in the case above even adding a few minutes to the waypoint will solve the problem.

If indeed this is what's happening (I will check this thoroughly though using Nick's expedition.yaml), I do appreciate that this is quite clunky from the user's perspective. It reflects the existing workflow in run though where we have a schedule.verify() check and further checks in simulate_schedule. I'll have a look if this can be tidied up.

@j-atkins

j-atkins commented Feb 13, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Update: Schedule.verify() now also takes the instrument deployment times into account when calculating whether the next waypoint can be reached in time. This should avoid situations where Schedule.verify() passes but simulate_measurements fails because instrument deployment timings have since been added to the calculation.

@j-atkins
j-atkins merged commit 8c900a3 into mainFeb 13, 2026
10 checks passed
@j-atkins
j-atkins deleted the problems branch February 13, 2026 14:40
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.

Adding problems during expedition

4 participants

@j-atkins@VeckoTheGecko@ammedd@erikvansebille
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Adding 'problems' module - #269

Merged
j-atkins merged 87 commits into
mainfrom
problems
Feb 13, 2026
Merged

Adding 'problems' module#269
j-atkins merged 87 commits into
mainfrom
problems

Conversation

@j-atkins

@j-atkinsj-atkins commented Jan 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds a 'problems' module to VirtualShip, whereby as expeditions are run users are faced with authentic problems which may happen on a real-life research vessel. These can be "general" problems (e.g. delayed food/fuel deliveries, unplanned safety drills), or "instrument" problems (e.g. CTD winch breaks down).

Features & implementation

All problems are associated with a delay duration. There are checks of whether there is already enough contingency time built into the schedule to still reach the next waypoint in time. If there is then the simulation is allowed to continue. However, if the next waypoint would be missed, users are prompted to account for the delay in their schedules and the expedition cannot proceed until the scheduling is resolved.

The problems module interacts with Checkpoint objects to test that the scheduling issues have been resolved. A unique record of the problems is also cached to keep track of and determine whether they've been resolved etc. It may be that dealing with a problem at one waypoint causes more scheduling issues way down the chain of waypoints. This is by design (as similar headaches would be experienced in real life!) and the schedule/checkpoint verification methods should capture this and prompt further changes.

The selection of problems and their execution in the main virtualship run workflow is handled by a new ProblemSimulator class. Specific problem scenarios are housed in scenarios.py as problem classes, which are themselves sub-classes of GeneralProblem and InstrumentProblem base classes (to establish a structure for building complexity in further PRs).

When propagated through virtualship run, a selection of all the problems for the expedition is first created but the individual problems are only raised at the right time. For example, a pre-departure problem will occur before any instrument simulations and a CTD related problem only when the CTD instrument is being simulated.

A new 'prob-level' argument is now added to the virtualship run CLI command. There are three options to choose from:

  • Level 0 = No problems encountered during the expedition (i.e. turn off problems module).
  • Level 1 = 1-2 problems encountered across the expedition [DEFAULT].
  • Level 2 = 1 or more problems encountered, depending on expedition length and complexity, where longer and more complex expeditions will encounter more problems.

N.B. I have set the default to prob_level = 1 for now, as this is best for upcoming in-class VirtualShip use.

Additional notes

I have set up the logic so that if waypoints are added/removed from the expedition, if a waypoint location changes or the instruments employed changes, this will prompt a new set of problems for the expedition. I see this as the expedition having materially changed and it being a 'new' expedition. This also prevents just re-running the same expedition until you get a 'nicer' set of problems (without manually removing the problems cache!).


  • Tests

Closes#120

@j-atkins
j-atkins marked this pull request as draft January 15, 2026 13:31
@j-atkinsj-atkins changed the title ProblemsAdding 'problems' moduleJan 15, 2026
@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I've now changed "prob-level" to "difficulty-level" (as suggested by @VeckoTheGecko) and set the default to "easy". For in-class applications where we want to use problems then we can point to a custom installation with default set to e.g. "medium" instead.

Let me know when you're happy with the PR (cc @ammedd and @erikvansebille) and we'll get this merged 🚢

@ammedd

Copy link
Copy Markdown
Collaborator

I run into the same issue as #281
Good to check/fix before merging this PR?

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I run into the same issue as #281 Good to check/fix before merging this PR?

To understand this better, are you encountering this problem because you have indeed made changes to the timings at waypoints before the waypoint affected by the problem? If so I would say this is the expected behaviour...as we only want users to make changes to waypoint timings after the problem waypoint?

@ammedd

Copy link
Copy Markdown
Collaborator

No, the message is "Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00."
I've only changed waypoint 5 and that is the last waypoint in the expedition.

@erikvansebille

Copy link
Copy Markdown
Member

I don't have time to carefully go through the code again myself, but I think that the issue that Emma raised above is very important to get fixed before merging. Please keep me updated how you are progressing

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

If I understand this correctly, @ammedd your point is about the first part of #281 (waypoint not reached in time) rather than the second part (warning about not re-scheduling previous waypoints)?

In any case, I've asked for the expedition.yaml from @VeckoTheGecko in #281 so that I can investigate this further. In the meantime, and regarding the message:

Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00.
Have you ensured that your schedule includes sufficient time for taking measurements, e.g. CTD casts (in addition to the time it takes to sail between waypoints)?
Hint: previous schedule verification checks (e.g. in the `virtualship plan` tool or after dealing with unexpected problems during the expedition) will not account for measurement times, only the time it takes to sail between waypoints.

This alone is not necessarily unexpected behaviour in the code's existing form. It is possible that a user fixes a scheduling issue as a result of a problem, which passes the schedule.verify() checks (no knowledge of instrument deployment timings, only sailing time) but then the simulate_schedule methods identify that the instrument deployment timings would mean it's late to the following waypoint, so it throws another message saying the waypoint still cannot be reached. I would expect in the case above even adding a few minutes to the waypoint will solve the problem.

If indeed this is what's happening (I will check this thoroughly though using Nick's expedition.yaml), I do appreciate that this is quite clunky from the user's perspective. It reflects the existing workflow in run though where we have a schedule.verify() check and further checks in simulate_schedule. I'll have a look if this can be tidied up.

@j-atkins

j-atkins commented Feb 13, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Update: Schedule.verify() now also takes the instrument deployment times into account when calculating whether the next waypoint can be reached in time. This should avoid situations where Schedule.verify() passes but simulate_measurements fails because instrument deployment timings have since been added to the calculation.

@j-atkins
j-atkins merged commit 8c900a3 into mainFeb 13, 2026
10 checks passed
@j-atkins
j-atkins deleted the problems branch February 13, 2026 14:40
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.

Adding problems during expedition

4 participants

@j-atkins@VeckoTheGecko@ammedd@erikvansebille
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Adding 'problems' module - #269

Merged
j-atkins merged 87 commits into
mainfrom
problems
Feb 13, 2026
Merged

Adding 'problems' module#269
j-atkins merged 87 commits into
mainfrom
problems

Conversation

@j-atkins

@j-atkinsj-atkins commented Jan 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds a 'problems' module to VirtualShip, whereby as expeditions are run users are faced with authentic problems which may happen on a real-life research vessel. These can be "general" problems (e.g. delayed food/fuel deliveries, unplanned safety drills), or "instrument" problems (e.g. CTD winch breaks down).

Features & implementation

All problems are associated with a delay duration. There are checks of whether there is already enough contingency time built into the schedule to still reach the next waypoint in time. If there is then the simulation is allowed to continue. However, if the next waypoint would be missed, users are prompted to account for the delay in their schedules and the expedition cannot proceed until the scheduling is resolved.

The problems module interacts with Checkpoint objects to test that the scheduling issues have been resolved. A unique record of the problems is also cached to keep track of and determine whether they've been resolved etc. It may be that dealing with a problem at one waypoint causes more scheduling issues way down the chain of waypoints. This is by design (as similar headaches would be experienced in real life!) and the schedule/checkpoint verification methods should capture this and prompt further changes.

The selection of problems and their execution in the main virtualship run workflow is handled by a new ProblemSimulator class. Specific problem scenarios are housed in scenarios.py as problem classes, which are themselves sub-classes of GeneralProblem and InstrumentProblem base classes (to establish a structure for building complexity in further PRs).

When propagated through virtualship run, a selection of all the problems for the expedition is first created but the individual problems are only raised at the right time. For example, a pre-departure problem will occur before any instrument simulations and a CTD related problem only when the CTD instrument is being simulated.

A new 'prob-level' argument is now added to the virtualship run CLI command. There are three options to choose from:

  • Level 0 = No problems encountered during the expedition (i.e. turn off problems module).
  • Level 1 = 1-2 problems encountered across the expedition [DEFAULT].
  • Level 2 = 1 or more problems encountered, depending on expedition length and complexity, where longer and more complex expeditions will encounter more problems.

N.B. I have set the default to prob_level = 1 for now, as this is best for upcoming in-class VirtualShip use.

Additional notes

I have set up the logic so that if waypoints are added/removed from the expedition, if a waypoint location changes or the instruments employed changes, this will prompt a new set of problems for the expedition. I see this as the expedition having materially changed and it being a 'new' expedition. This also prevents just re-running the same expedition until you get a 'nicer' set of problems (without manually removing the problems cache!).


  • Tests

Closes#120

@j-atkins
j-atkins marked this pull request as draft January 15, 2026 13:31
@j-atkinsj-atkins changed the title ProblemsAdding 'problems' moduleJan 15, 2026
@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I've now changed "prob-level" to "difficulty-level" (as suggested by @VeckoTheGecko) and set the default to "easy". For in-class applications where we want to use problems then we can point to a custom installation with default set to e.g. "medium" instead.

Let me know when you're happy with the PR (cc @ammedd and @erikvansebille) and we'll get this merged 🚢

@ammedd

Copy link
Copy Markdown
Collaborator

I run into the same issue as #281
Good to check/fix before merging this PR?

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I run into the same issue as #281 Good to check/fix before merging this PR?

To understand this better, are you encountering this problem because you have indeed made changes to the timings at waypoints before the waypoint affected by the problem? If so I would say this is the expected behaviour...as we only want users to make changes to waypoint timings after the problem waypoint?

@ammedd

Copy link
Copy Markdown
Collaborator

No, the message is "Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00."
I've only changed waypoint 5 and that is the last waypoint in the expedition.

@erikvansebille

Copy link
Copy Markdown
Member

I don't have time to carefully go through the code again myself, but I think that the issue that Emma raised above is very important to get fixed before merging. Please keep me updated how you are progressing

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

If I understand this correctly, @ammedd your point is about the first part of #281 (waypoint not reached in time) rather than the second part (warning about not re-scheduling previous waypoints)?

In any case, I've asked for the expedition.yaml from @VeckoTheGecko in #281 so that I can investigate this further. In the meantime, and regarding the message:

Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00.
Have you ensured that your schedule includes sufficient time for taking measurements, e.g. CTD casts (in addition to the time it takes to sail between waypoints)?
Hint: previous schedule verification checks (e.g. in the `virtualship plan` tool or after dealing with unexpected problems during the expedition) will not account for measurement times, only the time it takes to sail between waypoints.

This alone is not necessarily unexpected behaviour in the code's existing form. It is possible that a user fixes a scheduling issue as a result of a problem, which passes the schedule.verify() checks (no knowledge of instrument deployment timings, only sailing time) but then the simulate_schedule methods identify that the instrument deployment timings would mean it's late to the following waypoint, so it throws another message saying the waypoint still cannot be reached. I would expect in the case above even adding a few minutes to the waypoint will solve the problem.

If indeed this is what's happening (I will check this thoroughly though using Nick's expedition.yaml), I do appreciate that this is quite clunky from the user's perspective. It reflects the existing workflow in run though where we have a schedule.verify() check and further checks in simulate_schedule. I'll have a look if this can be tidied up.

@j-atkins

j-atkins commented Feb 13, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Update: Schedule.verify() now also takes the instrument deployment times into account when calculating whether the next waypoint can be reached in time. This should avoid situations where Schedule.verify() passes but simulate_measurements fails because instrument deployment timings have since been added to the calculation.

@j-atkins
j-atkins merged commit 8c900a3 into mainFeb 13, 2026
10 checks passed
@j-atkins
j-atkins deleted the problems branch February 13, 2026 14:40
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.

Adding problems during expedition

4 participants

@j-atkins@VeckoTheGecko@ammedd@erikvansebille
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Adding 'problems' module - #269

Merged
j-atkins merged 87 commits into
mainfrom
problems
Feb 13, 2026
Merged

Adding 'problems' module#269
j-atkins merged 87 commits into
mainfrom
problems

Conversation

@j-atkins

@j-atkinsj-atkins commented Jan 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds a 'problems' module to VirtualShip, whereby as expeditions are run users are faced with authentic problems which may happen on a real-life research vessel. These can be "general" problems (e.g. delayed food/fuel deliveries, unplanned safety drills), or "instrument" problems (e.g. CTD winch breaks down).

Features & implementation

All problems are associated with a delay duration. There are checks of whether there is already enough contingency time built into the schedule to still reach the next waypoint in time. If there is then the simulation is allowed to continue. However, if the next waypoint would be missed, users are prompted to account for the delay in their schedules and the expedition cannot proceed until the scheduling is resolved.

The problems module interacts with Checkpoint objects to test that the scheduling issues have been resolved. A unique record of the problems is also cached to keep track of and determine whether they've been resolved etc. It may be that dealing with a problem at one waypoint causes more scheduling issues way down the chain of waypoints. This is by design (as similar headaches would be experienced in real life!) and the schedule/checkpoint verification methods should capture this and prompt further changes.

The selection of problems and their execution in the main virtualship run workflow is handled by a new ProblemSimulator class. Specific problem scenarios are housed in scenarios.py as problem classes, which are themselves sub-classes of GeneralProblem and InstrumentProblem base classes (to establish a structure for building complexity in further PRs).

When propagated through virtualship run, a selection of all the problems for the expedition is first created but the individual problems are only raised at the right time. For example, a pre-departure problem will occur before any instrument simulations and a CTD related problem only when the CTD instrument is being simulated.

A new 'prob-level' argument is now added to the virtualship run CLI command. There are three options to choose from:

  • Level 0 = No problems encountered during the expedition (i.e. turn off problems module).
  • Level 1 = 1-2 problems encountered across the expedition [DEFAULT].
  • Level 2 = 1 or more problems encountered, depending on expedition length and complexity, where longer and more complex expeditions will encounter more problems.

N.B. I have set the default to prob_level = 1 for now, as this is best for upcoming in-class VirtualShip use.

Additional notes

I have set up the logic so that if waypoints are added/removed from the expedition, if a waypoint location changes or the instruments employed changes, this will prompt a new set of problems for the expedition. I see this as the expedition having materially changed and it being a 'new' expedition. This also prevents just re-running the same expedition until you get a 'nicer' set of problems (without manually removing the problems cache!).


  • Tests

Closes#120

@j-atkins
j-atkins marked this pull request as draft January 15, 2026 13:31
@j-atkinsj-atkins changed the title ProblemsAdding 'problems' moduleJan 15, 2026
@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I've now changed "prob-level" to "difficulty-level" (as suggested by @VeckoTheGecko) and set the default to "easy". For in-class applications where we want to use problems then we can point to a custom installation with default set to e.g. "medium" instead.

Let me know when you're happy with the PR (cc @ammedd and @erikvansebille) and we'll get this merged 🚢

@ammedd

Copy link
Copy Markdown
Collaborator

I run into the same issue as #281
Good to check/fix before merging this PR?

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

I run into the same issue as #281 Good to check/fix before merging this PR?

To understand this better, are you encountering this problem because you have indeed made changes to the timings at waypoints before the waypoint affected by the problem? If so I would say this is the expected behaviour...as we only want users to make changes to waypoint timings after the problem waypoint?

@ammedd

Copy link
Copy Markdown
Collaborator

No, the message is "Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00."
I've only changed waypoint 5 and that is the last waypoint in the expedition.

@erikvansebille

Copy link
Copy Markdown
Member

I don't have time to carefully go through the code again myself, but I think that the issue that Emma raised above is very important to get fixed before merging. Please keep me updated how you are progressing

@j-atkins

Copy link
Copy Markdown
CollaboratorAuthor

If I understand this correctly, @ammedd your point is about the first part of #281 (waypoint not reached in time) rather than the second part (warning about not re-scheduling previous waypoints)?

In any case, I've asked for the expedition.yaml from @VeckoTheGecko in #281 so that I can investigate this further. In the meantime, and regarding the message:

Waypoint 5 could not be reached in time. Current time: 1998-01-01 03:00:14.987829. Waypoint time: 1998-01-01 03:00:00.
Have you ensured that your schedule includes sufficient time for taking measurements, e.g. CTD casts (in addition to the time it takes to sail between waypoints)?
Hint: previous schedule verification checks (e.g. in the `virtualship plan` tool or after dealing with unexpected problems during the expedition) will not account for measurement times, only the time it takes to sail between waypoints.

This alone is not necessarily unexpected behaviour in the code's existing form. It is possible that a user fixes a scheduling issue as a result of a problem, which passes the schedule.verify() checks (no knowledge of instrument deployment timings, only sailing time) but then the simulate_schedule methods identify that the instrument deployment timings would mean it's late to the following waypoint, so it throws another message saying the waypoint still cannot be reached. I would expect in the case above even adding a few minutes to the waypoint will solve the problem.

If indeed this is what's happening (I will check this thoroughly though using Nick's expedition.yaml), I do appreciate that this is quite clunky from the user's perspective. It reflects the existing workflow in run though where we have a schedule.verify() check and further checks in simulate_schedule. I'll have a look if this can be tidied up.

@j-atkins

j-atkins commented Feb 13, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Update: Schedule.verify() now also takes the instrument deployment times into account when calculating whether the next waypoint can be reached in time. This should avoid situations where Schedule.verify() passes but simulate_measurements fails because instrument deployment timings have since been added to the calculation.

@j-atkins
j-atkins merged commit 8c900a3 into mainFeb 13, 2026
10 checks passed
@j-atkins
j-atkins deleted the problems branch February 13, 2026 14:40
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.

Adding problems during expedition

4 participants

@j-atkins@VeckoTheGecko@ammedd@erikvansebille