Skip to content

Add StateVectorActionGenerator and make OptunaSensorManager compatible#1251

Open
nperree-dstl wants to merge 10 commits intomainfrom
move_to_actions
Open

Add StateVectorActionGenerator and make OptunaSensorManager compatible#1251
nperree-dstl wants to merge 10 commits intomainfrom
move_to_actions

Conversation

@nperree-dstl
Copy link
Copy Markdown
Contributor

@nperree-dstl nperree-dstl commented Jan 30, 2026

IntroducesStateVectorActionGenerator as a base class for generating actions which change the state (e.g. platform location), and MovePositionActionGenerator for generating MovePositionActions.

Updates OptunaSensorManager so it is compatible with StateVectorActionGenerators.

Addresses #1190.

@nperree-dstl nperree-dstl requested a review from a team as a code owner January 30, 2026 16:14
@nperree-dstl nperree-dstl requested review from sdhiscocks and timothy-glover and removed request for a team January 30, 2026 16:14
@codecov
Copy link
Copy Markdown

codecov bot commented Jan 30, 2026

Codecov Report

❌ Patch coverage is 87.67123% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.60%. Comparing base (b30d402) to head (4407286).
⚠️ Report is 21 commits behind head on main.

Files with missing lines Patch % Lines
stonesoup/sensormanager/optuna.py 77.77% 2 Missing and 4 partials ⚠️
stonesoup/movable/action/move_position_action.py 90.62% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1251      +/-   ##
==========================================
+ Coverage   94.58%   94.60%   +0.01%     
==========================================
  Files         233      233              
  Lines       16743    16761      +18     
  Branches     2356     2363       +7     
==========================================
+ Hits        15837    15856      +19     
+ Misses        607      604       -3     
- Partials      299      301       +2     
Flag Coverage Δ
integration 66.68% <38.35%> (-0.11%) ⬇️
unittests 91.97% <87.67%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +76 to +80
max_index_change = float(np.sqrt(generator.max_state_change**2 -
sum(value**2)))
max_index_change, resolution = self.sample_parameters(
max_index_change,
generator)
Copy link
Copy Markdown
Member

@sdhiscocks sdhiscocks Feb 4, 2026

Choose a reason for hiding this comment

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

I wonder if max change could be something that is part of the action generator, as different StateVectorActionGenerators may have different ways to define constraints. Possibly min and max?

Copy link
Copy Markdown
Contributor

@hpritchett-dstl hpritchett-dstl Feb 10, 2026

Choose a reason for hiding this comment

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

I think having a min / max StateVector with the same length as action mapping that defines the min / max of each dimension would be useful. This specific constraint seems to be an inequality rather than a min / max, i.e. bounding a 2d position by a circle, rather than a square (which min / max would do).

To do this generally, we would need to add lower (or upper) inequalities to generators. This could be a list of callables that act on this generator's action space?

e.g for CircleSamplePositionActionGenerator and MaxSpeedPositionActionGenerator we would have a less than or equal inequality looking something like:

lambda x: np.sum( [ (x[index] - self.current_value[index]) ** 2 for index in self.action_mapping ] ) - self.maximum_travel**2

These could then be integrated into constraints for Optuna objectives / other optimisation packages more easily without having to have custom logic per generator in each sensor manager.


@staticmethod
def sample_parameters(max_value, generator):
resolution = getattr(generator, "resolution", None)
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.

The resolution for the NStepDirectionalGridActionGenerator is resolution * step_size. So in most cases a platform with that generator will be given an action value it doesn't contain and it will fail silently.

Sign up for free to 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.

4 participants