# RFReady **Repository Path**: xcy63/rfready ## Basic Information - **Project Name**: RFReady - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-26 - **Last Updated**: 2025-10-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 射频腔Ready状态控制器 - 使用指南 ## 文件清单 ``` main.py # 主程序 config.yaml # 配置文件 README.md # 本文件 ``` ## 快速开始 ### 1. 安装依赖 ```bash pip install pyepics pyyaml ``` ### 2. 修改配置 编辑 `config.yaml`,根据实际硬件配置修改: ```yaml hardware: cryomodules: ['01', '02', '03'] # 实际的CM列表 cavities_per_cm: ['01', '02', '03', '04', '05'] # 每个CM的腔体数 ``` 修改PV命名规则: ```yaml pv_config: input: enable: 'iLinac-CM{cm}:LLRF-{cav}:Enable' # 根据实际PV名称修改 # ... ``` ### 3. 运行程序 ```bash python main.py ``` ## 配置文件详解 ### 硬件配置 **自动生成所有腔体:** ```yaml hardware: cryomodules: ['01', '02', '03', '04', '05', '06'] cavities_per_cm: ['01', '02', '03', '04', '05'] # 会生成: CM01-01, CM01-02, ..., CM06-05 共30个腔体 ``` **明确指定腔体(测试):** ```yaml hardware: specific_cavities: ['CM01-01', 'CM01-02', 'CM02-01'] # 或使用连续编号 # specific_cavities: ['1', '2', '3'] # 会自动映射到CM和腔体 ``` ### PV命名规则 配置使用模板字符串,`{cm}` 和 `{cav}` 会被替换: ```yaml pv_config: input: enable: 'iLinac-CM{cm}:LLRF-{cav}:Enable' # CM01-03 会被解析为: iLinac-CM01:LLRF-03:Enable ``` **输入PV(监控):** - `enable` - 腔体使能信号 - `epk_mon` - Epk监测值(MV/m) - `phase_mon` - 相位监测值(度) - `loop_status` - LLRF闭环状态(1=闭环) - `target_status` - LLRF目标设定(>阈值表示ready) - `trig_status` - LLRF触发参数(>阈值表示ready) **输出PV(控制):** - `epk_set` - Epk设定值 - `phase_set` - 相位设定值 - `rfon` - RF开关(0=关,1=开) - `ready_all` - 总就绪信号(0=未就绪,1=就绪) ### 就绪条件配置 ```yaml pv_config: ready_thresholds: target_status_min: 0.1 # target_status > 0.1 表示ready trig_status_min: 0.1 # trig_status > 0.1 表示ready ``` 就绪条件 = `loop_status==1 AND target_status>0.1 AND trig_status>0.1` ## 状态机说明 ### 4个状态 ``` IDLE (0) ↓ Enable=1, Epk!=0 LOADING (2) ↓ 就绪条件满足 READY (3) 或 IDLE (0) ↓ Enable=1, Epk=0 PREP_DENIED (1) ↓ Epk!=0 LOADING (2) ``` ### 状态转换详解 #### IDLE → LOADING - **条件**: Enable=1 且 Epk≠0 - **动作**: - Ready_all = 0 - 复制 Epk_mon → Epk_set - 复制 Phase_mon → Phase_set #### IDLE → PREP_DENIED - **条件**: Enable=1 但 Epk=0 - **动作**: - Ready_all = 0 - RFon = 0(强制关闭) - 启动RFon监控(防止外部开启) #### LOADING → READY - **条件**: 就绪条件全部满足 - **动作**: Ready_all = 1 #### READY → LOADING - **条件**: 就绪条件丢失 - **动作**: Ready_all = 0 #### 任意状态 → IDLE - **条件**: Enable=0 - **动作**: - Ready_all = 0 - 停止RFon监控 ### RFon强制关闭机制 在 **PREP_DENIED** 状态下: - 系统持续监控RFon PV - 如果检测到RFon=1,立即强制写回0 - 防止Epk未就绪时误开启射频 ## 使用示例 ### 示例1: 测试3个腔体 **config.yaml:** ```yaml hardware: specific_cavities: ['CM01-01', 'CM01-02', 'CM01-03'] ``` **运行:** ```bash python main.py ``` ### 示例2: 生产环境(30个腔体) **config.yaml:** ```yaml hardware: cryomodules: ['01', '02', '03', '04', '05', '06'] cavities_per_cm: ['01', '02', '03', '04', '05'] ``` ### 示例3: 跳过连接失败的腔体 **config.yaml:** ```yaml runtime: skip_failed_cavities: true # 默认值 ``` 这样即使某些腔体的PV无法连接,程序也会继续运行其他腔体。 ## 输出说明 ### 控制台输出 ``` ====================================================================== 射频腔Ready状态控制器 - 简单开发版本 ====================================================================== ✓ 配置文件加载成功: config.yaml ✓ 日志系统初始化完成 正在初始化 30 个腔体... ---------------------------------------------------------------------- ✓ CM01-01 初始化成功 ✓ CM01-02 初始化成功 ... ✗ CM03-05 初始化失败 ====================================================================== ✓ 28/30 个腔体正在运行 控制器运行中,按 Ctrl+C 停止 ---------------------------------------------------------------------- 2025-10-26 10:30:00 - INFO - 状态摘要: IDLE:25 | LOADING:2 | READY:1 ``` ### 日志文件 `rf_ready_controller.log`: ``` 2025-10-26 10:30:00 - INFO - ================================================== 2025-10-26 10:30:00 - INFO - 射频腔Ready状态控制器启动 2025-10-26 10:30:00 - INFO - ================================================== 2025-10-26 10:30:01 - INFO - 正在初始化腔体 CM01-01... 2025-10-26 10:30:02 - INFO - CM01-01: 所有PV连接成功 (10个) 2025-10-26 10:30:03 - INFO - CM01-01: IDLE -> LOADING (Enable=1且Epk!=0) ``` ### 状态文件 `rf_ready_status.json`: ```json { "timestamp": "2025-10-26T10:30:00.123456", "total_cavities": 30, "state_summary": { "IDLE": 25, "PREP_DENIED": 0, "LOADING": 3, "READY": 2 }, "cavities": [ { "cm": "01", "cav": "01", "state": "READY", "event_count": 1523, "events_per_minute": 25.4, "connected_pvs": 10, "total_pvs": 10, "uptime_seconds": 3600.5, "last_event_seconds_ago": 2.1 }, ... ] } ``` ## 监控和调试 ### 实时查看状态 ```bash # 监控日志 tail -f rf_ready_controller.log # 监控状态文件 watch -n 1 cat rf_ready_status.json # 使用jq美化输出 watch -n 1 'cat rf_ready_status.json | jq .' # 只看状态摘要 watch -n 1 'cat rf_ready_status.json | jq .state_summary' # 只看READY状态的腔体 cat rf_ready_status.json | jq '.cavities[] | select(.state=="READY")' ``` ### 测试PV连接 ```bash # 测试单个腔体的PV caget iLinac-CM01:LLRF-01:Enable caget iLinac-CM01:LLRF-01:Epk caget iLinac-CM01:LLRF-01:SELLoopOn # 测试所有输入PV caget iLinac-CM01:LLRF-01:Enable \ iLinac-CM01:LLRF-01:Epk \ iLinac-CM01:LLRF-01:PhaseSetpoint \ iLinac-CM01:LLRF-01:SELLoopOn \ iLinac-CM01:LLRF-01:AmpSetpoint \ iLinac-CM01:LLRF-01:RFPulseOnTime ``` ### 手动触发状态变化 ```bash # 启用腔体 caput iLinac-CM01:LLRF-01:Enable 1 # 设置Epk caput iLinac-CM01:LLRF-01:Epk 10.5 # 设置就绪条件 caput iLinac-CM01:LLRF-01:SELLoopOn 1 caput iLinac-CM01:LLRF-01:AmpSetpoint 5.0 caput iLinac-CM01:LLRF-01:RFPulseOnTime 1000 # 查看结果 caget iLinac-CM01:LLRF-01:RF:Ready ``` ### 调试模式 修改配置启用详细日志: ```yaml runtime: log_level: 'DEBUG' ``` ## 常见问题 ### Q1: PV连接超时 **现象:** ``` CM01-01: 以下PV连接失败: enable(iLinac-CM01:LLRF-01:Enable) ``` **解决方案:** 1. 检查IOC是否运行 2. 检查PV名称是否正确: `caget iLinac-CM01:LLRF-01:Enable` 3. 检查EPICS环境变量: ```bash echo $EPICS_CA_ADDR_LIST echo $EPICS_CA_AUTO_ADDR_LIST ``` 4. 增加连接超时: ```yaml runtime: connection_timeout: 20.0 ``` ### Q2: 部分腔体初始化失败 **现象:** ``` ✓ 25/30 个腔体正在运行 ``` **说明:** 这是正常的,可能原因: - 部分腔体的IOC未运行 - PV命名规则不统一 - 网络问题 **处理:** - 如果`skip_failed_cavities: true`,程序会继续运行其他腔体 - 检查日志找出具体失败原因 ### Q3: 状态不转换 **现象:** 腔体卡在某个状态 **诊断:** ```bash # 查看当前状态 cat rf_ready_status.json | jq '.cavities[] | select(.cm=="01" and .cav=="01")' # 手动检查条件 caget iLinac-CM01:LLRF-01:Enable # 应该为1 caget iLinac-CM01:LLRF-01:Epk # 应该不为0 caget iLinac-CM01:LLRF-01:SELLoopOn # 应该为1 caget iLinac-CM01:LLRF-01:AmpSetpoint # 应该>0.1 caget iLinac-CM01:LLRF-01:RFPulseOnTime # 应该>0.1 ``` ### Q4: RFon无法保持关闭 **现象:** PREP_DENIED状态下RFon频繁变为1 **说明:** 外部系统在持续写入RFon=1 **解决:** - 检查日志确认有"强制关闭RFon"消息 - 这是正常保护机制 - 需要检查外部系统逻辑 ### Q5: 事件频率过高 **现象:** `events_per_minute` 非常大(>1000) **说明:** PV变化频繁,可能原因: - PV值噪声大,频繁变化 - 多个PV同时变化 **影响:** 可能导致CPU占用高 **优化:** - 在IOC端添加死区(deadband) - 降低PV更新频率 ## 高级配置 ### 自定义日志轮转 ```yaml logging: max_bytes: 52428800 # 50 MB backup_count: 10 ``` ### 调整就绪条件阈值 ```yaml pv_config: ready_thresholds: target_status_min: 0.5 # 更严格的阈值 trig_status_min: 1.0 ``` ### 禁用失败跳过 ```yaml runtime: skip_failed_cavities: false # 任何腔体失败都退出程序 ``` ## 性能参考 **单个腔体资源消耗:** - 内存: ~1-2 MB - CPU: 空闲时接近0% **30个腔体:** - 内存: ~30-60 MB - CPU: <5% - 网络: 取决于PV变化频率 **启动时间:** - 取决于PV连接速度 - 通常 <30秒 ## 限制和注意事项 ⚠️ **这是简化的开发版本,有以下限制:** 1. **无高级线程安全** - 基本够用但不够完善 2. **无自动重连** - PV断连后需要手动重启 3. **无配置热重载** - 修改配置需要重启程序 4. **有限的错误恢复** - 严重错误可能需要人工介入 **适用场景:** - ✓ 开发测试 - ✓ 概念验证 - ✓ 小规模部署(<50个腔体) - ✗ 关键生产环境 - ✗ 需要高可用性的场景 ## 升级建议 如果需要在生产环境使用,建议参考完整的设计方案,增加: - 线程安全保护 - 自动重连机制 - 配置热重载 - 告警系统 - 性能优化 - 完善的监控 ## 故障排查流程 ``` 1. 检查程序是否运行 ps aux | grep main.py 2. 查看最近日志 tail -n 100 rf_ready_controller.log 3. 检查状态文件 cat rf_ready_status.json | jq . 4. 测试PV连接 caget 5. 查看详细日志 修改log_level: 'DEBUG',重启程序 6. 如果无法解决 收集日志和状态文件联系管理员 ``` ## 许可和免责声明 本程序仅用于开发测试,不提供任何保证。在生产环境使用前请充分测试。 --- **版本:** 1.0 **更新日期:** 2025-10-26 **作者:** RF Controls Team