Skip to content

Commit

Permalink
Merge pull request #17 from AllenNeuralDynamics/feat-add-continuous-f…
Browse files Browse the repository at this point in the history
…eedback

Add ability to provide continuous feedback on HarvestAction
  • Loading branch information
bruno-f-cruz authored Aug 13, 2024
2 parents 98104b0 + 4fd23c1 commit 2d82059
Show file tree
Hide file tree
Showing 12 changed files with 1,493 additions and 907 deletions.
56 changes: 55 additions & 1 deletion src/DataSchemas/aind_behavior_force_foraging/task_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,50 @@ class TrialType(str, Enum):
ROI = "RegionOfInterest"


class ContinuousFeedbackMode(str, Enum):
"""Defines the feedback mode"""

NONE = "None"
AUDIO = "Audio"
VISUAL = "Visual"
MANIPULATOR = "Manipulator"


ValuePair = Annotated[List[float], Field(min_length=2, max_length=2, description="A tuple of two values")]


class _ContinuousFeedbackBase(BaseModel):
continuous_feedback_mode: ContinuousFeedbackMode = Field(
default=ContinuousFeedbackMode.NONE, description="Continuous feedback mode"
)
converter_lut_input: List[Annotated[float, Field(ge=0, le=1)]] = Field(
default=[0, 1], min_length=2, description="Input domain. All values should be between 0 and 1"
)
converter_lut_output: List[float] = Field(
default=[0, 1],
min_length=2,
description="Output domain used to linearly interpolate the input values to the output values",
)

@model_validator(mode="after")
def _validate_lut(self) -> Self:
if len(self.converter_lut_input) != len(self.converter_lut_output):
raise ValueError("Input and output LUT must have the same length")
return self


class ManipulatorFeedback(_ContinuousFeedbackBase):
continuous_feedback_mode: Literal[ContinuousFeedbackMode.MANIPULATOR] = ContinuousFeedbackMode.MANIPULATOR


class AudioFeedback(_ContinuousFeedbackBase):
continuous_feedback_mode: Literal[ContinuousFeedbackMode.AUDIO] = ContinuousFeedbackMode.AUDIO


class ContinuousFeedback(RootModel):
root: Annotated[Union[ManipulatorFeedback, AudioFeedback], Field(discriminator="continuous_feedback_mode")]


class HarvestAction(BaseModel):
"""Defines an abstract class for an harvest action"""

Expand Down Expand Up @@ -160,6 +204,7 @@ class HarvestAction(BaseModel):
action_updaters: List[ActionUpdater] = Field(
default=[], description="List of action updaters. All updaters are called at the start of a new trial."
)
continuous_feedback: Optional[ContinuousFeedback] = Field(default=None, description="Continuous feedback settings")

@model_validator(mode="after")
def _validate_thresholds(self) -> Self:
Expand Down Expand Up @@ -248,7 +293,7 @@ class BlockStatisticsMode(str, Enum):
"""Defines the mode of the environment"""

BLOCK = "Block"
BROWNIAN = "BownianRandomWalk"
BROWNIAN = "BrownianRandomWalk"
BLOCK_GENERATOR = "BlockGenerator"


Expand Down Expand Up @@ -367,10 +412,19 @@ def _validate_press_mode_versus_lut(self) -> Self:
return self


class SpoutOperationControl(BaseModel):
default_retracted_position: float = Field(default=0, description="Default retracted position (mm)")
default_extended_position: float = Field(default=0, description="Default extended position (mm)")
enabled: bool = Field(default=True, description="Whether the spout control is enabled")


class OperationControl(BaseModel):
force: ForceOperationControl = Field(
default=ForceOperationControl(), validate_default=True, description="Operation control for force sensor"
)
spout: SpoutOperationControl = Field(
default=SpoutOperationControl(), validate_default=True, description="Operation control for spout"
)


class AindForceForagingTaskParameters(TaskParameters):
Expand Down
164 changes: 159 additions & 5 deletions src/DataSchemas/aind_force_foraging_task_logic.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@
"left_index": 0,
"press_mode": "Double",
"right_index": 1
},
"spout": {
"default_extended_position": 0.0,
"default_retracted_position": 0.0,
"enabled": true
}
},
"description": "Operation control"
Expand All @@ -90,6 +95,46 @@
"title": "AindForceForagingTaskParameters",
"type": "object"
},
"AudioFeedback": {
"properties": {
"continuous_feedback_mode": {
"const": "Audio",
"default": "Audio",
"title": "Continuous Feedback Mode",
"type": "string"
},
"converter_lut_input": {
"default": [
0,
1
],
"description": "Input domain. All values should be between 0 and 1",
"items": {
"maximum": 1.0,
"minimum": 0.0,
"type": "number"
},
"minItems": 2,
"title": "Converter Lut Input",
"type": "array"
},
"converter_lut_output": {
"default": [
0,
1
],
"description": "Output domain used to linearly interpolate the input values to the output values",
"items": {
"type": "number"
},
"minItems": 2,
"title": "Converter Lut Output",
"type": "array"
}
},
"title": "AudioFeedback",
"type": "object"
},
"BetaDistribution": {
"properties": {
"family": {
Expand Down Expand Up @@ -339,7 +384,7 @@
"mapping": {
"Block": "#/definitions/Block",
"BlockGenerator": "#/definitions/BlockGenerator",
"BownianRandomWalk": "#/definitions/BrownianRandomWalk"
"BrownianRandomWalk": "#/definitions/BrownianRandomWalk"
},
"propertyName": "mode"
},
Expand All @@ -359,8 +404,8 @@
"BrownianRandomWalk": {
"properties": {
"mode": {
"const": "BownianRandomWalk",
"default": "BownianRandomWalk",
"const": "BrownianRandomWalk",
"default": "BrownianRandomWalk",
"title": "Mode",
"type": "string"
},
Expand Down Expand Up @@ -403,6 +448,24 @@
"title": "BrownianRandomWalk",
"type": "object"
},
"ContinuousFeedback": {
"discriminator": {
"mapping": {
"Audio": "#/definitions/AudioFeedback",
"Manipulator": "#/definitions/ManipulatorFeedback"
},
"propertyName": "continuous_feedback_mode"
},
"oneOf": [
{
"$ref": "#/definitions/ManipulatorFeedback"
},
{
"$ref": "#/definitions/AudioFeedback"
}
],
"title": "ContinuousFeedback"
},
"Distribution": {
"description": "Available distributions",
"discriminator": {
Expand Down Expand Up @@ -858,6 +921,18 @@
},
"title": "Action Updaters",
"type": "array"
},
"continuous_feedback": {
"default": null,
"description": "Continuous feedback settings",
"oneOf": [
{
"$ref": "#/definitions/ContinuousFeedback"
},
{
"type": "null"
}
]
}
},
"title": "HarvestAction",
Expand Down Expand Up @@ -980,6 +1055,46 @@
"title": "LogNormalDistributionParameters",
"type": "object"
},
"ManipulatorFeedback": {
"properties": {
"continuous_feedback_mode": {
"const": "Manipulator",
"default": "Manipulator",
"title": "Continuous Feedback Mode",
"type": "string"
},
"converter_lut_input": {
"default": [
0,
1
],
"description": "Input domain. All values should be between 0 and 1",
"items": {
"maximum": 1.0,
"minimum": 0.0,
"type": "number"
},
"minItems": 2,
"title": "Converter Lut Input",
"type": "array"
},
"converter_lut_output": {
"default": [
0,
1
],
"description": "Output domain used to linearly interpolate the input values to the output values",
"items": {
"type": "number"
},
"minItems": 2,
"title": "Converter Lut Output",
"type": "array"
}
},
"title": "ManipulatorFeedback",
"type": "object"
},
"NormalDistribution": {
"properties": {
"family": {
Expand Down Expand Up @@ -1149,6 +1264,19 @@
"force_lookup_table": null
},
"description": "Operation control for force sensor"
},
"spout": {
"allOf": [
{
"$ref": "#/definitions/SpoutOperationControl"
}
],
"default": {
"default_retracted_position": 0.0,
"default_extended_position": 0.0,
"enabled": true
},
"description": "Operation control for spout"
}
},
"title": "OperationControl",
Expand Down Expand Up @@ -1361,6 +1489,30 @@
"title": "ScalingParameters",
"type": "object"
},
"SpoutOperationControl": {
"properties": {
"default_retracted_position": {
"default": 0,
"description": "Default retracted position (mm)",
"title": "Default Retracted Position",
"type": "number"
},
"default_extended_position": {
"default": 0,
"description": "Default extended position (mm)",
"title": "Default Extended Position",
"type": "number"
},
"enabled": {
"default": true,
"description": "Whether the spout control is enabled",
"title": "Enabled",
"type": "boolean"
}
},
"title": "SpoutOperationControl",
"type": "object"
},
"Trial": {
"description": "Defines a trial",
"properties": {
Expand Down Expand Up @@ -1422,7 +1574,8 @@
"lower_force_threshold": 5000.0,
"is_operant": true,
"time_to_collect": null,
"action_updaters": []
"action_updaters": [],
"continuous_feedback": null
},
"description": "Specification of the left action",
"oneOf": [
Expand All @@ -1446,7 +1599,8 @@
"lower_force_threshold": 5000.0,
"is_operant": true,
"time_to_collect": null,
"action_updaters": []
"action_updaters": [],
"continuous_feedback": null
},
"description": "Specification of the right action",
"oneOf": [
Expand Down
1 change: 1 addition & 0 deletions src/Extensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<PackageReference Include="Bonsai.Spinnaker" Version="0.7.1" />
<PackageReference Include="Harp.Behavior" Version="0.1.0" />
<PackageReference Include="Harp.Olfactometer" Version="0.1.0-build231127" />
<PackageReference Include="Harp.StepperDriver" Version="0.3.0" />
<PackageReference Include="MathNet.Numerics" Version="4.15.0" />
<PackageReference Include="Bonsai.Design.Visualizers" Version="2.8.0" />
<PackageReference Include="AllenNeuralDynamics.Core" Version="0.2.2" />
Expand Down
Loading

0 comments on commit 2d82059

Please sign in to comment.