Neurasense / app.py
Sephfox's picture
Update app.py
c5987cc verified
raw
history blame
4.94 kB
import streamlit as st
import numpy as np
from typing import List, Tuple
from transformers import pipeline
import matplotlib.pyplot as plt
import time
# Constants
WIDTH, HEIGHT = 600, 600
ELASTICITY = 0.3
DAMPING = 0.7
# Create touch points
num_points = 20
touch_points: List[Tuple[float, float]] = [(x, y) for x in range(50, WIDTH-50, int((WIDTH-100)/(num_points-1))) for y in range(50, HEIGHT-50, int((HEIGHT-100)/(num_points-1)))]
original_points = touch_points.copy()
velocities: List[Tuple[float, float]] = [(0.0, 0.0)] * len(touch_points)
is_affected: List[bool] = [False] * len(touch_points)
# Create pain and pleasure points
pain_points = [(100, 100), (500, 500)]
pleasure_points = [(300, 300), (200, 400)]
# Set up the Hugging Face pipeline
@st.cache_resource
def load_model():
return pipeline('text-generation', model='gpt2')
text_generator = load_model()
# Streamlit app
st.title("Advanced Artificial Touch Simulation")
# Create a Streamlit container for the touch simulation
touch_container = st.container()
def update_points():
global touch_points, velocities, is_affected
# Apply spring force
for i, (x, y) in enumerate(touch_points):
force_x = (original_points[i][0] - x) * ELASTICITY
force_y = (original_points[i][1] - y) * ELASTICITY
velocities[i] = (velocities[i][0] + force_x, velocities[i][1] + force_y)
# Apply damping
for i, (vx, vy) in enumerate(velocities):
velocities[i] = (vx * DAMPING, vy * DAMPING)
# Update position
for i, (x, y) in enumerate(touch_points):
vx, vy = velocities[i]
touch_points[i] = (x + vx, y + vy)
# Reset affected flags
is_affected = [False] * len(touch_points)
def calculate_sensation(x, y, pressure, duration):
sensation = 0
for px, py in pain_points:
distance = np.sqrt((x - px)**2 + (y - py)**2)
if distance < 50:
sensation -= (50 - distance) * pressure * (duration ** 1.5) / 50
for px, py in pleasure_points:
distance = np.sqrt((x - px)**2 + (y - py)**2)
if distance < 50:
sensation += (50 - distance) * pressure / 50
return sensation
def on_tap(x, y, pressure, duration):
global touch_points, velocities, is_affected
for i, (tx, ty) in enumerate(touch_points):
distance = ((tx - x)**2 + (ty - y)**2)**0.5
if distance < 30:
force_x = (tx - x) / distance
force_y = (ty - y) / distance
velocities[i] = (velocities[i][0] - force_x * 10 * pressure, velocities[i][1] - force_y * 10 * pressure)
is_affected[i] = True
sensation = calculate_sensation(x, y, pressure, duration)
# Generate a description of the touch
st.write(f"Touch at ({x:.2f}, {y:.2f}) with pressure {pressure:.2f} for {duration:.2f} seconds")
st.write(f"Sensation: {sensation:.2f}")
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 sensation of {sensation:.2f}. Describe the experience:"
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']
st.write(text)
update_points()
# Initialize session state
if 'x' not in st.session_state:
st.session_state.x = 0
if 'y' not in st.session_state:
st.session_state.y = 0
if 'pressure' not in st.session_state:
st.session_state.pressure = 1.0
if 'duration' not in st.session_state:
st.session_state.duration = 0.0
if 'touch_start_time' not in st.session_state:
st.session_state.touch_start_time = None
# Main app logic
fig, ax = plt.subplots(figsize=(6, 6))
ax.set_xlim(0, WIDTH)
ax.set_ylim(0, HEIGHT)
for i, (x, y) in enumerate(touch_points):
color = "red" if is_affected[i] else "navy"
ax.add_artist(plt.Circle((x, y), 5, color=color, alpha=0.5))
for x, y in pain_points:
ax.add_artist(plt.Circle((x, y), 10, color="red", alpha=0.3))
for x, y in pleasure_points:
ax.add_artist(plt.Circle((x, y), 10, color="green", alpha=0.3))
touch_container.pyplot(fig)
col1, col2 = st.columns(2)
with col1:
st.session_state.x = st.slider("X coordinate", 0, WIDTH, st.session_state.x)
st.session_state.y = st.slider("Y coordinate", 0, HEIGHT, st.session_state.y)
with col2:
st.session_state.pressure = st.slider("Pressure", 0.1, 2.0, st.session_state.pressure)
if touch_container.button("Start Touch"):
st.session_state.touch_start_time = time.time()
if touch_container.button("End Touch"):
if st.session_state.touch_start_time is not None:
st.session_state.duration = time.time() - st.session_state.touch_start_time
on_tap(st.session_state.x, st.session_state.y, st.session_state.pressure, st.session_state.duration)
st.session_state.touch_start_time = None
st.session_state.duration = 0.0
update_points()