Skip to content

Commit

Permalink
ACU: acu-config setting for forcing sequential moves
Browse files Browse the repository at this point in the history
E.g. if you generally don't want to move az and el axes
simultaneously.  If enabled, this applies whether Sun Avoidance is on,
or not.  But special handling is applied, for case of Sun Avoidance.
  • Loading branch information
mhasself committed Oct 21, 2024
1 parent 641fa3e commit 9e04bf3
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 11 deletions.
1 change: 1 addition & 0 deletions docs/agents/acu_agent.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ example configuration block is below::
'upper': 360.,
},
'acc': (8./1.88),
'axes_sequential': False,
},
}

Expand Down
27 changes: 16 additions & 11 deletions socs/agents/acu/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -2118,12 +2118,13 @@ def _reset_sun_params(self, enabled=None, radius=None):
_p['active_avoidance'] = config['enabled']
_p['policy'] = config['policy']

# And add in platform limits
# And add in platform limits and move policies
_p['policy'].update({
'min_az': self.motion_limits['azimuth']['lower'],
'max_az': self.motion_limits['azimuth']['upper'],
'min_el': self.motion_limits['elevation']['lower'],
'max_el': self.motion_limits['elevation']['upper'],
'axes_sequential': self.motion_limits.get('axes_sequential', False),
})

self.sun_params = _p
Expand Down Expand Up @@ -2598,10 +2599,23 @@ def _get_sunsafe_moves(self, target_az, target_el, zero_legs_ok=True):
the target position in it.
When Sun avoidance is not enabled, this function returns as
though the direct path to the target is a safe one.
though the direct path to the target is a safe one (though
axes_sequential=True may turn this into a move with two legs).
"""
# Get current position.
try:
az, el = [self.data['status']['summary'][f'{ax}_current_position']
for ax in ['Azimuth', 'Elevation']]
if az is None or el is None:
raise KeyError
except KeyError:
return None, 'Current position could not be determined.'

if not self._get_sun_policy('sunsafe_moves'):
if self.motion_limits.get('axes_sequential'):
# Move in az first, then el.
return [(target_az, el), (target_az, target_el)], None
return [(target_az, target_el)], None

if not self._get_sun_policy('map_valid'):
Expand All @@ -2611,15 +2625,6 @@ def _get_sunsafe_moves(self, target_az, target_el, zero_legs_ok=True):
if self.sun.check_trajectory([target_az], [target_el])['sun_time'] <= 0:
return None, 'Requested target position is not Sun-Safe.'

# Ok, so where are we now ...
try:
az, el = [self.data['status']['summary'][f'{ax}_current_position']
for ax in ['Azimuth', 'Elevation']]
if az is None or el is None:
raise KeyError
except KeyError:
return None, 'Current position could not be determined.'

moves = self.sun.analyze_paths(az, el, target_az, target_el)
move, decisions = self.sun.select_move(moves)
if move is None:
Expand Down
21 changes: 21 additions & 0 deletions socs/agents/acu/avoidance.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@
setting only affects point-to-point motions; "escape" paths will
always consider all available elevations.
``axes_sequential``
If True, a point-to-point motion will only be accepted if the legs
each move only in az or only in el. When this is False, legs that
move simultaneously in az and el are permitted (and probably
preferred) as long as they are safe.
A "Sun-safe" position is a pointing of the boresight that currently
has a ``sun_time`` that meets or exceeds the ``min_sun_time``
Expand Down Expand Up @@ -100,6 +106,7 @@
'el_dodging': False,
'min_sun_time': HOUR,
'response_time': HOUR * 4,
'axes_sequential': False,
}


Expand Down Expand Up @@ -557,6 +564,10 @@ def reject(d, reason):

els = m['req_start'][1], m['req_stop'][1]

if _p['axes_sequential'] and m['moves'].includes_mixed_moves():
reject(d, 'Path includes simultaneous az+el legs (forbidden in policy).')
continue

if (m['sun_time_start'] < _p['min_sun_time']):
# If the path is starting in danger zone, then only
# enforce that the move takes the platform to a better place.
Expand Down Expand Up @@ -688,3 +699,13 @@ def get_traj(self, res=0.5):
xx.append(np.linspace(x0, x1, n))
yy.append(np.linspace(y0, y1, n))
return np.hstack(tuple(xx)), np.hstack(tuple(yy))

def includes_mixed_moves(self):
"""Returns True if any of the legs include simultaneous
changes in az and el.
"""
for (x0, y0), (x1, y1) in self.get_legs():
if (x0 != x1) + (y0 != y1) > 1:
return True
return False
8 changes: 8 additions & 0 deletions tests/agents/test_acu_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ def test_avoidance():
assert path is not None
assert len(path['moves'].nodes) == 2

# .. even if policy forbids mixed-axis moves
sun.policy['axes_sequential'] = True
paths = sun.analyze_paths(270.01, 40.01, 270, 40)
path, analysis = sun.select_move(paths)
assert path is not None
assert len(path['moves'].nodes) == 3
del sun.policy['axes_sequential']

# Find safe paths to here (no moves)
paths = sun.analyze_paths(270, 40, 270, 40)
path, analysis = sun.select_move(paths)
Expand Down

0 comments on commit 9e04bf3

Please sign in to comment.