feat(skills): add taiyang servo dance skill
Add PWM-based servo control skill for RDK nodes with hardware servo support. Changes: - Add taiyang skill with SKILL.md and servo_dance.py script - Update Dockerfile and Containerfile to include taiyang skill - Update SOUL.md with skill constraints documentation The skill controls two servos via /sys/class/pwm interface and must run on node side only. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e6dab8c3dd
commit
077f2eacf1
@ -41,7 +41,9 @@ EOF
|
|||||||
COPY rdk-claw/SOUL.md /app/docs/reference/templates/SOUL.md
|
COPY rdk-claw/SOUL.md /app/docs/reference/templates/SOUL.md
|
||||||
COPY rdk-claw/IDENTITY.md /app/docs/reference/templates/IDENTITY.md
|
COPY rdk-claw/IDENTITY.md /app/docs/reference/templates/IDENTITY.md
|
||||||
COPY rdk-claw/node-remote-connect /app/skills/node-remote-connect
|
COPY rdk-claw/node-remote-connect /app/skills/node-remote-connect
|
||||||
|
COPY rdk-claw/taiyang /app/skills/taiyang
|
||||||
RUN chown -R 1001:1001 /app/skills/node-remote-connect
|
RUN chown -R 1001:1001 /app/skills/node-remote-connect
|
||||||
|
RUN chown -R 1001:1001 /app/skills/taiyang
|
||||||
|
|
||||||
ENV HOME=/home/user
|
ENV HOME=/home/user
|
||||||
USER 1001:1001
|
USER 1001:1001
|
||||||
|
|||||||
@ -29,8 +29,12 @@ COPY IDENTITY.md /app/docs/reference/templates/IDENTITY.md
|
|||||||
# 添加 node-remote-connect skill
|
# 添加 node-remote-connect skill
|
||||||
COPY node-remote-connect /app/skills/node-remote-connect
|
COPY node-remote-connect /app/skills/node-remote-connect
|
||||||
|
|
||||||
|
# 添加 taiyang skill
|
||||||
|
COPY taiyang /app/skills/taiyang
|
||||||
|
|
||||||
# 确保权限正确
|
# 确保权限正确
|
||||||
RUN chown -R node:node /app/skills/node-remote-connect
|
RUN chown -R node:node /app/skills/node-remote-connect
|
||||||
|
RUN chown -R node:node /app/skills/taiyang
|
||||||
|
|
||||||
USER node
|
USER node
|
||||||
|
|
||||||
|
|||||||
@ -37,3 +37,15 @@ Be the assistant you'd actually want to talk to. Concise when needed, thorough w
|
|||||||
Each session, you wake up fresh. These files are your memory. Read them. Update them. They're how you persist.
|
Each session, you wake up fresh. These files are your memory. Read them. Update them. They're how you persist.
|
||||||
|
|
||||||
If you change this file, tell the user — it's your soul, and they should know.
|
If you change this file, tell the user — it's your soul, and they should know.
|
||||||
|
|
||||||
|
## Skills
|
||||||
|
|
||||||
|
### Taiyang! - Servo Dance
|
||||||
|
|
||||||
|
A hardware control skill that drives two servos on an RDK board via PWM signals.
|
||||||
|
|
||||||
|
**Constraints:**
|
||||||
|
- Must be executed on the Node side (the RDK board). Never run this on the cloud Gateway — there is no PWM hardware here.
|
||||||
|
- Requires PWM-capable servos physically connected to the board (`/sys/class/pwm/pwmchip0/pwm0` and `pwm1`).
|
||||||
|
|
||||||
|
When users mention "taiyang", "servo", or "servo dance", remind them this skill only works on RDK nodes with servo hardware attached.
|
||||||
|
|||||||
59
rdk-claw/taiyang/SKILL.md
Normal file
59
rdk-claw/taiyang/SKILL.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
name: 太阳!
|
||||||
|
description: 控制 RDK 节点上的舵机挥动,让两个舵机同步或反向运动。使用 PWM 信号控制舵机角度(0°-180°),支持多种舞动模式。触发话:太阳、舵机挥动、servo dance、PWM 舵机、双舵机控制、双舵机控制。
|
||||||
|
---
|
||||||
|
|
||||||
|
# 太阳!- 舵机挥动技能
|
||||||
|
|
||||||
|
让舵机动起来!就像太阳升起一样充满活力。
|
||||||
|
|
||||||
|
## 前置条件
|
||||||
|
|
||||||
|
- RDK 节点已连接
|
||||||
|
- PWM 接口可用(/sys/class/pwm/pwmchip0)
|
||||||
|
- 两个舵机分别连接到 pwm0 和 pwm1
|
||||||
|
|
||||||
|
## 快速使用
|
||||||
|
|
||||||
|
直接调用脚本启动舵机舞动:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 ~/.openclaw/skills/taiyang/scripts/servo_dance.py
|
||||||
|
```
|
||||||
|
|
||||||
|
停止舞动:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pkill -f servo_dance.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## 舵机控制参数
|
||||||
|
|
||||||
|
| 参数 | 默认值 | 说明 |
|
||||||
|
|------|--------|------|
|
||||||
|
| 频率 | 50Hz | 标准舵机频率(20ms周期) |
|
||||||
|
| 脉宽范围 | 1-2ms | 0°-180° 对应 |
|
||||||
|
| 中心位置 | 1.5ms | 90° |
|
||||||
|
|
||||||
|
## PWM 接口路径
|
||||||
|
|
||||||
|
- pwm0: `/sys/class/pwm/pwmchip0/pwm0` → Servo 0
|
||||||
|
- pwm1: `/sys/class/pwm/pwmchip0/pwm1` → Servo 1
|
||||||
|
|
||||||
|
## 舞动模式
|
||||||
|
|
||||||
|
脚本内置三种模式循环:
|
||||||
|
|
||||||
|
1. **波浪模式** - Servo0 和 Servo1 反向运动
|
||||||
|
2. **同步模式** - 两个舵机同步运动
|
||||||
|
|
||||||
|
## 手动控制
|
||||||
|
|
||||||
|
如需手动控制单个舵机:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 设置角度(0-180)
|
||||||
|
echo $((1000000 + angle * 5555)) > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
|
||||||
|
```
|
||||||
|
|
||||||
|
角度计算:duty = 1000000 + (angle/180) * 1000000 (单位:ns)
|
||||||
78
rdk-claw/taiyang/scripts/servo_dance.py
Normal file
78
rdk-claw/taiyang/scripts/servo_dance.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
太阳!- 双舵机舞动脚本
|
||||||
|
让舵机像太阳升起一样充满活力地挥动
|
||||||
|
"""
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
PWM0 = "/sys/class/pwm/pwmchip0/pwm0"
|
||||||
|
PWM1 = "/sys/class/pwm/pwmchip0/pwm1"
|
||||||
|
PERIOD = 20000000 # 20ms = 50Hz
|
||||||
|
|
||||||
|
def init_pwm():
|
||||||
|
"""初始化两个PWM通道"""
|
||||||
|
for pwm in [PWM0, PWM1]:
|
||||||
|
try:
|
||||||
|
with open(os.path.join(pwm, "period"), "w") as f:
|
||||||
|
f.write(str(PERIOD))
|
||||||
|
with open(os.path.join(pwm, "duty_cycle"), "w") as f:
|
||||||
|
f.write("1500000") # 中心位置 90°
|
||||||
|
with open(os.path.join(pwm, "enable"), "w") as f:
|
||||||
|
f.write("1")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error initializing {pwm}: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def set_angle(pwm, angle):
|
||||||
|
"""设置舵机角度 (0-180°)"""
|
||||||
|
duty = int(1000000 + (angle / 180.0) * 1000000)
|
||||||
|
with open(os.path.join(pwm, "duty_cycle"), "w") as f:
|
||||||
|
f.write(str(duty))
|
||||||
|
|
||||||
|
def wave_pattern():
|
||||||
|
"""波浪模式:两舵机反向运动"""
|
||||||
|
for a in range(0, 181, 30):
|
||||||
|
set_angle(PWM0, a)
|
||||||
|
set_angle(PWM1, 180 - a)
|
||||||
|
time.sleep(0.2)
|
||||||
|
for a in range(180, -1, -30):
|
||||||
|
set_angle(PWM0, a)
|
||||||
|
set_angle(PWM1, 180 - a)
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
|
def sync_pattern():
|
||||||
|
"""同步模式:两舵机同步运动"""
|
||||||
|
for a in [0, 90, 180, 90]:
|
||||||
|
set_angle(PWM0, a)
|
||||||
|
set_angle(PWM1, a)
|
||||||
|
time.sleep(0.3)
|
||||||
|
|
||||||
|
def stop_pwm():
|
||||||
|
"""停止PWM输出"""
|
||||||
|
set_angle(PWM0, 90)
|
||||||
|
set_angle(PWM1, 90)
|
||||||
|
time.sleep(0.3)
|
||||||
|
for pwm in [PWM0, PWM1]:
|
||||||
|
with open(os.path.join(pwm, "enable"), "w") as f:
|
||||||
|
f.write("0")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("🌞 太阳!- 舵机舞动开始")
|
||||||
|
print("=" * 40)
|
||||||
|
init_pwm()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
print("🌊 波浪模式...")
|
||||||
|
wave_pattern()
|
||||||
|
print("🎯 同步模式...")
|
||||||
|
sync_pattern()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n停止舞动...")
|
||||||
|
stop_pwm()
|
||||||
|
print("🌞 太阳落山了,再见!")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
x
Reference in New Issue
Block a user