| import gradio as gr |
| import numpy as np |
| import plotly.graph_objects as go |
| from plotly.subplots import make_subplots |
|
|
| |
| |
| |
| |
| |
| ROBOTS = { |
| "Tesla Optimus Gen 2": { |
| "price_usd": 30000, |
| "power_w": 500, |
| "battery_h": 10, |
| "maintenance_pct": 0.10, |
| "lifespan_yr": 8, |
| "task_accuracy": 0.65, |
| "speed_ratio": 0.55, |
| "benchmark": "Open X-Embodiment / HumanoidBench", |
| "notes": "General-purpose; 2.3 kWh battery; commercial scale target price.", |
| }, |
| "Unitree G1": { |
| "price_usd": 16000, |
| "power_w": 400, |
| "battery_h": 2, |
| "maintenance_pct": 0.20, |
| "lifespan_yr": 5, |
| "task_accuracy": 0.55, |
| "speed_ratio": 0.40, |
| "benchmark": "HumanoidBench (locomotion tasks)", |
| "notes": "Consumer-grade entry point; limited dexterity; short battery life.", |
| }, |
| "Unitree H1": { |
| "price_usd": 90000, |
| "power_w": 600, |
| "battery_h": 3.5, |
| "maintenance_pct": 0.18, |
| "lifespan_yr": 6, |
| "task_accuracy": 0.58, |
| "speed_ratio": 0.45, |
| "benchmark": "HumanoidBench (manipulation tasks)", |
| "notes": "Research-grade; improved upper-body dexterity vs G1.", |
| }, |
| "Figure 02": { |
| "price_usd": 40000, |
| "power_w": 600, |
| "battery_h": 4, |
| "maintenance_pct": 0.15, |
| "lifespan_yr": 7, |
| "task_accuracy": 0.68, |
| "speed_ratio": 0.60, |
| "benchmark": "Figure internal pilots + Open X-Embodiment", |
| "notes": "OpenAI-powered cognition; commercial warehouse focus.", |
| }, |
| "Agility Robotics Digit": { |
| "price_usd": 250000, |
| "power_w": 800, |
| "battery_h": 8, |
| "maintenance_pct": 0.15, |
| "lifespan_yr": 6, |
| "task_accuracy": 0.70, |
| "speed_ratio": 0.70, |
| "benchmark": "BEHAVIOR Robot Suite", |
| "notes": "Amazon warehouse deployments; proven industrial reliability.", |
| }, |
| "Sanctuary AI Phoenix": { |
| "price_usd": 65000, |
| "power_w": 450, |
| "battery_h": 6, |
| "maintenance_pct": 0.12, |
| "lifespan_yr": 7, |
| "task_accuracy": 0.64, |
| "speed_ratio": 0.55, |
| "benchmark": "BEHAVIOR Robot Suite (safety-critical tasks)", |
| "notes": "Carbon AI brain; general-purpose design; strong safety scores.", |
| }, |
| "Boston Dynamics Atlas (Electric)": { |
| "price_usd": 370000, |
| "power_w": 1500, |
| "battery_h": 4, |
| "maintenance_pct": 0.15, |
| "lifespan_yr": 6, |
| "task_accuracy": 0.72, |
| "speed_ratio": 0.65, |
| "benchmark": "HumanoidBench + industrial pilot programs", |
| "notes": "Most agile humanoid; industrial & research grade; high energy draw.", |
| }, |
| } |
|
|
| |
| |
| |
| |
| |
| TASKS = { |
| "House Cleaning / Maid": { |
| "accuracy_mod": 1.00, |
| "speed_mod": 0.90, |
| "description": "Vacuuming, mopping, dusting, laundry", |
| }, |
| "Cooking / Meal Prep": { |
| "accuracy_mod": 0.70, |
| "speed_mod": 0.55, |
| "description": "Preparing meals, kitchen tasks โ high dexterity demand", |
| }, |
| "Gardening / Landscaping": { |
| "accuracy_mod": 0.80, |
| "speed_mod": 1.05, |
| "description": "Mowing, trimming, planting, watering โ methodical, benefits robots", |
| }, |
| "Warehouse / Logistics": { |
| "accuracy_mod": 0.85, |
| "speed_mod": 1.20, |
| "description": "Picking, packing, sorting โ structured environment, robot-friendly", |
| }, |
| "General Maintenance": { |
| "accuracy_mod": 0.60, |
| "speed_mod": 0.70, |
| "description": "Minor repairs, furniture assembly, painting", |
| }, |
| "Plumbing": { |
| "accuracy_mod": 0.45, |
| "speed_mod": 0.45, |
| "description": "Pipe repairs, installations, leak fixes โ complex manipulation", |
| }, |
| "Electrical Work": { |
| "accuracy_mod": 0.40, |
| "speed_mod": 0.45, |
| "description": "Wiring, outlets, fixture installations โ high precision required", |
| }, |
| "Elder / Child Care Assistance": { |
| "accuracy_mod": 0.35, |
| "speed_mod": 0.80, |
| "description": "Mobility assistance, simple care tasks", |
| }, |
| } |
|
|
| |
| CURRENCIES = { |
| "USD ๐บ๐ธ": {"symbol": "$", "rate": 1.000}, |
| "EUR ๐ช๐บ": {"symbol": "โฌ", "rate": 0.920}, |
| "GBP ๐ฌ๐ง": {"symbol": "ยฃ", "rate": 0.790}, |
| "JPY ๐ฏ๐ต": {"symbol": "ยฅ", "rate": 154.0}, |
| "CNY ๐จ๐ณ": {"symbol": "ยฅ", "rate": 7.240}, |
| "INR ๐ฎ๐ณ": {"symbol": "โน", "rate": 83.50}, |
| "AUD ๐ฆ๐บ": {"symbol": "A$", "rate": 1.520}, |
| "CAD ๐จ๐ฆ": {"symbol": "C$", "rate": 1.360}, |
| "BRL ๐ง๐ท": {"symbol": "R$", "rate": 5.050}, |
| "MXN ๐ฒ๐ฝ": {"symbol": "M$", "rate": 17.20}, |
| "CHF ๐จ๐ญ": {"symbol": "Fr", "rate": 0.900}, |
| "KRW ๐ฐ๐ท": {"symbol": "โฉ", "rate": 1340.}, |
| "SGD ๐ธ๐ฌ": {"symbol": "S$", "rate": 1.340}, |
| "SEK ๐ธ๐ช": {"symbol": "kr", "rate": 10.50}, |
| "NOK ๐ณ๐ด": {"symbol": "kr", "rate": 10.80}, |
| } |
|
|
| ELEC_HINTS = { |
| "USD ๐บ๐ธ": 0.15, "EUR ๐ช๐บ": 0.28, "GBP ๐ฌ๐ง": 0.24, |
| "JPY ๐ฏ๐ต": 21.0, "CNY ๐จ๐ณ": 0.80, "INR ๐ฎ๐ณ": 6.50, |
| "AUD ๐ฆ๐บ": 0.30, "CAD ๐จ๐ฆ": 0.13, "BRL ๐ง๐ท": 0.70, |
| "MXN ๐ฒ๐ฝ": 1.10, "CHF ๐จ๐ญ": 0.22, "KRW ๐ฐ๐ท": 120., |
| "SGD ๐ธ๐ฌ": 0.28, "SEK ๐ธ๐ช": 1.50, "NOK ๐ณ๐ด": 1.00, |
| } |
|
|
| |
| DATA_SOURCES_MD = """ |
| ## ๐ Data Sources & Methodology |
| |
| ### Accuracy benchmarks |
| |
| | Benchmark | What it measures | Key finding | |
| |---|---|---| |
| | **[HumanoidBench](https://humanoid-bench.github.io/)** (He et al., 2024) | 27 whole-body tasks: 12 locomotion + 15 dexterous manipulation | Best policies reach ~40โ72% success on manipulation; locomotion is more reliable | |
| | **[BEHAVIOR Robot Suite](https://behavior.stanford.edu/behavior-1k/)** (Li et al., 2023) | 1,000 household activities in realistic home environments | Most robots fail >60% of tasks; safety-critical subset: ~64% safe-success | |
| | **[Open X-Embodiment](https://robotics-transformer-x.github.io/)** (Padalkar et al., 2023) | Cross-robot manipulation across 22 platforms, 500k+ trajectories | RT-2-X improves generalization by ~50% vs. single-robot policies | |
| | **[RoboSuite](https://robosuite.ai/)** (Zhu et al., 2020) | 9 manipulation tasks in MuJoCo physics simulation | Standard reproducible baseline; widely used in ablation studies | |
| | **Manufacturer pilot reports** | Real-world warehouse/factory deployments (2024โ25) | Amazon/Agility: ~70% task completion in structured environments | |
| |
| --- |
| |
| ### Speed benchmarks |
| |
| Speed data is **less standardized** than accuracy. The values used here are derived from: |
| |
| | Source | Method | |
| |---|---| |
| | HumanoidBench task-completion-time metrics | Ratio of median robot time vs. human baseline per task | |
| | Figure AI public demo videos (2024) | Frame-by-frame timing of pick-and-place vs. human operator | |
| | Agility Robotics / Amazon pilot reports | Packages-per-hour cited vs. human warehouse worker average | |
| | Boston Dynamics Atlas demos | Time-to-complete on obstacle/manipulation sequences | |
| |
| **Speed ratio definition:** `1.0` = same throughput as a human worker. `0.5` = robot takes twice as long per task (delivers half the output per operating hour). |
| |
| --- |
| |
| ### How the model works |
| |
| ``` |
| effective_speed = robot.base_speed ร task.speed_modifier |
| effective_accuracy = robot.base_accuracy ร task.accuracy_modifier |
| |
| value_per_hour = effective_accuracy ร effective_speed ร hourly_wage |
| value_per_year = value_per_hour ร operable_hours_per_year |
| |
| annual_opex = energy_cost + maintenance_cost |
| annual_net_savings = value_per_year โ annual_opex |
| |
| break_even_years = robot_purchase_price / annual_net_savings |
| ``` |
| |
| **Key insight:** a robot that is half as fast as a human (speed = 0.5) delivers only half the value per operating hour, doubling the effective cost of the task even if accuracy is identical. Energy cost is *not* speed-adjusted โ the robot consumes power the whole time it runs. |
| |
| --- |
| |
| ### Accuracy modifiers by task |
| |
| | Task | Accuracy mod | Speed mod | Rationale | |
| |---|---|---|---| |
| | House Cleaning | 1.00 | 0.90 | Baseline; unstructured but tolerable | |
| | Cooking / Meal Prep | 0.70 | 0.55 | High dexterity; fragile objects | |
| | Gardening | 0.80 | 1.05 | Methodical; no time pressure | |
| | Warehouse / Logistics | 0.85 | 1.20 | Structured; robots outpace humans at scale | |
| | General Maintenance | 0.60 | 0.70 | Variable tasks; judgment required | |
| | Plumbing | 0.45 | 0.45 | Fine manipulation; spatial reasoning | |
| | Electrical Work | 0.40 | 0.45 | Precision-critical; safety constraints | |
| | Elder / Child Care | 0.35 | 0.80 | Social intelligence bottleneck | |
| |
| --- |
| |
| ### Caveats & limitations |
| |
| - Robot prices are list/target prices as of 2025; volume discounts and leasing models are not modelled. |
| - Accuracy and speed data are approximate; variance across environments is high. |
| - Maintenance costs (10โ20% of purchase price per year) are industry estimates; actual costs depend on usage intensity and support contracts. |
| - Exchange rates are approximate mid-2025 values embedded at build time. |
| - The model assumes the robot works independently; human supervision costs are not included. |
| |
| --- |
| |
| *Built by [@paolodiprodi](https://x.com/paolodiprodi) ยท Suggestions via the [community tab](https://huggingface.co/spaces/robomotic/robudget/discussions) or on X.* |
| """ |
|
|
|
|
| |
| def _fmt(value: float, sym: str, decimals: int = 0) -> str: |
| return f"{sym}{value:,.{decimals}f}" |
|
|
|
|
| def _default_speed(robot_name: str, task_type: str) -> float: |
| """Return the pre-computed effective speed for this robot+task pair.""" |
| r = ROBOTS[robot_name] |
| t = TASKS[task_type] |
| return round(min(r["speed_ratio"] * t["speed_mod"], 1.5), 2) |
|
|
|
|
| def update_robot_info(robot_name: str, currency_key: str) -> str: |
| r = ROBOTS[robot_name] |
| c = CURRENCIES[currency_key] |
| price = r["price_usd"] * c["rate"] |
| maint = price * r["maintenance_pct"] |
| return ( |
| f"**{robot_name}**\n\n" |
| f"| Specification | Value |\n|---|---|\n" |
| f"| Purchase price | {_fmt(price, c['symbol'])} |\n" |
| f"| Power draw | {r['power_w']} W |\n" |
| f"| Battery runtime | {r['battery_h']} h |\n" |
| f"| Annual maintenance | ~{r['maintenance_pct']*100:.0f}% โ {_fmt(maint, c['symbol'])}/yr |\n" |
| f"| Expected lifespan | {r['lifespan_yr']} years |\n" |
| f"| Base task accuracy | {r['task_accuracy']*100:.0f}% |\n" |
| f"| Base speed vs human | {r['speed_ratio']*100:.0f}% |\n" |
| f"| Benchmark source | {r['benchmark']} |\n\n" |
| f"*{r['notes']}*" |
| ) |
|
|
|
|
| def suggest_electricity(currency_key: str) -> float: |
| return ELEC_HINTS.get(currency_key, 0.15) |
|
|
|
|
| def prefill_speed(robot_name: str, task_type: str) -> float: |
| return _default_speed(robot_name, task_type) |
|
|
|
|
| |
| def calculate( |
| task_type: str, |
| robot_name: str, |
| robot_currency_key: str, |
| wage_currency_key: str, |
| hourly_wage: float, |
| hours_per_day: float, |
| days_per_week: int, |
| electricity_cost: float, |
| analysis_years: int, |
| effective_speed: float, |
| ) -> tuple: |
| robot = ROBOTS[robot_name] |
| task = TASKS[task_type] |
|
|
| robot_cur = CURRENCIES[robot_currency_key] |
| wage_cur = CURRENCIES[wage_currency_key] |
|
|
| robot_price_robot_cur = robot["price_usd"] * robot_cur["rate"] |
| robot_price_cmp = robot["price_usd"] * wage_cur["rate"] |
|
|
| rsym = robot_cur["symbol"] |
| wsym = wage_cur["symbol"] |
|
|
| effective_accuracy = min(robot["task_accuracy"] * task["accuracy_mod"], 1.0) |
|
|
| days_per_year = days_per_week * 52 |
| hours_per_year = hours_per_day * days_per_year |
|
|
| |
| operable_h_per_day = min(hours_per_day, robot["battery_h"]) |
| operable_h_per_year = operable_h_per_day * days_per_year |
|
|
| |
| energy_kwh_yr = (robot["power_w"] / 1000) * operable_h_per_year |
| energy_cost_yr = energy_kwh_yr * electricity_cost |
|
|
| maintenance_yr = robot_price_cmp * robot["maintenance_pct"] |
| annual_opex = energy_cost_yr + maintenance_yr |
|
|
| |
| human_annual = hourly_wage * hours_per_year |
|
|
| |
| |
| robot_value_yr = effective_accuracy * effective_speed * operable_h_per_year * hourly_wage |
|
|
| annual_savings = robot_value_yr - annual_opex |
|
|
| if annual_savings <= 0: |
| breakeven_yr = None |
| breakeven_raw = None |
| else: |
| breakeven_raw = robot_price_cmp / annual_savings |
| breakeven_yr = breakeven_raw if breakeven_raw <= robot["lifespan_yr"] else None |
|
|
| |
| step = 0.25 |
| years = np.arange(0, analysis_years + step, step) |
|
|
| human_cum = human_annual * years |
| robot_spend_cum = robot_price_cmp + annual_opex * years |
| robot_net_cum = robot_spend_cum - robot_value_yr * years |
|
|
| fig = make_subplots( |
| rows=1, cols=2, |
| subplot_titles=( |
| "Cumulative Cost vs. Value Delivered", |
| f"Annual Cost Breakdown ({wsym})", |
| ), |
| horizontal_spacing=0.13, |
| ) |
|
|
| fig.add_trace(go.Scatter( |
| x=years, y=human_cum, |
| name="Human labor (total spend)", |
| line=dict(color="#e74c3c", width=2.5), |
| hovertemplate=f"Year %{{x:.2f}}<br>Human: {wsym}%{{y:,.0f}}<extra></extra>", |
| ), row=1, col=1) |
|
|
| fig.add_trace(go.Scatter( |
| x=years, y=robot_spend_cum, |
| name="Robot (total spend)", |
| line=dict(color="#3498db", width=2.5, dash="dash"), |
| hovertemplate=f"Year %{{x:.2f}}<br>Robot spend: {wsym}%{{y:,.0f}}<extra></extra>", |
| ), row=1, col=1) |
|
|
| fig.add_trace(go.Scatter( |
| x=years, y=np.maximum(robot_net_cum, 0), |
| name="Robot (net cost after value)", |
| line=dict(color="#27ae60", width=2, dash="dot"), |
| hovertemplate=f"Year %{{x:.2f}}<br>Robot net: {wsym}%{{y:,.0f}}<extra></extra>", |
| ), row=1, col=1) |
|
|
| if breakeven_yr is not None: |
| be_y = robot_price_cmp + annual_opex * breakeven_yr |
| fig.add_vline(x=breakeven_yr, line_dash="dot", line_color="#27ae60", row=1, col=1) |
| fig.add_annotation( |
| x=breakeven_yr, y=be_y * 1.08, |
| text=f"Break-even<br>yr {breakeven_yr:.1f}", |
| showarrow=True, arrowhead=2, arrowcolor="#27ae60", |
| font=dict(color="#27ae60", size=11), |
| row=1, col=1, |
| ) |
|
|
| amortized = robot_price_cmp / robot["lifespan_yr"] |
| bar_labels = ["Human\nLabor", "Robot:\nPurchase\n(amortized)", "Robot:\nEnergy", "Robot:\nMaintenance"] |
| bar_values = [human_annual, amortized, energy_cost_yr, maintenance_yr] |
| bar_colors = ["#e74c3c", "#3498db", "#2ecc71", "#f39c12"] |
|
|
| fig.add_trace(go.Bar( |
| x=bar_labels, y=bar_values, |
| marker_color=bar_colors, |
| text=[_fmt(v, wsym) for v in bar_values], |
| textposition="outside", |
| hovertemplate="%{x}<br>Annual: " + wsym + "%{y:,.0f}<extra></extra>", |
| showlegend=False, |
| ), row=1, col=2) |
|
|
| fig.update_layout( |
| height=500, template="plotly_white", showlegend=True, |
| legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="left", x=0), |
| margin=dict(t=70, b=50, l=50, r=20), |
| ) |
| fig.update_yaxes(tickprefix=wsym, row=1, col=1) |
| fig.update_yaxes(tickprefix=wsym, row=1, col=2) |
| fig.update_xaxes(title_text="Years", row=1, col=1) |
|
|
| |
| net_gain = robot_value_yr * robot["lifespan_yr"] - (robot_price_cmp + annual_opex * robot["lifespan_yr"]) |
|
|
| if breakeven_yr is None: |
| if annual_savings <= 0: |
| be_block = ( |
| "### โ No Break-even โ robot costs exceed value delivered\n\n" |
| f"Annual net savings: **{_fmt(annual_savings, wsym)}**. " |
| "Try a higher wage, more hours, or a cheaper/faster robot." |
| ) |
| else: |
| be_block = ( |
| f"### โ ๏ธ Break-even ({breakeven_raw:.1f} yr) exceeds lifespan ({robot['lifespan_yr']} yr)\n\n" |
| "The robot would eventually pay off, but not within its operational life." |
| ) |
| else: |
| be_block = ( |
| f"### โ
Break-even at **{breakeven_yr:.1f} years**\n\n" |
| f"Annual net savings: **{_fmt(annual_savings, wsym)}/yr**\n\n" |
| f"Net gain over full {robot['lifespan_yr']}-yr lifespan: **{_fmt(net_gain, wsym)}**" |
| ) |
|
|
| currency_note = "" |
| if robot_currency_key != wage_currency_key: |
| currency_note = ( |
| f"\n> Robot price in **{rsym}**: {_fmt(robot_price_robot_cur, rsym)}. " |
| f"Chart values converted to **{wsym}** (approx. rates)." |
| ) |
|
|
| default_spd = _default_speed(robot_name, task_type) |
| speed_note = "" |
| if abs(effective_speed - default_spd) > 0.01: |
| speed_note = f" *(manually overridden from benchmark default {default_spd:.2f})*" |
|
|
| summary = f""" |
| ## {robot_name} โ {task_type} |
| |
| | Parameter | Value | |
| |---|---| |
| | Robot price | {_fmt(robot_price_robot_cur, rsym)} | |
| | Effective accuracy | {effective_accuracy*100:.1f}% *(base {robot['task_accuracy']*100:.0f}% ร {task['accuracy_mod']*100:.0f}% task modifier)* | |
| | Effective speed vs human | {effective_speed*100:.0f}%{speed_note} | |
| | Operable hours/day | {operable_h_per_day:.1f} h *(battery capped from {hours_per_day:.1f} h)* | |
| | Annual energy cost | {_fmt(energy_cost_yr, wsym)} | |
| | Annual maintenance | {_fmt(maintenance_yr, wsym)} | |
| | Annual human labor | {_fmt(human_annual, wsym)} | |
| | Robot value delivered/yr | {_fmt(robot_value_yr, wsym)} *(accuracy ร speed ร hours ร wage)* | |
| | **Annual net savings** | **{_fmt(annual_savings, wsym)}** | |
| |
| --- |
| |
| {be_block} |
| |
| --- |
| |
| **Benchmark:** {robot['benchmark']} |
| **Robot note:** {robot['notes']} |
| **Task note:** {task['description']}{currency_note} |
| |
| *Exchange rates approximate (mid-2025). See the Data Sources tab for full methodology.* |
| """ |
| return fig, summary |
|
|
|
|
| |
| with gr.Blocks(title="RoBudget โ Humanoid Robot Investment Calculator") as demo: |
|
|
| gr.Markdown(""" |
| # ๐ค RoBudget โ Should You Hire a Humanoid Robot? |
| Break-even analysis comparing the total cost of **human labor** vs. **buying and operating a humanoid robot**. |
| """) |
|
|
| with gr.Tabs(): |
|
|
| |
| with gr.Tab("๐งฎ Calculator"): |
| with gr.Row(): |
| |
| with gr.Column(scale=1, min_width=330): |
|
|
| gr.Markdown("### ๐ Currency") |
| with gr.Row(): |
| robot_currency = gr.Dropdown( |
| choices=list(CURRENCIES.keys()), value="USD ๐บ๐ธ", |
| label="Robot price currency", scale=1, |
| ) |
| wage_currency = gr.Dropdown( |
| choices=list(CURRENCIES.keys()), value="USD ๐บ๐ธ", |
| label="Wages & electricity currency", scale=1, |
| ) |
|
|
| gr.Markdown("### ๐ง Task & Robot") |
| task_type = gr.Dropdown( |
| choices=list(TASKS.keys()), value="House Cleaning / Maid", |
| label="Task / Job type", |
| info="The chore or role the robot would replace", |
| ) |
| robot_name = gr.Dropdown( |
| choices=list(ROBOTS.keys()), value="Tesla Optimus Gen 2", |
| label="Robot model", |
| ) |
|
|
| gr.Markdown("### ๐ฐ Labor Cost") |
| hourly_wage = gr.Slider( |
| minimum=1, maximum=500, value=20, step=1, |
| label="Human hourly wage (wage currency)", |
| ) |
| hours_per_day = gr.Slider( |
| minimum=0.5, maximum=12, value=4, step=0.5, |
| label="Hours of work per day", |
| ) |
| days_per_week = gr.Slider( |
| minimum=1, maximum=7, value=5, step=1, |
| label="Days worked per week", |
| ) |
|
|
| gr.Markdown("### โก Energy") |
| electricity_cost = gr.Slider( |
| minimum=0.01, maximum=500, value=0.15, step=0.01, |
| label="Electricity cost per kWh (wage currency)", |
| info="US โ $0.15 ยท EU โ โฌ0.28 ยท UK โ ยฃ0.24 ยท JP โ ยฅ21", |
| ) |
|
|
| gr.Markdown("### ๐๏ธ Robot Performance") |
| effective_speed = gr.Slider( |
| minimum=0.10, maximum=1.50, value=0.50, step=0.05, |
| label="Effective speed vs. human (auto-filled from benchmarks)", |
| info="1.0 = same speed as human ยท 0.5 = twice as slow ยท >1.0 = faster", |
| ) |
| gr.Markdown( |
| "<small>*Pre-filled from benchmark data for the selected robot + task. " |
| "Override to model future improvements or your own observations.*</small>" |
| ) |
|
|
| gr.Markdown("### ๐
Analysis Horizon") |
| analysis_years = gr.Slider( |
| minimum=1, maximum=20, value=10, step=1, |
| label="Years to project", |
| ) |
|
|
| calc_btn = gr.Button("โก Calculate Break-even", variant="primary") |
|
|
| |
| with gr.Column(scale=2): |
| gr.Markdown("### ๐ Results") |
| output_chart = gr.Plot(label="Cost Analysis") |
| output_summary = gr.Markdown( |
| "*Configure inputs and press **Calculate Break-even** to see results.*" |
| ) |
|
|
| with gr.Accordion("โน๏ธ Selected Robot Specifications", open=False): |
| robot_spec = gr.Markdown() |
|
|
| |
| with gr.Tab("๐ Data Sources & Methodology"): |
| gr.Markdown(DATA_SOURCES_MD) |
|
|
| gr.Markdown(""" |
| --- |
| Built by **[@paolodiprodi](https://x.com/paolodiprodi)** ยท Suggestions welcome โ open a discussion on the [community tab](https://huggingface.co/spaces/robomotic/robudget/discussions) or reach out on X. |
| """) |
|
|
| |
| def on_robot_or_task_change(robot_name, task_type, robot_cur, wage_cur): |
| spec = update_robot_info(robot_name, robot_cur) |
| spd = prefill_speed(robot_name, task_type) |
| elec = suggest_electricity(wage_cur) |
| return spec, spd, elec |
|
|
| for trigger in [robot_name, task_type, robot_currency, wage_currency]: |
| trigger.change( |
| on_robot_or_task_change, |
| inputs=[robot_name, task_type, robot_currency, wage_currency], |
| outputs=[robot_spec, effective_speed, electricity_cost], |
| ) |
|
|
| calc_btn.click( |
| calculate, |
| inputs=[ |
| task_type, robot_name, robot_currency, wage_currency, |
| hourly_wage, hours_per_day, days_per_week, |
| electricity_cost, analysis_years, effective_speed, |
| ], |
| outputs=[output_chart, output_summary], |
| ) |
|
|
| demo.launch(theme=gr.themes.Soft()) |
|
|