42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 | def main(
config: str | None = None,
**context: dict[str, Any],
):
"""Run the `matbii` simulation."""
# args from command line can be used in config
# context = dict(
# experiment=dict(id=experiment) if experiment else dict(),
# participant=dict(id=participant) if participant else dict(),
# **kwargs,
# )
# load configuration from the config file
config = Configuration.from_file(config, context=context)
# initialise logging
config = Configuration.initialise_logging(config)
# Create the avatar:
# - required sensors are added by default
# - task related actuators are added when their corresponding task is enabled
avatar = Avatar(
[],
[AvatarActuator(), ExitActuator()], # will log user events by default
window_config=config.window,
)
# if eyetracking is enabled, add a sensor to the avatar
eyetracking_sensor = config.eyetracking.new_eyetracking_sensor()
if eyetracking_sensor:
avatar.add_component(eyetracking_sensor)
agents = [] # will be given to the environment
# create the guidance agent
# - sensors will determine the acceptability of each task - if the task is enabled.
# - change actuators for different guidance to be shown (must inherit from GuidanceActuator)
guidance_agent = DefaultGuidanceAgent(
[
# add more if there are more tasks!
SystemMonitoringTaskAcceptabilitySensor(),
ResourceManagementTaskAcceptabilitySensor(),
TrackingTaskAcceptabilitySensor(),
],
[
# used to log this agents beliefs for post experiment analysis
# LogActuator(path=Path(config.logging.path) / "guidance_logs.log"),
# shows arrow pointing at a task as guidance
config.guidance.arrow.to_actuator(),
# shows a box around a task as guidance
config.guidance.box.to_actuator(),
],
break_ties=config.guidance.break_ties,
grace_period=config.guidance.grace_period,
grace_mode=config.guidance.grace_mode,
attention_mode=config.guidance.attention_mode,
counter_factual=config.guidance.counter_factual,
)
agents.append(guidance_agent)
env = MultiTaskEnvironment(
wait=0.01, # this can be zero as long as it doesnt matter that the env scheduler hogs asyncio: TODO test this with IO devices (eyetracker particularly)
avatar=avatar,
agents=agents,
svg_size=(config.ui.width, config.ui.height),
logging_path=config.logging.path,
terminate_after=config.experiment.duration,
)
# NOTE: if you have more tasks to add, add them here!
env.add_task(
name=TASK_ID_TRACKING,
path=[config.experiment.path, TASK_PATHS[TASK_ID_TRACKING]],
agent_actuators=[TrackingActuator],
avatar_actuators=[
partial(
AvatarTrackingActuator,
# Negative values will invert the direction of movement
target_speed=-50.0, # TODO a config option for this?
)
],
enable=TASK_ID_TRACKING in config.experiment.enable_tasks,
)
env.add_task(
name=TASK_ID_SYSTEM_MONITORING,
path=[config.experiment.path, TASK_PATHS[TASK_ID_SYSTEM_MONITORING]],
agent_actuators=[SystemMonitoringActuator],
avatar_actuators=[AvatarSystemMonitoringActuator],
enable=TASK_ID_SYSTEM_MONITORING in config.experiment.enable_tasks,
)
env.add_task(
name=TASK_ID_RESOURCE_MANAGEMENT,
path=[config.experiment.path, TASK_PATHS[TASK_ID_RESOURCE_MANAGEMENT]],
agent_actuators=[ResourceManagementActuator],
avatar_actuators=[AvatarResourceManagementActuator],
enable=TASK_ID_RESOURCE_MANAGEMENT in config.experiment.enable_tasks,
)
env.run()
|