Skip to content

Commit f750c4a

Browse files
committed
Update tasks:
- task is given a list of actions that we can do duration and cost analysis on to clump certain actions together. - irma main file updated to generate a task given actions.
1 parent 00e5f12 commit f750c4a

File tree

2 files changed

+38
-31
lines changed

2 files changed

+38
-31
lines changed

famodel/irma/irma.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,7 @@ def addActionDependencies(self, action, dependencies):
284284
if dep in self.actions.values():
285285
action.addDependency(dep)
286286
else:
287-
raise Exception(f"New action '{action.name}' has a dependency '{dep.name}' this is not in the action list.")
288-
287+
raise Exception(f"New action '{action.name}' has a dependency '{dep.name}' this is not in the action list.")
289288

290289

291290
def visualizeActions(self):
@@ -325,10 +324,8 @@ def visualizeActions(self):
325324
nx.draw_networkx_nodes(G, pos, nodelist=[node], node_color='green', node_size=500, label='Action starters' if i==0 else None)
326325
i += 1
327326
plt.legend()
328-
return G
329-
330-
331-
327+
return G
328+
332329
def findCompatibleVessels(self):
333330
'''Go through actions and identify which vessels have the required
334331
capabilities (could be based on capability presence, or quantitative.
@@ -421,15 +418,18 @@ def findCompatibleVessels(self):
421418
for a in hookups:
422419
sc.addActionDependencies(a, [a5]) # make each hookup action dependent on the FOWT being towed out
423420

421+
424422

425-
423+
# ----- Generate tasks (groups of Actions according to specific strategies) -----
424+
425+
t1 = Task(sc.actions, 'install_mooring_system')
426+
426427
# ----- Do some graph analysis -----
427428

428429
G = sc.visualizeActions()
429430

430431

431-
432-
# ----- Generate tasks (groups of Actions according to specific strategies) -----
432+
433433

434434

435435

famodel/irma/task.py

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from moorpy import helpers
99
import yaml
1010
from copy import deepcopy
11-
11+
import networkx as nx
1212

1313
# Import select required helper functions
1414
from famodel.helpers import (check_headings, head_adjust, getCableDD, getDynamicCables,
@@ -17,7 +17,6 @@
1717
configureAdjuster, route_around_anchors)
1818

1919

20-
2120
class Task():
2221
'''
2322
A Task is a general representation of a set of marine operations
@@ -33,43 +32,36 @@ class Task():
3332
3433
'''
3534

36-
def __init__(self, taskType, name, **kwargs):
35+
def __init__(self, actionList, name, **kwargs):
3736
'''Create an action object...
38-
It must be given a name.
39-
The remaining parameters should correspond to items in the actionType dict...
37+
It must be given a name and a list of actions.
38+
The action list should be by default coherent with actionTypes dictionary.
4039
4140
Parameters
4241
----------
43-
taskType : dict
44-
Dictionary defining the action type (typically taken from a yaml).
42+
actionList : list
43+
A list of all actions that are part of this task.
4544
name : string
4645
A name for the action. It may be appended with numbers if there
4746
are duplicate names.
4847
kwargs
49-
Additional arguments may depend on the action type and typically
50-
include a list of FAModel objects that are acted upon, or
51-
a list of dependencies (other action names/objects).
48+
Additional arguments may depend on the task type.
5249
5350
'''
5451

55-
# list of things that will be controlled during this action
56-
self.vesselList = [] # all vessels required for the action
57-
self.objectList = [] # all objects that are acted on
58-
self.actionList = [] # all actions that are carried out in this task
59-
self.dependencies = {} # list of other tasks this one depends on
60-
61-
self.type = getFromDict(taskType, 'type', dtype=str)
52+
self.actionList = actionList # all actions that are carried out in this task
6253
self.name = name
6354
self.status = 0 # 0, waiting; 1=running; 2=finished
6455

6556
self.duration = 0 # duration must be calculated based on lengths of actions
66-
57+
self.cost = 0 # cost must be calculated based on the cost of individual actions.
58+
6759
# what else do we need to initialize the task?
6860

69-
# internal graph of the actions within this task?
61+
# internal graph of the actions within this task.
62+
self.G = self.getTaskGraph()
7063

71-
72-
def organizeActions(self, actions):
64+
def organizeActions(self):
7365
'''Organizes the actions to be done by this task into the proper order
7466
based on the strategy of this type of task...
7567
'''
@@ -85,4 +77,19 @@ def calcDuration(self):
8577
individual actions and their order of operation.'''
8678

8779
# Does Rudy have graph-based code that can do this?
88-
80+
81+
def getTaskGraph(self):
82+
'''Generate a graph of the action dependencies.
83+
'''
84+
85+
# Create the graph
86+
G = nx.DiGraph()
87+
for item, data in self.actionList.items():
88+
for dep in data.dependencies:
89+
G.add_edge(dep, item, duration=data.duration) # Store duration as edge attribute
90+
91+
# Compute longest path & total duration
92+
longest_path = nx.dag_longest_path(G, weight='duration')
93+
longest_path_edges = list(zip(longest_path, longest_path[1:])) # Convert path into edge pairs
94+
total_duration = sum(self.actionList[node].duration for node in longest_path)
95+
return G

0 commit comments

Comments
 (0)