Sephfox commited on
Commit
9aeacca
·
verified ·
1 Parent(s): 43d4502

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -76
app.py CHANGED
@@ -1,32 +1,39 @@
1
  import streamlit as st
2
  import numpy as np
3
- from typing import List, Tuple
4
- from transformers import pipeline
5
  import matplotlib.pyplot as plt
6
  from matplotlib.backends.backend_agg import FigureCanvasAgg
7
  from streamlit_drawable_canvas import st_canvas
8
  import time
9
  from PIL import Image
10
  import io
 
11
 
12
  # Constants
13
- WIDTH, HEIGHT = 600, 600
14
- ELASTICITY = 0.3
15
- DAMPING = 0.7
16
 
17
- # Create sensation map
 
 
 
 
 
 
 
 
 
18
  def create_sensation_map(width, height):
19
  sensation_map = np.zeros((height, width, 3)) # RGB channels for pain, pleasure, and neutral
20
  for y in range(height):
21
  for x in range(width):
22
  # Base sensation
23
- base = np.sin(x/30) * np.cos(y/30) * 0.5 + np.random.normal(0, 0.1)
24
 
25
  # Pain regions (red channel)
26
- pain = np.exp(-((x-150)**2 + (y-150)**2) / 5000) + np.exp(-((x-450)**2 + (y-450)**2) / 5000)
27
 
28
  # Pleasure regions (green channel)
29
- pleasure = np.exp(-((x-300)**2 + (y-300)**2) / 5000) + np.exp(-((x-150)**2 + (y-450)**2) / 5000)
30
 
31
  # Neutral sensation (blue channel)
32
  neutral = 1 - (pain + pleasure)
@@ -35,51 +42,66 @@ def create_sensation_map(width, height):
35
 
36
  return sensation_map
37
 
38
- sensation_map = create_sensation_map(WIDTH, HEIGHT)
39
-
40
- # Set up the Hugging Face pipeline
41
- @st.cache_resource
42
- def load_model():
43
- return pipeline('text-generation', model='gpt2')
44
-
45
- text_generator = load_model()
46
 
47
  # Streamlit app
48
- st.title("Advanced Artificial Touch Simulation")
49
-
50
- # Create a Streamlit container for the touch simulation
51
- touch_container = st.container()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  def calculate_sensation(x, y, pressure, duration):
54
- # Get sensation from the map
55
- sensation = sensation_map[int(y), int(x)]
56
-
57
- # Modify sensation based on pressure and duration
58
  modified_sensation = sensation * pressure * (1 + np.log(duration + 1))
59
-
60
  return modified_sensation
61
 
62
- def on_touch(x, y, pressure, duration):
63
- sensation = calculate_sensation(x, y, pressure, duration)
64
- pain = sensation[0]
65
- pleasure = sensation[1]
66
- neutral = sensation[2]
67
-
68
- # Generate a description of the touch
69
- st.write(f"Touch at ({x:.2f}, {y:.2f}) with pressure {pressure:.2f} for {duration:.2f} seconds")
70
- st.write(f"Pain: {pain:.2f}, Pleasure: {pleasure:.2f}, Neutral: {neutral:.2f}")
71
 
72
- # Determine the dominant sensation
73
- if pain > pleasure and pain > neutral:
74
- dominant = "pain"
75
- elif pleasure > pain and pleasure > neutral:
76
- dominant = "pleasure"
77
- else:
78
- dominant = "neutral"
79
 
80
- prompt = f"The user touched the screen at ({x:.2f}, {y:.2f}) with a pressure of {pressure:.2f} for {duration:.2f} seconds, resulting in a {dominant} sensation. Pain: {pain:.2f}, Pleasure: {pleasure:.2f}, Neutral: {neutral:.2f}. Describe the experience:"
81
- text = text_generator(prompt, max_length=100, num_return_sequences=1, do_sample=True, top_k=50, top_p=0.95, num_beams=1)[0]['generated_text']
82
- st.write(text)
83
 
84
  # Initialize session state
85
  if 'touch_start_time' not in st.session_state:
@@ -87,34 +109,6 @@ if 'touch_start_time' not in st.session_state:
87
  if 'last_touch_position' not in st.session_state:
88
  st.session_state.last_touch_position = None
89
 
90
- # Main app logic
91
- fig, ax = plt.subplots(figsize=(6, 6))
92
- ax.imshow(sensation_map)
93
- ax.axis('off')
94
-
95
- # Convert matplotlib figure to Image
96
- canvas = FigureCanvasAgg(fig)
97
- canvas.draw()
98
- buf = io.BytesIO()
99
- plt.savefig(buf, format='png')
100
- buf.seek(0)
101
- img = Image.open(buf)
102
-
103
- # Use streamlit-drawable-canvas for interaction
104
- canvas_result = st_canvas(
105
- fill_color="rgba(255, 165, 0, 0.3)",
106
- stroke_width=3,
107
- stroke_color="#e00",
108
- background_color="#eee",
109
- background_image=img,
110
- update_streamlit=True,
111
- height=HEIGHT,
112
- width=WIDTH,
113
- drawing_mode="point",
114
- point_display_radius=0,
115
- key="canvas",
116
- )
117
-
118
  # Handle touch events
119
  if canvas_result.json_data is not None:
120
  objects = canvas_result.json_data["objects"]
@@ -136,12 +130,21 @@ if canvas_result.json_data is not None:
136
  pressure = 1.0
137
 
138
  duration = time.time() - st.session_state.touch_start_time
139
- on_touch(current_position[0], current_position[1], pressure, duration)
 
 
 
 
 
 
 
 
 
140
 
141
  st.session_state.last_touch_position = current_position
142
  else:
143
  st.session_state.touch_start_time = None
144
  st.session_state.last_touch_position = None
145
 
146
- st.write("Click and drag on the image to simulate touch. The color represents different sensations.")
147
- st.write("Red areas are pain regions, green areas are pleasure regions, and blue areas are neutral.")
 
1
  import streamlit as st
2
  import numpy as np
 
 
3
  import matplotlib.pyplot as plt
4
  from matplotlib.backends.backend_agg import FigureCanvasAgg
5
  from streamlit_drawable_canvas import st_canvas
6
  import time
7
  from PIL import Image
8
  import io
9
+ from transformers import AutoModelForCausalLM, AutoTokenizer
10
 
11
  # Constants
12
+ WIDTH, HEIGHT = 800, 400
13
+ AVATAR_WIDTH, AVATAR_HEIGHT = 300, 400
 
14
 
15
+ # Set up DialoGPT model
16
+ @st.cache_resource
17
+ def load_model():
18
+ tokenizer = AutoTokenizer.from_pretrained("microsoft/DialoGPT-small")
19
+ model = AutoModelForCausalLM.from_pretrained("microsoft/DialoGPT-small")
20
+ return tokenizer, model
21
+
22
+ tokenizer, model = load_model()
23
+
24
+ # Create sensation map for the avatar
25
  def create_sensation_map(width, height):
26
  sensation_map = np.zeros((height, width, 3)) # RGB channels for pain, pleasure, and neutral
27
  for y in range(height):
28
  for x in range(width):
29
  # Base sensation
30
+ base = np.sin(x/15) * np.cos(y/15) * 0.5 + np.random.normal(0, 0.1)
31
 
32
  # Pain regions (red channel)
33
+ pain = np.exp(-((x-75)**2 + (y-100)**2) / 2000) + np.exp(-((x-225)**2 + (y-300)**2) / 2000)
34
 
35
  # Pleasure regions (green channel)
36
+ pleasure = np.exp(-((x-150)**2 + (y-200)**2) / 2000) + np.exp(-((x-75)**2 + (y-300)**2) / 2000)
37
 
38
  # Neutral sensation (blue channel)
39
  neutral = 1 - (pain + pleasure)
 
42
 
43
  return sensation_map
44
 
45
+ avatar_sensation_map = create_sensation_map(AVATAR_WIDTH, AVATAR_HEIGHT)
 
 
 
 
 
 
 
46
 
47
  # Streamlit app
48
+ st.title("Advanced Humanoid Touch Simulation")
49
+
50
+ # Create two columns
51
+ col1, col2 = st.columns(2)
52
+
53
+ # Avatar column
54
+ with col1:
55
+ st.subheader("Humanoid Avatar")
56
+ avatar_fig, avatar_ax = plt.subplots(figsize=(4, 6))
57
+ avatar_ax.imshow(avatar_sensation_map)
58
+ avatar_ax.axis('off')
59
+ st.pyplot(avatar_fig)
60
+
61
+ # Touch interface column
62
+ with col2:
63
+ st.subheader("Touch Interface")
64
+ touch_fig, touch_ax = plt.subplots(figsize=(4, 6))
65
+ touch_ax.add_patch(plt.Rectangle((0, 0), AVATAR_WIDTH, AVATAR_HEIGHT, fill=False))
66
+ touch_ax.set_xlim(0, AVATAR_WIDTH)
67
+ touch_ax.set_ylim(0, AVATAR_HEIGHT)
68
+ touch_ax.axis('off')
69
+
70
+ # Convert matplotlib figure to Image
71
+ canvas = FigureCanvasAgg(touch_fig)
72
+ canvas.draw()
73
+ buf = io.BytesIO()
74
+ plt.savefig(buf, format='png')
75
+ buf.seek(0)
76
+ img = Image.open(buf)
77
+
78
+ # Use streamlit-drawable-canvas for interaction
79
+ canvas_result = st_canvas(
80
+ fill_color="rgba(255, 165, 0, 0.3)",
81
+ stroke_width=3,
82
+ stroke_color="#e00",
83
+ background_color="#eee",
84
+ background_image=img,
85
+ update_streamlit=True,
86
+ height=AVATAR_HEIGHT,
87
+ width=AVATAR_WIDTH,
88
+ drawing_mode="point",
89
+ point_display_radius=5,
90
+ key="canvas",
91
+ )
92
 
93
  def calculate_sensation(x, y, pressure, duration):
94
+ sensation = avatar_sensation_map[int(y), int(x)]
 
 
 
95
  modified_sensation = sensation * pressure * (1 + np.log(duration + 1))
 
96
  return modified_sensation
97
 
98
+ def generate_description(x, y, pressure, duration, pain, pleasure, neutral):
99
+ prompt = f"Human: Describe the sensation when touched at ({x:.1f}, {y:.1f}) with pressure {pressure:.2f} for {duration:.2f} seconds. Pain: {pain:.2f}, Pleasure: {pleasure:.2f}, Neutral: {neutral:.2f}.\nAvatar:"
 
 
 
 
 
 
 
100
 
101
+ input_ids = tokenizer.encode(prompt, return_tensors="pt")
102
+ output = model.generate(input_ids, max_length=150, num_return_sequences=1, no_repeat_ngram_size=2, top_k=50, top_p=0.95, temperature=0.7)
 
 
 
 
 
103
 
104
+ return tokenizer.decode(output[0], skip_special_tokens=True).split("Avatar: ")[-1].strip()
 
 
105
 
106
  # Initialize session state
107
  if 'touch_start_time' not in st.session_state:
 
109
  if 'last_touch_position' not in st.session_state:
110
  st.session_state.last_touch_position = None
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  # Handle touch events
113
  if canvas_result.json_data is not None:
114
  objects = canvas_result.json_data["objects"]
 
130
  pressure = 1.0
131
 
132
  duration = time.time() - st.session_state.touch_start_time
133
+ x, y = current_position
134
+ sensation = calculate_sensation(x, y, pressure, duration)
135
+ pain, pleasure, neutral = sensation
136
+
137
+ description = generate_description(x, y, pressure, duration, pain, pleasure, neutral)
138
+
139
+ st.write(f"Touch at ({x:.1f}, {y:.1f}) with pressure {pressure:.2f} for {duration:.2f} seconds")
140
+ st.write(f"Pain: {pain:.2f}, Pleasure: {pleasure:.2f}, Neutral: {neutral:.2f}")
141
+ st.write("Avatar's response:")
142
+ st.write(description)
143
 
144
  st.session_state.last_touch_position = current_position
145
  else:
146
  st.session_state.touch_start_time = None
147
  st.session_state.last_touch_position = None
148
 
149
+ st.write("Click and drag on the touch interface to simulate touching the avatar.")
150
+ st.write("The avatar's sensation map shows pain (red), pleasure (green), and neutral (blue) areas.")