From 1fbc400e9208f47bb8e9bac25ec4a21fdf3cc0e8 Mon Sep 17 00:00:00 2001 From: Chadlia Jerad Date: Sat, 6 Jan 2024 00:05:06 +0100 Subject: [PATCH 1/4] Add TagOfWar demo --- experiments/C/src/TugOfWar/Interface/app.py | 239 ++++++++++++++++++ .../C/src/TugOfWar/Interface/app_helper.py | 63 +++++ .../C/src/TugOfWar/Interface/assets/lf.png | Bin 0 -> 3429 bytes .../C/src/TugOfWar/Interface/request.sh | 7 + .../C/src/TugOfWar/Interface/requirements.txt | 7 + experiments/C/src/TugOfWar/Interface/start.sh | 18 ++ experiments/C/src/TugOfWar/Player.lf | 17 ++ experiments/C/src/TugOfWar/README.md | 17 ++ experiments/C/src/TugOfWar/TugOfWar.lf | 21 ++ experiments/C/src/TugOfWar/TugOfWarGame.lf | 111 ++++++++ 10 files changed, 500 insertions(+) create mode 100755 experiments/C/src/TugOfWar/Interface/app.py create mode 100755 experiments/C/src/TugOfWar/Interface/app_helper.py create mode 100755 experiments/C/src/TugOfWar/Interface/assets/lf.png create mode 100755 experiments/C/src/TugOfWar/Interface/request.sh create mode 100755 experiments/C/src/TugOfWar/Interface/requirements.txt create mode 100755 experiments/C/src/TugOfWar/Interface/start.sh create mode 100755 experiments/C/src/TugOfWar/Player.lf create mode 100644 experiments/C/src/TugOfWar/README.md create mode 100755 experiments/C/src/TugOfWar/TugOfWar.lf create mode 100755 experiments/C/src/TugOfWar/TugOfWarGame.lf diff --git a/experiments/C/src/TugOfWar/Interface/app.py b/experiments/C/src/TugOfWar/Interface/app.py new file mode 100755 index 00000000..88adec5e --- /dev/null +++ b/experiments/C/src/TugOfWar/Interface/app.py @@ -0,0 +1,239 @@ +import pandas as pd +import dash +from dash import dcc, html, Input, Output +from dash.exceptions import PreventUpdate +import plotly.express as px +from flask import Flask, request +import json +import app_helper as ap +import dash_bootstrap_components as dbc +import dash_daq as daq + + +player_force = dict({ + 'players': ['Team_A_Player_0', 'Team_A_Player_1', 'Team_B_Player_0', 'Team_B_Player_1'], + 'forces': [0, 0, 0, 0], + 'score': 'Advantage: None', + 'rope_mark': 20 +}) + +print(player_force) + +limit1 = 5 +limit2 = 35 +rope_range = 40 + + +# Create Flask server +server = Flask(__name__) + +# Create Dash app +app = dash.Dash(__name__, server=server,external_stylesheets=[dbc.themes.BOOTSTRAP]) + +df = ap.build_rope_dataframe(limit1, limit2, player_force['rope_mark']) + +# Define layout +app.layout = html.Div([ + dbc.Card( + dbc.CardBody([ + + # Row 1: title + dbc.Row([ + dbc.Col([ + html.Div( + dbc.CardImg(src='assets/lf.png', + style={'backgroundColor': '#013163', 'width': '40%', 'height': '40%'}, + id='logo' + ) + , style={'align': 'center'}) + ], align='center', width=2), + dbc.Col([ + html.Div(ap.drawTextCard("TUG OF WAR"), + id='title'), + ], width=10), + ], style={'backgroundColor': '#013163'}, align='center'), + html.Br(), + + ### Row 2: Score + dbc.Row([ + dbc.Col([ + html.Div( + dbc.Card([ + dbc.CardBody([ + html.Div([ + dcc.Input(id='score', value=player_force['score'], type="text", style={'fontSize': '20px'}) + ], style={'textAlign': 'center'}) + ]) + ]) + ), + ], width=12), + ], align='center'), + html.Br(), + + ### Row 3: Rope + dbc.Row([ + dbc.Col([ + html.Div( + dbc.Card( + dbc.CardBody([ + dcc.Graph( + id='rope', + figure=px.scatter(df, + x="x", + y="y", + color="val", + symbol='val', + size='val', + range_x=[1,rope_range], + range_y=[0, 0] + ).update_layout( + template='plotly_dark', + plot_bgcolor= 'rgba(0, 0, 0, 0)', + paper_bgcolor= 'rgba(0, 0, 0, 0)', + xaxis={'visible':False}, + coloraxis={'showscale':False} + ), + config={ + 'displayModeBar': False + } + + ) + ]) + ), + ) + ], width=12), + ], align='center'), + html.Br(), + + ### Row 4: Gauges + dbc.Row([ + ## Gauge 1 + dbc.Col([ + html.Div( + dbc.Card([ + dbc.CardBody([ + html.Div([ + daq.Gauge( + value=player_force['forces'][0], + label=player_force['players'][0], + max=20, + min=0, id='gauge1' + ) + ], style={'color': 'dark', 'margin': '2', 'textAlign': 'center'}) + ]) + ]) + ), + ], width=3), + + ## Gauge 2 + dbc.Col([ + html.Div( + dbc.Card([ + dbc.CardBody([ + html.Div([ + daq.Gauge( + value=player_force['forces'][1], + label=player_force['players'][1], + max=20, + min=0, id='gauge2' + ) + ], style={'color': 'dark', 'margin': '2', 'textAlign': 'center'}) + ]) + ]) + ), + ], width=3), + + ## Gauge 3 + dbc.Col([ + html.Div( + dbc.Card([ + dbc.CardBody([ + html.Div([ + daq.Gauge( + value=player_force['forces'][2], + label=player_force['players'][2], + max=20, + min=0, id='gauge3' + ) + ], style={'color': 'dark', 'margin': '2', 'textAlign': 'center'}) + ]) + ]) + ), + ], width=3), + + ## Gauge 4 + dbc.Col([ + html.Div( + dbc.Card([ + dbc.CardBody([ + html.Div([ + daq.Gauge( + value=player_force['forces'][3], + label=player_force['players'][3], + max=20, + min=0, id='gauge4' + ) + ], style={'color': 'dark', 'margin': '2', 'textAlign': 'center'}) + ]) + ]) + ), + ], width=3), + ],align='center'), + + ]) + ), dcc.Interval(id='interval-component', interval=1000, n_intervals=0) +]) + +@app.callback([ + Output('gauge1', 'value'), + Output('gauge2', 'value'), + Output('gauge3', 'value'), + Output('gauge4', 'value'), + Output('rope', 'figure'), + Output('score', 'value') + ], + Input('interval-component', 'n_intervals') +) +def update_layout(n): + global player_force + global rope_range + global limit1 + global limit2 + df = ap.build_rope_dataframe(limit1, limit2, player_force['rope_mark']) + fig = px.scatter(df, + x="x", + y="y", + color="val", + symbol='val', + size='val', + range_x=[1,rope_range], + range_y=[0, 0] + ).update_layout( + template='plotly_dark', + plot_bgcolor= 'rgba(0, 0, 0, 0)', + paper_bgcolor= 'rgba(0, 0, 0, 0)', + xaxis={'visible':False}, + coloraxis={'showscale':False} + ) + return player_force['forces'][0], \ + player_force['forces'][1], \ + player_force['forces'][2], \ + player_force['forces'][3], \ + fig, \ + player_force['score'] + +@server.route('/update_force', methods=['POST']) +def update_force(): + global player_force + try: + data = json.loads(request.data) + player_force = data[0] + print(player_force) + # player_force['players'] = data['players'] + # player_force['rope_mark'] = int(data['rope_mark']) + return 'Force values updated successfully' + except Exception as e: + return str(e), 400 + +if __name__ == '__main__': + server.run(port=5004) diff --git a/experiments/C/src/TugOfWar/Interface/app_helper.py b/experiments/C/src/TugOfWar/Interface/app_helper.py new file mode 100755 index 00000000..7f14b53b --- /dev/null +++ b/experiments/C/src/TugOfWar/Interface/app_helper.py @@ -0,0 +1,63 @@ +from dash import dcc, html +import dash_bootstrap_components as dbc +import plotly.express as px +import dash_daq as daq +import pandas as pd +import plotly.graph_objects as go + +def drawFigureCard(l1, l2, m): + df = build_rope_dataframe(l1, l2, m) + return dbc.Card( + dbc.CardBody([ + dcc.Graph( + figure=px.scatter(df, + x="x", + y="y", + color="val", + symbol='val', + size='val', + range_x=[0,40], + range_y=[0, 0] + ).update_layout( + template='plotly_dark', + plot_bgcolor= 'rgba(0, 0, 0, 0)', + paper_bgcolor= 'rgba(0, 0, 0, 0)', + xaxis={'visible':False}, + coloraxis={'showscale':False} + ), + config={ + 'displayModeBar': False + } + ) + ]) + ) + +# Title field +def drawTextCard(tt): + return dbc.Card( + dbc.CardBody([ + html.Div([ + html.H1(tt, style={'color': 'white'}), + ], style={'textAlign': 'center'}) + ], style={'backgroundColor': '#013163'}) + ) + +# Build the dataframe for the heatmap +def build_rope_dataframe(limit1, limit2, mark): + # Create a DataFrame of zeros + # Create lists for 'x', 'y', and 'val' + x_values = list(range(1, 39)) + y_values = [0] + val_values = [0] * len(x_values) + data = {'x': [], 'y': [], 'val': []} + for y in y_values: + data['x'].extend(x_values) + data['y'].extend([y] * len(x_values)) + data['val'].extend(val_values) + df = pd.DataFrame(data) + # Render the limits + df.loc[(df['x'] == limit1) & (df['y'] == 0), 'val'] = 50 + df.loc[(df['x'] == limit2) & (df['y'] == 0), 'val'] = 50 + # # Render the mark + df.loc[(df['x'] == mark) & (df['y'] == 0), 'val'] = 100 + return df diff --git a/experiments/C/src/TugOfWar/Interface/assets/lf.png b/experiments/C/src/TugOfWar/Interface/assets/lf.png new file mode 100755 index 0000000000000000000000000000000000000000..5c6bd98d5a2172a2db718d96996dee428d260bf3 GIT binary patch literal 3429 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 Hu0mjfbI6Sj literal 0 HcmV?d00001 diff --git a/experiments/C/src/TugOfWar/Interface/request.sh b/experiments/C/src/TugOfWar/Interface/request.sh new file mode 100755 index 00000000..d48afe7d --- /dev/null +++ b/experiments/C/src/TugOfWar/Interface/request.sh @@ -0,0 +1,7 @@ +curl -X POST http://127.0.0.1:5004/update_force -H "Content-Type: application/json" -d '[ + {"players": ["Team_A_Player_0", "Team_A_Player_1", "Team_B_Player_0", "Team_B_Player_1"], + "forces": [12, 13, 11, 12], + "score": "ttt", + "rope_mark": 1 + } +]' diff --git a/experiments/C/src/TugOfWar/Interface/requirements.txt b/experiments/C/src/TugOfWar/Interface/requirements.txt new file mode 100755 index 00000000..70e7fae5 --- /dev/null +++ b/experiments/C/src/TugOfWar/Interface/requirements.txt @@ -0,0 +1,7 @@ +flask==2.2.0 +dash==2.11.1 +Werkzeug==2.2.0 +pandas +plotly_express +dash_bootstrap_components +dash_daq \ No newline at end of file diff --git a/experiments/C/src/TugOfWar/Interface/start.sh b/experiments/C/src/TugOfWar/Interface/start.sh new file mode 100755 index 00000000..16760419 --- /dev/null +++ b/experiments/C/src/TugOfWar/Interface/start.sh @@ -0,0 +1,18 @@ +#!/bin/bash +if [ ! -f ".lf_env/bin/activate" ] +then + # Create a virtual environment + virtualenv .venv + + # Activate the virtual environment + source .venv/bin/activate + + # Install Flask + pip install -r requirements.txt +else + # Activate the virtual environment + source .venv/bin/activate +fi + +# Start the Flask and Dash application +python3 app.py \ No newline at end of file diff --git a/experiments/C/src/TugOfWar/Player.lf b/experiments/C/src/TugOfWar/Player.lf new file mode 100755 index 00000000..10b3ad1e --- /dev/null +++ b/experiments/C/src/TugOfWar/Player.lf @@ -0,0 +1,17 @@ +target C + +preamble {= + #include +=} + +reactor Player(max_force: int = 7) { + output out: int + timer t(0, 1 s) + + reaction(t) -> out {= + int lower = 1; + int force = (rand() % (self->max_force - lower + 1)) + lower; + lf_print("Force = %d", force); + lf_set(out, force); + =} +} diff --git a/experiments/C/src/TugOfWar/README.md b/experiments/C/src/TugOfWar/README.md new file mode 100644 index 00000000..31b8a28d --- /dev/null +++ b/experiments/C/src/TugOfWar/README.md @@ -0,0 +1,17 @@ +## Tug of War + +Tug of War is a team-based game where two teams pull on opposite ends of a rope to bring the other team across a center marker. The demo involves two players per team, each characterized by a parameter. Players apply a randomly generated force within the interval 1 and a specified maximum force parameter. The sum of forces on each side moves the marker, and when it reaches one of the limits, the game ends. + +## How it works + +This example features a browser-based UI. The server is constructed using [Flask](https://flask.palletsprojects.com/en/3.0.x/), a Python web framework, and [Dash](https://dash.plotly.com/) components. + +Every second, player forces are generated and their values are send to the server as +a post request. The UI's gauges are updated with these values, along with the position of the mark (yellow square). When the mark reaches one of the limits (pink diamond), the label on the top of the page is updated with the result. + +## Steps: + + 1. Compile `TugOfWar.lf`. + 2. Launch the UI by runnig the script `start.sh` under `C/src/TugOfWar/Interface`. The script will create a virtual environment and install the requirements listed in `requirements.txt`, if not there already. It then lauches Falsk server, accessible on: [http://127.0.0.1:5004](http://127.0.0.1:5004). + 3. Run the launching script under `bin` and watch the game on the UI. + diff --git a/experiments/C/src/TugOfWar/TugOfWar.lf b/experiments/C/src/TugOfWar/TugOfWar.lf new file mode 100755 index 00000000..1a774860 --- /dev/null +++ b/experiments/C/src/TugOfWar/TugOfWar.lf @@ -0,0 +1,21 @@ +target C { + keepalive: true +} + +import Player from "Player.lf" +import TugOfWarGame from "TugOfWarGame.lf" + +preamble {= + #include + #include +=} + +federated reactor TugOfWar { + towg = new TugOfWarGame() + p1 = new Player(max_force=5) + p2 = new Player(max_force=6) + p3 = new Player(max_force=3) + p4 = new Player(max_force=9) + + p1.out, p2.out, p3.out, p4.out -> towg.force +} diff --git a/experiments/C/src/TugOfWar/TugOfWarGame.lf b/experiments/C/src/TugOfWar/TugOfWarGame.lf new file mode 100755 index 00000000..3871000f --- /dev/null +++ b/experiments/C/src/TugOfWar/TugOfWarGame.lf @@ -0,0 +1,111 @@ +target C + +preamble {= + #include + #include +=} + +reactor TugOfWarGame { + input[4] force: int // Each player will exert a force + + timer t(0, 1 s) // Timer to compute the total status and send the display request + + state agent_force: int[4] = {0, 0, 0, 0} // States + state rope_mark: int = 20 + state updated: bool = false + + reaction(startup) {= + // Construct the data to send + char curl_cmd[1024]; + sprintf(curl_cmd, + "curl -X POST http://127.0.0.1:5004/update_force -H \"Content-Type: application/json\" -d '[ \ + {\"players\": [\"Team_A_Player_0\", \"Team_A_Player_1\", \"Team_B_Player_0\", \"Team_B_Player_1\"], \ + \"forces\": [0, 0, 0, 0], \ + \"score\": \"Advantage: None\", \ + \"rope_mark\": 20 \ + }\ + ]' \ + " + ); + int status = system(curl_cmd); + if (status == 0) { + lf_print("Updates successfully sent."); + } else { + lf_print("Unable to send update."); + } + =} + + reaction(force) {= + int sum = 0; + for (int i = 0; i < 4; i++) { + if (force[i]->is_present) { + self->agent_force[i] = force[i]->value; + self->updated = true; + } + } + =} + + reaction(t) {= + if (self->updated) { + // Compute the new rope mark position + self->rope_mark = self->rope_mark - self->agent_force[0] + - self->agent_force[1] + + self->agent_force[2] + + self->agent_force[3]; + + // Derive the new score + char score[25]; + if (self->rope_mark <= 5) { + sprintf(score, "Winner: Team A"); + } else if (self->rope_mark >= 35) { + sprintf(score, "Winner: Team B"); + } else if (self->rope_mark == 20) { + sprintf(score, "Advantage: None"); + } else if (self->rope_mark < 20) { + sprintf(score, "Advantage: Team A"); + } else { + sprintf(score, "Advantage: Team B"); + } + + + // Construct the data to send + char curl_cmd[1024]; + + sprintf(curl_cmd, + "curl -X POST http://127.0.0.1:5004/update_force -H \"Content-Type: application/json\" -d '[ \ + {\"players\": [\"Team_A_Player_0\", \"Team_A_Player_1\", \"Team_B_Player_0\", \"Team_B_Player_1\"], \ + \"forces\": [%d, %d, %d, %d], \ + \"score\": \"%s\", \ + \"rope_mark\": %d \ + }\ + ]' \ + ", + self->agent_force[0], + self->agent_force[1], + self->agent_force[2], + self->agent_force[3], + score, + self->rope_mark + ); + + int status = system(curl_cmd); + if (status == 0) { + lf_print("Updates successfully sent."); + } else { + lf_print("Unable to send update."); + } + + self->updated = false; + + // Reset all forces + for (int i = 0; i < 4; i++) { + self->agent_force[i] = 0; + } + + // If one of team won, stop the game + if (self->rope_mark<= 5 || self->rope_mark >= 35) { + lf_request_stop(); + } + } + =} +} From 4dc465a1f9760bcad5a43840c66f074dbb4ae086 Mon Sep 17 00:00:00 2001 From: Chadlia Jerad <37504116+ChadliaJerad@users.noreply.github.com> Date: Mon, 5 Feb 2024 09:13:22 +0100 Subject: [PATCH 2/4] Update experiments/C/src/TugOfWar/README.md Co-authored-by: Edward A. Lee --- experiments/C/src/TugOfWar/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/C/src/TugOfWar/README.md b/experiments/C/src/TugOfWar/README.md index 31b8a28d..05c86d1b 100644 --- a/experiments/C/src/TugOfWar/README.md +++ b/experiments/C/src/TugOfWar/README.md @@ -12,6 +12,6 @@ a post request. The UI's gauges are updated with these values, along with the po ## Steps: 1. Compile `TugOfWar.lf`. - 2. Launch the UI by runnig the script `start.sh` under `C/src/TugOfWar/Interface`. The script will create a virtual environment and install the requirements listed in `requirements.txt`, if not there already. It then lauches Falsk server, accessible on: [http://127.0.0.1:5004](http://127.0.0.1:5004). + 2. Launch the UI by running the script `start.sh` under `C/src/TugOfWar/Interface`. The script will create a virtual environment and install the requirements listed in `requirements.txt`, if not there already. It then lauches Falsk server, accessible on: [http://127.0.0.1:5004](http://127.0.0.1:5004). 3. Run the launching script under `bin` and watch the game on the UI. From 8330fbf035a541eef3af16c69023a1749516f09b Mon Sep 17 00:00:00 2001 From: Chadlia Jerad <37504116+ChadliaJerad@users.noreply.github.com> Date: Mon, 5 Feb 2024 09:13:54 +0100 Subject: [PATCH 3/4] Update experiments/C/src/TugOfWar/Interface/requirements.txt Co-authored-by: Edward A. Lee --- experiments/C/src/TugOfWar/Interface/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/experiments/C/src/TugOfWar/Interface/requirements.txt b/experiments/C/src/TugOfWar/Interface/requirements.txt index 70e7fae5..1d357f30 100755 --- a/experiments/C/src/TugOfWar/Interface/requirements.txt +++ b/experiments/C/src/TugOfWar/Interface/requirements.txt @@ -4,4 +4,5 @@ Werkzeug==2.2.0 pandas plotly_express dash_bootstrap_components -dash_daq \ No newline at end of file +dash_daq +setuptools From 28c902ecd76c77ee0d6adb4e71f4a967432a7119 Mon Sep 17 00:00:00 2001 From: Chadlia Jerad Date: Mon, 5 Feb 2024 09:36:44 +0100 Subject: [PATCH 4/4] Manual commit of an outdated commit suggestion --- experiments/C/src/TugOfWar/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/C/src/TugOfWar/README.md b/experiments/C/src/TugOfWar/README.md index 05c86d1b..c99eaae4 100644 --- a/experiments/C/src/TugOfWar/README.md +++ b/experiments/C/src/TugOfWar/README.md @@ -12,6 +12,6 @@ a post request. The UI's gauges are updated with these values, along with the po ## Steps: 1. Compile `TugOfWar.lf`. - 2. Launch the UI by running the script `start.sh` under `C/src/TugOfWar/Interface`. The script will create a virtual environment and install the requirements listed in `requirements.txt`, if not there already. It then lauches Falsk server, accessible on: [http://127.0.0.1:5004](http://127.0.0.1:5004). + 2. Launch the UI by running the script `start.sh` in the `C/src/TugOfWar/Interface` directory. The script will create a virtual environment and install the requirements listed in `requirements.txt`, if not there already. It then lauches Flask server, accessible on: [http://127.0.0.1:5004](http://127.0.0.1:5004). 3. Run the launching script under `bin` and watch the game on the UI.