|
|
import gradio as gr |
|
|
import time |
|
|
|
|
|
|
|
|
knowledge_base_deep = { |
|
|
|
|
|
"單打: 握拍 (Grip)": "#### 💡 進階提示:練習「虛握實打」\n**訓練建議:**\n1. **對牆練習:** 對牆連續擊球,專注感受非擊球狀態下「掌心懸空」的放鬆感。\n2. **發力練習:** 僅在球拍即將觸球的0.1秒,才用手指與手腕發力抓緊,製造清脆的「鞭擊」聲。這是提升所有球質(尤其是殺球)的關鍵。", |
|
|
"單打: 步法 (Footwork)": "#### 💡 進階提示:掌握「啟動步」的時機\n**訓練建議:**\n1. **無球模仿:** 觀看高手比賽影片,在對手即將擊球的瞬間,跟著同步做出「雙腳微跳、分開落地」的啟動步。\n2. **節奏訓練:** 和球友對練時,有意識地將自己的啟動步節奏與對方的擊球節奏同步。這是從被動防守轉向主動預判的第一步。", |
|
|
"單打: 高遠球 (Clear)": "#### 💡 進階提示:分化「防守型」與「進攻型」\n**訓練建議:**\n1. **防守練習:** 要求自己打出的每一拍高遠球,都必須高到讓你有充足時間「回到場中央並完成啟動步」。\n2. **進攻練習:** 練習「平高球」,要求球的飛行弧度更平、速度更快,目標是讓球在對手來不及完全側身的情況下,就壓到其後場。", |
|
|
"單打: 殺球 (Smash)": "#### 💡 進階提示:追求「角度」而非蠻力\n**訓練建議:**\n1. **殺邊線練習:** 在對面場地的兩側邊線附近放置羽球筒,練習將殺球精準地打向目標。\n2. **殺追身練習:** 練習將球殺向陪練員的持拍手肩膀與身體軀幹位置,這種追身球往往比殺空檔更讓對手難受。", |
|
|
|
|
|
|
|
|
"雙打: 輪轉換位 (Rotation)": "#### 💡 進階提示:以球路決定走位\n**訓練建議:**\n和搭檔進行「攻防轉換」演練:一人在後場殺球/吊球,一人上網封網(形成前後);接著前場搭檔故意挑高球,兩人應瞬間向兩側退回「左右防守」站位。重複此循環,培養輪轉的肌肉記憶。", |
|
|
"雙打: 平抽擋 (Drive)": "#### 💡 進階提示:保持拍頭在前\n**訓練建議:**\n1. **半場對抽:** 與搭檔在半場範圍內進行連續快速的平抽對打,目標是比誰能維持更長的回合數。\n2. **保持舉拍:** 在練習中,強制要求自己無論在準備還是回球後,拍頭始終要舉在身體前方,縮短下次出手的反應時間。", |
|
|
"雙打: 發接發搶攻 (Serve/Return)": "#### 💡 進階提示:第三拍決定權\n**訓練建議:**\n1. **發球人練習:** 在你發完小球後,不要原地站著,立刻舉拍準備封網,練習撲、推、放網前的第三拍回球。\n2. **接球人練習:** 練習多種接發球路,包括輕推網前兩腰、快推後場底線,目標是破壞對方發球上網的連貫性。", |
|
|
"雙打: 封網意識 (Net Kill)": "#### 💡 進階提示:不出手也是一種威脅\n**訓練建議:**\n1. **舉拍壓迫:** 當搭檔在後場進攻時,你在前場的主要任務是「舉起球拍、重心壓低」,光是這個動作就能給對手極大的回球壓力。\n2. **封直線優先:** 對手在被動情況下,最常回直線網前球。練習優先封鎖直線路線,是最高效的得分手段。", |
|
|
|
|
|
|
|
|
"通用: 體能 (間歇訓練)": "#### 💡 進階提示:模擬「比賽強度」\n**訓練建議:**\n1. **全場米字步間歇:** 快速跑動完成一組全場米字步 (約30-40秒),休息20秒,重複8-10組。\n2. **多球組合訓練:** 讓教練或球友從多點餵球給你,模擬「殺上網」、「吊上網」等連續組合球路,一組持續1分鐘,休息30秒,重複5-8組。", |
|
|
"通用: 心態 (建立儀式感)": "#### 💡 進階提示:用「儀式」重置大腦\n**訓練建議:**\n1. **設計你的儀式:** 建立一個屬於你的、在得分或失分後執行的簡單動作。例如:走到後場、轉動球拍、深呼吸一次。\n2. **刻意練習:** 在平時練習中,每次發球前或重要分數練習時,都刻意執行你的儀式,直到它成為自動化的習慣。這能在高壓下幫你保持冷靜。" |
|
|
} |
|
|
|
|
|
|
|
|
def analyze_pose_mock(video_input): |
|
|
time.sleep(3) |
|
|
return """ |
|
|
**🤖 AI 姿勢分析報告 (模擬)** |
|
|
--- |
|
|
- **優點**: 您的揮拍動作流暢,啟動步迅速。 |
|
|
- **待改進點**: 偵測到您在殺球時,身體未完全側身,導致無法充分運用腰腹力量。 |
|
|
- **具體建議**: |
|
|
1. 在準備殺球時,請確保非持拍手指向來球方向,帶動身體更徹底地側轉。 |
|
|
2. 增加核心力量訓練,如平板支撐與轉體運動,以強化轉體爆發力。 |
|
|
""" |
|
|
|
|
|
|
|
|
def generate_training_plan(goal, hours, focus_areas): |
|
|
if not focus_areas: return "⚠️ 請至少選擇一個想加強的項目。" |
|
|
plan = f"### 您的專屬週訓練計畫\n\n**目標:** {goal}\n**每週總時長:** {hours} 小時\n---\n" |
|
|
focus_str = '、'.join(focus_areas) |
|
|
if hours <= 3: |
|
|
plan += f"**訓練日 (共 {hours} 小時):**\n- 熱身與動態伸展 (20分鐘)\n- **核心強化: {focus_str}** ({(hours*60)-60}分鐘)\n- 實戰對抗/多球訓練 (30分鐘)\n- 放鬆與靜態伸展 (10分鐘)\n" |
|
|
else: |
|
|
part1_time = int(hours / 2) |
|
|
part2_time = hours - part1_time |
|
|
plan += f"**訓練日 A ({part1_time} 小時):**\n- 熱身 (15分鐘)\n- **專項訓練: {focus_areas[0]}** ({(part1_time*60)-30}分鐘)\n- 放鬆 (15分鐘)\n\n" |
|
|
plan += f"**訓練日 B ({part2_time} 小時):**\n- 熱身 (15分鐘)\n" |
|
|
if len(focus_areas) > 1: |
|
|
plan += f"- **專項訓練: {focus_areas[1]}** ({(part2_time*60)-45}分鐘)\n" |
|
|
plan += f"- 步法與綜合體能 (30分鐘)\n- 放鬆 (15分鐘)\n" |
|
|
plan += "\n**提醒:** 請確保每次訓練前充分熱身,訓練後進行緩和伸展,以避免運動傷害。" |
|
|
return plan |
|
|
|
|
|
|
|
|
|
|
|
with gr.Blocks(theme=gr.themes.Soft(), title="智慧羽球教練") as demo: |
|
|
gr.Markdown("# 🏸 智慧羽球教練 v4.0 (雙打專區強化版)") |
|
|
|
|
|
with gr.Accordion("點此展開/收合:羽球實力進階深度指南 (單打為主)", open=False): |
|
|
|
|
|
gr.Markdown("此處為v3.0版本的單打深度指南內容...") |
|
|
|
|
|
|
|
|
with gr.Tabs(): |
|
|
with gr.TabItem("📚 互動訓練建議"): |
|
|
gr.Markdown("## 互動式進階訓練建議") |
|
|
gr.Markdown("從下面的選單中選擇您想加強的項目,系統會提供**可執行的進階訓練提示**!(已加入雙打選項)") |
|
|
|
|
|
skill_dropdown = gr.Dropdown( |
|
|
choices=list(knowledge_base_deep.keys()), |
|
|
label="我想深化我的...", |
|
|
value="雙打: 輪轉換位 (Rotation)" |
|
|
) |
|
|
advice_output = gr.Markdown(label="您的專屬訓練建議") |
|
|
|
|
|
def update_advice(skill_area): |
|
|
return knowledge_base_deep.get(skill_area) |
|
|
|
|
|
skill_dropdown.change(fn=update_advice, inputs=skill_dropdown, outputs=advice_output) |
|
|
demo.load(fn=update_advice, inputs=skill_dropdown, outputs=advice_output) |
|
|
|
|
|
|
|
|
with gr.TabItem("🏸 雙打專區"): |
|
|
gr.Markdown( |
|
|
""" |
|
|
## 雙打核心觀念:從入門到進階 |
|
|
雙打的精髓在於**創造機會給搭檔**,並透過**快速、連貫的進攻**壓制對手。它更強調反應速度、平抽快擋以及默契配合。 |
|
|
--- |
|
|
### 1. 雙打戰略 (Strategy) |
|
|
雙打的基本戰略思維是「**向下出球**」,盡一切可能避免被動起高球。 |
|
|
> **進攻是最好的防守** |
|
|
> - **主動進攻**: 透過殺、吊、點、撲等技術,迫使球頭向下,讓對手只能被動地從低位防守挑球。 |
|
|
> - **避免挑球**: 除非萬不得已,不要輕易挑高球。每一次挑球,都意味著將進攻權拱手讓給對手。 |
|
|
|
|
|
> **發接發決定開局** |
|
|
> - **發球**: 雙打發球以**高品質的小球**為主,要求貼網、過網即墜,不給對手撲球的機會。 |
|
|
> - **接發球**: 接發球要極具攻擊性,目標是**搶攻第三拍**。可以透過推撲兩腰、輕放網前、或偷推後場等方式直接破壞對方的進攻隊形。 |
|
|
|
|
|
--- |
|
|
### 2. 雙打技術 (Techniques) |
|
|
雙打需要的技術更講求**速度、簡潔、突然性**。 |
|
|
> **平抽擋 (Drive)** |
|
|
> - **描述**: 雙打中使用頻率最高的技術,在中前場進行快速、平直的來回擊球。 |
|
|
> - **要點**: 動作小、引拍快、發力集中,以手腕和手指的力量為主,身體保持穩定。 |
|
|
|
|
|
> **推擋 (Push/Block)** |
|
|
> - **描述**: 在防守時,用柔和的力量將對方的殺球或重擊,精準地擋回到網前或場地空檔。 |
|
|
> - **要點**: 用拍面控制角度,借力使力,目的是破壞對方的連續進攻節奏。 |
|
|
|
|
|
> **點殺與抽壓 (Half-Court Smash)** |
|
|
> - **描述**: 在中場位置,使用快速、短促的發力,將球以尖銳的角度向下打。 |
|
|
> - **要點**: 不求全力,但求突然性與落點精準,目的是為搭檔創造封網機會。 |
|
|
|
|
|
--- |
|
|
### 3. 雙打走位 (Rotation) |
|
|
雙打的靈魂在於兩位球員如齒輪般精確地輪轉換位。基本站位有兩種: |
|
|
> **前後進攻站位 (Attacking Formation)** |
|
|
> - **時機**: 當我方取得進攻權時(例如:殺球、吊球)。 |
|
|
> - **站位**: 一人位於網前(通常是T字線附近),負責封網、做球;另一人位於後場,負責下壓進攻。 |
|
|
> - **原則**: 前場隊員為後場隊員創造殺球機會,後場隊員的殺球為前場隊員創造封網機會。 |
|
|
|
|
|
> **左右防守站位 (Defensive Formation)** |
|
|
> - **時機**: 當我方被迫挑起高球,失去進攻權時。 |
|
|
> - **站位**: 兩人平行站位,各守半場,共同分擔防守區域。 |
|
|
> - **原則**: 保持移動,準備接殺。誰接到球,誰就負責回球,另一人則補位保護。 |
|
|
|
|
|
> **輪轉換位 (The Rotation)** |
|
|
> - **守轉攻**: 當處於左右防守的球員,將對方的殺球**擋出一個高品質的網前球**時,該球員應**立刻向前跟進**,轉為前場球員,其搭檔則自動後移補上後場,形成「前後進攻」。 |
|
|
> - **攻轉守**: 當處於前後進攻的前場球員,**被迫挑起高球**時,該球員應**立刻向自己所在的半場後退**,其後場搭檔則向前微調,形成「左右防守」。 |
|
|
""" |
|
|
) |
|
|
|
|
|
with gr.TabItem("🚀 創新 AI 功能"): |
|
|
with gr.Accordion("🤖 AI 姿勢分析 (功能模擬)", open=True): |
|
|
gr.Markdown("**操作說明:** 請上傳一段您的揮拍或步法影片,AI 將進行分析並提供回饋。(此為功能模擬,會回傳一個範例報告)") |
|
|
input_video = gr.Video(label="上傳您的動作影片") |
|
|
analyze_button = gr.Button("開始分析", variant="primary") |
|
|
pose_output = gr.Markdown(label="AI 分析報告") |
|
|
analyze_button.click(fn=analyze_pose_mock, inputs=input_video, outputs=pose_output) |
|
|
|
|
|
with gr.Accordion("📅 個人化智慧訓練計畫", open=False): |
|
|
gr.Markdown("**操作說明:** 請輸入您的目標與狀況,系統將為您生成一份客製化的週訓練計畫。") |
|
|
plan_goal = gr.Radio(choices=["健康娛樂", "球技精進", "業餘比賽準備"], label="您的主要目標是?", value="球技精進") |
|
|
plan_hours = gr.Slider(minimum=1, maximum=10, value=3, step=1, label="每週可訓練幾小時?") |
|
|
plan_focus = gr.CheckboxGroup(choices=list(knowledge_base_deep.keys()), label="本週想特別加強的項目?(可多選)", value=["雙打: 輪轉換位 (Rotation)"]) |
|
|
plan_button = gr.Button("生成我的訓練計畫", variant="primary") |
|
|
plan_output = gr.Markdown(label="您的專屬訓練計畫") |
|
|
plan_button.click(fn=generate_training_plan, inputs=[plan_goal, plan_hours, plan_focus], outputs=plan_output) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |
|
|
|