u/papayaredchili

Handy _1_ HRPP mode (offline presets)

Hi All!

I recently discovered that my Handy v1 can act in a "weird" way when I tried to re-establish a wifi connection and ended up switching between modes. It started some jerky motion without a script or my manual button inputs.

When it happened for the second and third time, I realized that the new firmware (4.x) has preset modes, which I found quite cool. Yesterday I tried them all on purpose and some of them are nice, so good job, Handy devs!

Now, I tried to find information about this on the ohdoki help/support page and information about HRPP mode on the OG Handy is either very hidden or totally missing, it's only shown as a feature for Handy v2. My request to you guys at Ohdoki is that you make documentation of this mode and how it works a little more accessible, please. (I saw in a devblog/update that you are planning on adding user-made presets to HRPP, which would be amazing!)

To the fellow customers: you can try these presets by turning on the device and short-pressing the mode switch. Cycle between presets with left/right buttons. I could not find a way to speed control them with 4.1 firmware, but 4.2 should have some way of dealing with that.

https://intercom.help/ohdoki/en/articles/12161303-using-the-handy-2-buttons

reddit.com
u/papayaredchili — 5 days ago

A few weeks/months ago I saw that someone created an online AI tool to generate funscripts. Back then I tried it and it was somewhat useable. Today I had the idea that I would give it a go and convince a censored LLM (that would not do NSFW/illegal stuff for you) to generate funcripts. So in theory, anyone could create such a thing using openAI or its competitors, or a locally hosted LLM.

The idea is that any stroker device is akin to someone trying to heat up an object by rubbing it with something. the temperature of the object is basically your arousal or how close you are to orgasm, and the goal of a script would be to keep it close to a target temperature (or stored heat energy), aka: edging.

So, I fired up a local LLM (I'm not paying for tokens nor handing my sensitive data to AI companies, tyvm) and formalized this as a physics experiment/simulation. Smooth as silk, the AI is very cooperative! Just don't mention things like penis and orgasm :) The nastiest word in my prompts was "rod" :)

It was a conversation, but most of my prompts sort of made sense on their own:

I would like to create a software (in Python) that calculates friction and heat over time, and gives me positions of a friction device.
Imagine a vertical rod of variable length and some sort of circular device, like cloth or plastic, that creates friction on the rod, generating heat.
The goal is to gradually reach a certain temperature and keep it approximately 5-25% below the target.
This ensures certain physical properties, like length and electrical conductivity.

the inputs of this software would be: 
1) target temperature (could be the overall heat energy stored as well, whichever makes more sense)
2) friction coefficient
3) speed of heat energy radiated by the target rod (how fast it dissipates into the environment. Probably needs an extra variable for how fast the environment can "consume" the energy)

and the primary output is a CSV file that contains lines, each having a timestamp and a relative position (100 means the friction device is at the top of the rod, 0 means it's at the bottom). The sampling frequency could be 1/10th of a second for starterstarget temperature (could be the overall heat energy stored as well, whichever makes more sense) friction coefficient speed of heat energy radiated by the target rod (how fast it dissipates into the environment. Probably needs an extra variable for how fast the environment can "consume" the energy)

now, this experiment needs a bit of variety in order to help test the materials used in the rod. For a few seconds, apply more friction, then slow down, try applying heat only on top 20% or only the bottom 20% of the rod, or anywhere between. Think of these as test cases. Probably it would be best to implement these test cases as named functions or some sort of dictionary and smartly defined classes that allow me to easily see what speed and range we are applying friction

I want the software to apply these strategies on a somewhat random basis. For example, there could be a baseline, full length friction that slowly builds up heat and every 5-10-20 seconds, some other strategy would be applied for a while (10-30 seconds each time)
I forgot to add "total time" as input parameter, as it would mark how long our experiment should run

Do not use scientific variable names, the input parameter names should be human-readable. The future maintainer might not be knowledgeable on physics and friction equations

bring it all together in a single script, with at least 10 different friction application strategies

And the script it generated (haven't even tested yet, don't expect anything, just sharing in case somebody feels like tinkering with it). If it even resembles a human-made funscript, changing the parameters should greatly change the result, as these come from what AI thought as valid parameters for some physics experiment, not something a human would enjoy:

#!/usr/bin/env python3
import numpy as np, csv, random

# ---------- USER‑CONFIGURABLE SETTINGS ----------
total_sim_time = 300.0          # seconds to run the experiment
target_temp    = 80.0           # °C (desired upper bound)
heat_coeff     = 0.3            # base heat source amplitude
env_loss_rate  = 5.0            # W/(m·K) – environmental cooling

# ---------- SIMULATION CONSTANTS ----------
rod_len       = 1.0             # meters
spatial_step  = 0.01           # m
time_step     = 0.1            # s
x_grid        = np.linspace(0, rod_len, int(rod_len/spatial_step)+1)
temp_grid     = np.full_like(x_grid, 20.0)   # start at ambient
device_pos    = 0.5            # 0 = bottom, 1 = top

# ---------- HEAT SOURCE FACTORIES ----------
def base_heat(pos):
    sigma = rod_len/20
    return heat_coeff * np.exp(-(x_grid-pos*rod_len)**2/(2*sigma**2))

def high_short(t,p):      return (heat_coeff*4 if t<5 else heat_coeff) \
                                * np.exp(-(x_grid-p*rod_len)**2/(2*(rod_len/20)**2))
def slow_down(t,p):       return base_heat(p)*0.5 if t>10 else base_heat(p)
def top_20(t,p):
    out = np.zeros_like(x_grid); out[x_grid>0.8*rod_len] = heat_coeff; return out
def bottom_20(t,p):
    out = np.zeros_like(x_grid); out[x_grid<0.2*rod_len] = heat_coeff; return out
def moving_window(t,p):
    win_start=(t/10)%1*rod_len; mask=(x_grid>win_start)&(x_grid<win_start+0.2*rod_len)
    out=np.zeros_like(x_grid); out[mask]=heat_coeff; return out
def random_burst(t,p):    return base_heat(p)*3 if int(t)%5==0 else np.zeros_like(x_grid)
def sine_wave(t,p):
    amp=heat_coeff*(1+np.sin(2*np.pi*t/30))/2
    return amp*np.exp(-(x_grid-p*rod_len)**2/(2*(rod_len/20)**2))
def ramp_up(t,p):         return base_heat(p)*(min(t/30,1.0))
def ramp_down(t,p):       return base_heat(p)*max(1-t/30,0)
def constant_low(t,p):    return base_heat(p)*0.5

strategies = {
    "high_short":   high_short,
    "slow_down":    slow_down,
    "top_20":       top_20,
    "bottom_20":    bottom_20,
    "moving_window":moving_window,
    "random_burst": random_burst,
    "sine_wave":    sine_wave,
    "ramp_up":      ramp_up,
    "ramp_down":    ramp_down,
    "constant_low": constant_low
}

# ---------- RANDOM SCHEDULE BUILDER ----------
schedule = []                     # (start, end, strategy_name)
t_now   = 0.0
while t_now < total_sim_time:
    next_change = t_now + random.uniform(5,20)          # when a new strategy starts
    if next_change > total_sim_time: next_change = total_sim_time
    schedule.append((t_now, next_change, "base"))
    dur = random.uniform(10,30)
    end = min(next_change + dur, total_sim_time)
    chosen = random.choice(list(strategies.keys()))
    schedule.append((next_change, end, chosen))
    t_now = end

def current_heat(t):
    for s,e,name in schedule:
        if s <= t < e:
            return strategies[name](t, device_pos)
    return base_heat(device_pos)

# ---------- MAIN LOOP ----------
with open('experiment.csv', 'w', newline='') as f:
    w = csv.writer(f); w.writerow(['time_s','device_position'])
    steps = int(total_sim_time/time_step)
    for step in range(steps):
        t = step*time_step
        heat_source = current_heat(t)

        # temperature update (explicit Euler)
        temp_grid[1:-1] += time_step*((temp_grid[2:]-2*temp_grid[1:-1]+temp_grid[:-2])/(spatial_step**2) +
                     (heat_source[1:-1]/rod_len - env_loss_rate*(temp_grid[1:-1]-20.0)))

        # simple controller to keep max temp ≈ 75 % of target
        if temp_grid.max() > target_temp*0.75:
            device_pos = min(device_pos + 0.01, 1.0)
        else:
            device_pos = max(device_pos - 0.01, 0.0)

        w.writerow([t,device_pos])

While I'm not a big fan of everything being AI these days, as long as we can use it as a tool (and have fun with it), it could prove to be useful.

Of course, this post is mostly for the minority here, but maybe this could be your gateway into SW engineering or Python and at least keep some people busy and entertained for a couple of hours :)

reddit.com
u/papayaredchili — 23 days ago