first commit

This commit is contained in:
Dejan R. 2026-01-06 18:05:40 +01:00
parent 47371c5a50
commit e55cbf11c8
2 changed files with 287 additions and 0 deletions

278
main.py Normal file
View file

@ -0,0 +1,278 @@
import streamlit as st
from math import gcd
# ----------------------------
# Helpers
# ----------------------------
def simplify_fraction(n: int, d: int) -> tuple[int, int]:
if d == 0:
raise ValueError("Denominator cannot be 0.")
if n == 0:
return 0, 1
g = gcd(abs(n), abs(d))
n //= g
d //= g
# Keep denominator positive
if d < 0:
n *= -1
d *= -1
return n, d
def scale_down_to_limit(n: int, d: int, limit: int) -> tuple[int, int]:
"""
If numerator/denominator exceed 'limit', scale them down proportionally.
Keeps ratio approximately the same (exact if divisible), then re-simplifies.
"""
if n == 0:
return 0, 1
n_abs, d_abs = abs(n), abs(d)
if n_abs <= limit and d_abs <= limit:
return n, d
# Scale by the maximum overflow factor
factor = max((n_abs + limit - 1) // limit, (d_abs + limit - 1) // limit)
n2 = n // factor
d2 = d // factor
# Avoid zeroing out
if n2 == 0:
n2 = 1 if n > 0 else -1
if d2 == 0:
d2 = 1
return simplify_fraction(n2, d2)
# ----------------------------
# Page config + nav
# ----------------------------
st.set_page_config(page_title="Delta ASDA-A2 Engineering Tool", layout="wide")
st.sidebar.title("Configuration")
page = st.sidebar.radio(
"Go to",
["Theory & Architecture", "PUU Calculator", "Parameter Guide", "ASDA-Soft Guide"],
)
# ----------------------------
# Pages
# ----------------------------
if page == "Theory & Architecture":
st.title("📚 Theory & Architecture")
st.markdown(
"""
This tool helps you set up **electronic gearing (PUU / P1-44 & P1-45)** and the **core safety/tuning parameters**
for a system with a gearbox (e.g., **50:1**).
### Concept (simple)
Most motion controllers output **position command pulses**.
The servo drive converts those pulses into **motor encoder counts** using an **electronic gear ratio**:
\[
\\text{Motor encoder counts} = \\text{Command pulses} \\times \\frac{P1-44}{P1-45}
\]
So you choose **P1-44 / P1-45** to match *your desired user unit* (degrees, mm, etc.) at the **load side**.
### With a gearbox
- Motor counts per **load revolution** = *(motor encoder counts per motor rev)* × *(gear ratio)*
- If you want e.g. **360 units per load rev** (degrees), then:
\[
\\frac{P1-44}{P1-45} = \\frac{\\text{motor counts per load rev}}{\\text{units per load rev} \\times \\text{controller pulses per unit}}
\]
Use the **PUU Calculator** page to get clean integers.
"""
)
elif page == "PUU Calculator":
st.title("🔢 Universal PUU Calculator (P1-44 / P1-45)")
st.caption(
"Goal: convert your controller command pulses into the correct motor encoder counts, "
"including gearbox ratio, and optionally define a meaningful user unit (deg/mm/etc.)."
)
col1, col2 = st.columns(2)
with col1:
st.subheader("Input")
motor_counts_per_rev = st.number_input(
"Motor encoder counts per motor revolution",
min_value=1,
value=128000,
step=1000,
help="Common values: 128000, 131072, 1048576 ... depends on encoder/resolution & drive setting.",
)
gear_ratio = st.number_input(
"Gear ratio (motor rev per load rev)",
min_value=1.0,
value=50.0,
step=1.0,
help="For 50:1 reduction, motor turns 50 rev while load turns 1 rev => enter 50.",
)
units_per_load_rev = st.number_input(
"User units per load revolution",
min_value=1,
value=360,
step=1,
help="Examples: degrees=360, turns=1, mm per rev for a leadscrew (e.g. 5 mm/rev => 5).",
)
controller_pulses_per_unit = st.number_input(
"Controller command pulses per user unit",
min_value=1.0,
value=1.0,
step=1.0,
help="If your controller outputs 1 pulse = 1 user unit, keep 1. "
"If it outputs e.g. 10 pulses per degree, enter 10.",
)
ratio_limit = st.number_input(
"Max integer limit for P1-44 / P1-45 (safety)",
min_value=1000,
value=2_147_483_647,
step=1000,
help="Keeps numbers within typical 32-bit signed range. "
"If you know the drive's tighter limit, set it here.",
)
# Calculate
# motor_counts_per_load_rev = motor_counts_per_rev * gear_ratio
# Desired motor counts per controller pulse = motor_counts_per_load_rev / (units_per_load_rev * controller_pulses_per_unit)
motor_counts_per_load_rev = motor_counts_per_rev * gear_ratio
denom_units = units_per_load_rev * controller_pulses_per_unit
st.divider()
# Convert to integer fraction:
# We want P1-44/P1-45 = motor_counts_per_load_rev / denom_units
# If denom_units isn't integer, scale to preserve precision.
# Use 1e6 scaling for decimals, then simplify.
SCALE = 1_000_000
n_raw = int(round(motor_counts_per_load_rev * SCALE))
d_raw = int(round(denom_units * SCALE))
n_s, d_s = simplify_fraction(n_raw, d_raw)
n_final, d_final = scale_down_to_limit(n_s, d_s, int(ratio_limit))
with col2:
st.subheader("Result")
st.success("Recommended electronic gear ratio for PUU:")
st.markdown(
f"""
- **P1-44 (Numerator / N):** **{n_final}**
- **P1-45 (Denominator / M):** **{d_final}**
"""
)
# Show what it means
pulses_to_motor_counts = n_final / d_final
st.write(f"✅ This means: **1 controller pulse → {pulses_to_motor_counts:.6f} motor encoder counts**")
# Derived helpful values
motor_counts_per_user_unit = motor_counts_per_load_rev / units_per_load_rev
controller_pulses_per_load_rev = units_per_load_rev * controller_pulses_per_unit
motor_counts_per_controller_rev = controller_pulses_per_load_rev * pulses_to_motor_counts
st.markdown("### Sanity checks")
st.write(f"- Motor counts per **load rev**: **{motor_counts_per_load_rev:.3f}**")
st.write(f"- User units per **load rev**: **{units_per_load_rev:.3f}**")
st.write(f"- Motor counts per **user unit** (load side): **{motor_counts_per_user_unit:.3f}**")
st.write(f"- Controller pulses per **load rev**: **{controller_pulses_per_load_rev:.3f}**")
st.write(f"- Motor counts generated by **controller pulses per load rev**: **{motor_counts_per_controller_rev:.3f}**")
st.info(
"Tip: The last line should match (or be very close to) motor counts per load rev. "
"If it's far off, check encoder counts, gear ratio, and pulses-per-unit."
)
st.info(
"Recommended Minimum: It is generally recommended to keep the PUU per motor revolution above 5000 to avoid 'stepping' or vibration at low speeds."
)
st.info(
f"Electronic Gear Ratio Limit: Delta A2 allows a ratio between $1/50$ and $25600$. "
f"Your ratio of {motor_counts_per_load_rev}/{units_per_load_rev}{motor_counts_per_load_rev / units_per_load_rev:.3f} "
f"is well within this safe range."
)
elif page == "Parameter Guide":
st.title("🛠️ Essential Parameter Setup")
st.write("Beyond the PUU (P1-44/45), these parameters are critical for a 50:1 gearbox system.")
st.subheader("1. The 'Big Three' for Gearbox Safety")
st.markdown(
"""
| Parameter | Name | Recommended Value | Why? |
| :--- | :--- | :--- | :--- |
| **P1-44** | Numerator (N) | *From Calculator* | Sets electronic gear / user units. |
| **P1-45** | Denominator (M) | *From Calculator* | Sets electronic gear / user units. |
| **P1-37** | Load to Motor Inertia | **10.0 ~ 20.0** | A 50:1 gearbox increases reflected inertia significantly. Start here for tuning. |
"""
)
st.subheader("2. Speed & Torque Limits")
st.info(
"With 50:1 reduction, output torque is multiplied ~50× while output speed is divided ~50×. "
"Use limits to protect mechanics during first tests."
)
st.markdown(
"""
- **P1-02 (Speed Limit):** Set to motor-rated safe speed (e.g., 3000 RPM) to prevent overspeed.
- **P1-12 / P1-13 (Torque Limit):** Start conservative (e.g., 3060%) during first motion tests to avoid smashing end-stops.
"""
)
st.divider()
st.subheader("🔄 Factory Reset (Set to Default)")
st.warning("Warning: Resetting will erase all PUU and tuning settings!")
col_a, col_b = st.columns(2)
with col_a:
st.markdown("#### Via Drive Keypad")
st.code(
"""
1. Go to Parameter P2-08.
2. Set value to 10.
3. Press 'SET'.
4. Power Cycle (Off/On).
""".strip(),
language="markdown",
)
with col_b:
st.markdown("#### Via ASDA-Soft")
st.markdown(
"""
1. Open **Parameter Editor**.
2. Click **Initial** / **Factory Default**.
3. Confirm and click **Write**.
4. Restart the Drive.
"""
)
elif page == "ASDA-Soft Guide":
st.title("💾 Implementation in ASDA-Soft")
st.markdown(
"""
To apply your **P1-44** and **P1-45** values:
1. Open **Parameter Editor**
2. Select **Group 1** (Basic Parameters)
3. Enter **P1-44** and **P1-45**
4. Click **Write to Drive**
5. **Power cycle / restart** the drive if required for the change to take effect
### Quick workflow
- Calculate PUU in the **PUU Calculator**
- Set **P1-44 / P1-45**
- Set safe limits (**P1-02**, **P1-12**, **P1-13**)
- Then tune (**P1-37** and auto-tuning if you use it)
"""
)

9
requirements.txt Normal file
View file

@ -0,0 +1,9 @@
asarPy==1.0.1
Cython==3.2.1
Mako==1.3.10.dev0
Markdown==3.10
MarkupSafe==3.0.3
meson==1.9.1
packaging==25.0
setuptools==80.9.0
wheel==0.46.1