Skip to content
This repository has been archived by the owner on Feb 9, 2024. It is now read-only.

Commit

Permalink
Use the v2 api for v2 brains (#80)
Browse files Browse the repository at this point in the history
* Use the v2 api but always use first named concept. Moab only has one concept so this is ok. Prevents tight coupling from the Inkling concept name "MoveToCenter".

* Bump version to 3.1.1

Co-authored-by: Scott Stanfield <[email protected]>
  • Loading branch information
polzounov and scotstan authored Jan 6, 2022
1 parent 94dab05 commit a98a667
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 15 deletions.
2 changes: 1 addition & 1 deletion os/files/etc/environment
Original file line number Diff line number Diff line change
@@ -1 +1 @@
MOABIAN=3.1.0
MOABIAN=3.1.1
2 changes: 1 addition & 1 deletion os/services/menu.service
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ DefaultDependencies=false
After=dhcpd.service

[Service]
Environment="MOABIAN=3.1.0"
Environment="MOABIAN=3.1.1"
Environment="PYTHONUNBUFFERED=1"
WorkingDirectory=/home/pi/moab/sw
ExecStart=/usr/bin/python3 menu.py --debug --verbose --reset
Expand Down
72 changes: 60 additions & 12 deletions sw/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def brain_controller(
max_angle=22,
port=5555,
client_id=123,
alert_fn=lambda toggle: None,
alert_fn=None,
**kwargs,
):
"""
Expand All @@ -72,13 +72,18 @@ def brain_controller(
endpoint. This way we don't need to know information about what the trained
brain was called to navigate the json response.
"""
prediction_url = f"http://localhost:{port}/v1/prediction"

# Reset memory if a v2 brain
status = requests.delete(f"http://localhost:{port}/v2/clients/{client_id}")
version = 2 if status.status_code == 204 else 1

def next_action(state):
if version == 1:
prediction_url = f"http://localhost:{port}/v1/prediction"
elif version == 2:
prediction_url = f"http://localhost:{port}/v2/clients/{client_id}/predict"
else:
raise ValueError("Brain version `{self.version}` is not supported.")

def next_action_v1(state):
env_state, ball_detected, buttons = state
x, y, vel_x, vel_y, sum_x, sum_y = env_state

Expand All @@ -102,8 +107,6 @@ def next_action(state):
info = {"status": response.status_code, "resp": response.json()}

if response.ok:
if alert_fn is not None:
alert_fn(False)
pitch = info["resp"]["input_pitch"]
roll = info["resp"]["input_roll"]

Expand All @@ -113,19 +116,64 @@ def next_action(state):

# To match how the old brain works (only integer plate angles)
pitch, roll = int(pitch), int(roll)

action = Vector2(-roll, pitch)
else:
if alert_fn is not None:
alert_fn(True)

except requests.exceptions.ConnectionError as e:
print(f"No brain listening on port: {port}", file=sys.stderr)
raise BrainNotFound

except Exception as e:
print(f"Brain exception: {e}")
return action, info

def next_action_v2(state):
env_state, ball_detected, buttons = state
x, y, vel_x, vel_y, sum_x, sum_y = env_state

observables = {
"state": {
"ball_x": x,
"ball_y": y,
"ball_vel_x": vel_x,
"ball_vel_y": vel_y,
}
}

action = Vector2(0, 0) # Action is 0,0 if not detected or brain didn't work
info = {"status": 400, "resp": ""}
if ball_detected:

# Trap on GET failures so we can restart the brain without
# bringing down this run loop. Plate will default to level
# when it loses the connection.
try:
# Get action from brain
response = requests.post(prediction_url, json=observables)
info = {"status": response.status_code, "resp": response.json()}

if response.ok:
concepts = info["resp"]["concepts"]
concept_name = list(concepts.keys())[0] # Just use first concept
pitch = concepts[concept_name]["action"]["input_pitch"]
roll = concepts[concept_name]["action"]["input_roll"]

# Scale and clip
pitch = np.clip(pitch * max_angle, -max_angle, max_angle)
roll = np.clip(roll * max_angle, -max_angle, max_angle)

# To match how the old brain works (only integer plate angles)
pitch, roll = int(pitch), int(roll)
action = Vector2(-roll, pitch)

except requests.exceptions.ConnectionError as e:
print(f"No brain listening on port: {port}", file=sys.stderr)
raise BrainNotFound
except Exception as e:
print(f"Brain exception: {e}")
return action, info

return next_action
if version == 1:
return next_action_v1
elif version == 2:
return next_action_v2
else:
raise ValueError("Brain version `{self.version}` is not supported.")
2 changes: 1 addition & 1 deletion sw/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def _handle_debug(ctx, param, debug):


@click.command()
@click.version_option(version="3.1.0")
@click.version_option(version="3.1.1")
@click.option(
"-c",
"--cont",
Expand Down

0 comments on commit a98a667

Please sign in to comment.