API source snapshot · 2026-09-24
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | #!/usr/bin/env python3 """Simple MTC-Bluesky Integration This script demonstrates how to use beambot with Bluesky by using the beambot_client.py action client. Backend: beambot (Python MTC implementation) """ import argparse import os import subprocess from pathlib import Path import bluesky.plan_stubs as bps import rclpy from bluesky import RunEngine from ophyd.status import Status class MTCDevice: """Simple MTC device that uses beambot_client.py action client""" def __init__(self, name="mtc_device"): self.name = name self.get_logger = lambda: print def set(self, task_params): """Execute MTC task using beambot_client.py Args: task_params: Dict with 'json_file' key (robot_ip no longer needed) """ json_file_path = task_params['json_file'] # Create a Status object status = Status() try: # Use beambot_client.py (only takes json file path) cmd = ['ros2', 'run', 'beambot', 'beambot_client.py', json_file_path] print(f"Executing MTC task from: {json_file_path}") result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) if result.returncode == 0: print("✓ MTC task completed successfully") status.set_finished() else: print(f"✗ MTC task failed: {result.stderr}") status.set_exception(Exception(f"MTC task failed: {result.stderr}")) except subprocess.TimeoutExpired: print("✗ MTC task timed out") status.set_exception(Exception("MTC task timed out")) except Exception as e: print(f"✗ Error running MTC task: {e}") status.set_exception(e) return status def simple_mtc_plan(mtc_device, json_files): """Simple plan to execute MTC tasks Args: mtc_device: The MTC device json_files: List of JSON file paths """ for i, json_file in enumerate(json_files): print(f"Processing task {i+1}/{len(json_files)}") task_params = {'json_file': json_file} yield from bps.abs_set(mtc_device, task_params) yield from bps.wait() print(f"Task {i+1} completed") def main(): """Main function""" print("=== Simple MTC-Bluesky Integration (beambot) ===") # Parse command-line arguments parser = argparse.ArgumentParser( description='Execute MTC tasks using Bluesky with beambot backend', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: # Use default JSON file python3 simple_mtc_bluesky.py # Use specific JSON file python3 simple_mtc_bluesky.py beamline_test.json # Multiple files python3 simple_mtc_bluesky.py test1.json test2.json Note: Robot IP is now configured in beambot beamline config, not passed as argument. """ ) parser.add_argument( 'json_files', nargs='*', help='JSON file(s) to execute (default: complete_sequence.json)' ) args = parser.parse_args() # Initialize ROS2 rclpy.init() try: # Create MTC device mtc_device = MTCDevice("mtc_device") # Create RunEngine RE = RunEngine({}) # Workspace path detection (priority order): # 1. EROBS_WORKSPACE environment variable # 2. Auto-detect from script location # 3. Search for colcon workspace markers WORKSPACE_ROOT = os.environ.get('EROBS_WORKSPACE') if not WORKSPACE_ROOT: # Auto-detect from script location (src/bluesky_ros/ -> workspace root) candidate = Path(__file__).absolute().parents[2] # Verify it's a valid workspace (has install/setup.bash or src/ directory) if (candidate / 'install' / 'setup.bash').exists() or \ (candidate / 'src').exists(): WORKSPACE_ROOT = candidate if not WORKSPACE_ROOT: print("⚠ Could not detect workspace. Set EROBS_WORKSPACE environment variable.") print(" Example: export EROBS_WORKSPACE=/path/to/your/workspace") return WORKSPACE_ROOT = Path(WORKSPACE_ROOT) # Process JSON file arguments if args.json_files: json_files = [str(WORKSPACE_ROOT / json_file) for json_file in args.json_files] else: # Default to complete_sequence.json in cms/tasks/ default_path = WORKSPACE_ROOT / "src" / "cms" / "tasks" / "complete_sequence.json" if default_path.exists(): json_files = [str(default_path)] else: print(f"⚠ Default task file not found: {default_path}") print("Please specify a JSON file path") return print(f"Workspace: {WORKSPACE_ROOT}") print(f"JSON files: {json_files}") print("Executing MTC tasks...") RE(simple_mtc_plan(mtc_device, json_files)) print("✓ All tasks completed") except Exception as e: print(f"✗ Error: {e}") import traceback traceback.print_exc() finally: rclpy.shutdown() print("✓ Done!") if __name__ == "__main__": main() |