lightweight_server.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 超轻量级伺服驱动选型工具 - 纯内置模块版本
  5. 使用 Python 内置 http.server 模块,无需额外依赖
  6. """
  7. import os
  8. import sys
  9. import json
  10. import threading
  11. from http.server import HTTPServer, SimpleHTTPRequestHandler
  12. from urllib.parse import parse_qs, urlparse
  13. # 伺服电机参数数据库
  14. SERVO_MOTORS = [
  15. {"model": "ECMA-C20604RS", "power": 0.4, "torque": 1.27, "speed": 3000, "inertia": 0.00015},
  16. {"model": "ECMA-C20804RS", "power": 0.75, "torque": 2.39, "speed": 3000, "inertia": 0.00028},
  17. {"model": "ECMA-C20807RS", "power": 0.75, "torque": 2.39, "speed": 3000, "inertia": 0.00028},
  18. {"model": "ECMA-C21007RS", "power": 1.5, "torque": 4.77, "speed": 3000, "inertia": 0.00056},
  19. {"model": "ECMA-C21307RS", "power": 2.0, "torque": 6.37, "speed": 3000, "inertia": 0.00075},
  20. {"model": "ECMA-C21807RS", "power": 3.0, "torque": 9.55, "speed": 3000, "inertia": 0.00112},
  21. {"model": "ECMA-C22010RS", "power": 4.0, "torque": 12.73, "speed": 3000, "inertia": 0.00150},
  22. ]
  23. class ServoHandler(SimpleHTTPRequestHandler):
  24. def do_GET(self):
  25. if self.path == '/':
  26. self.send_response(200)
  27. self.send_header('Content-type', 'text/html; charset=utf-8')
  28. self.end_headers()
  29. html_content = self.get_html_content()
  30. self.wfile.write(html_content.encode('utf-8'))
  31. elif self.path == '/api/motors':
  32. self.send_response(200)
  33. self.send_header('Content-type', 'application/json; charset=utf-8')
  34. self.end_headers()
  35. self.wfile.write(json.dumps(SERVO_MOTORS, ensure_ascii=False).encode('utf-8'))
  36. else:
  37. super().do_GET()
  38. def do_POST(self):
  39. if self.path == '/api/calculate':
  40. content_length = int(self.headers['Content-Length'])
  41. post_data = self.rfile.read(content_length).decode('utf-8')
  42. params = json.loads(post_data)
  43. # 简单的选型计算逻辑
  44. results = self.calculate_selection(params)
  45. self.send_response(200)
  46. self.send_header('Content-type', 'application/json; charset=utf-8')
  47. self.end_headers()
  48. self.wfile.write(json.dumps(results, ensure_ascii=False).encode('utf-8'))
  49. def calculate_selection(self, params):
  50. """简单的伺服电机选型计算"""
  51. required_torque = float(params.get('torque', 0))
  52. required_speed = float(params.get('speed', 0))
  53. safety_factor = float(params.get('safety', 1.5))
  54. suitable_motors = []
  55. for motor in SERVO_MOTORS:
  56. if (motor['torque'] >= required_torque * safety_factor and
  57. motor['speed'] >= required_speed):
  58. suitable_motors.append(motor)
  59. return {
  60. 'suitable_motors': suitable_motors,
  61. 'required_torque': required_torque,
  62. 'required_speed': required_speed,
  63. 'safety_factor': safety_factor
  64. }
  65. def get_html_content(self):
  66. return '''<!DOCTYPE html>
  67. <html lang="zh-CN">
  68. <head>
  69. <meta charset="UTF-8">
  70. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  71. <title>伺服驱动选型工具 - 超轻量版</title>
  72. <style>
  73. body { font-family: Arial, sans-serif; margin: 20px; background: #f5f5f5; }
  74. .container { max-width: 800px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
  75. h1 { color: #333; text-align: center; }
  76. .form-group { margin: 15px 0; }
  77. label { display: block; margin-bottom: 5px; font-weight: bold; }
  78. input, select { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; }
  79. button { background: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; width: 100%; margin-top: 10px; }
  80. button:hover { background: #0056b3; }
  81. .results { margin-top: 20px; padding: 15px; background: #e9ecef; border-radius: 4px; }
  82. .motor-item { padding: 10px; margin: 5px 0; background: white; border-radius: 4px; border-left: 4px solid #007bff; }
  83. </style>
  84. </head>
  85. <body>
  86. <div class="container">
  87. <h1>伺服驱动选型工具</h1>
  88. <div class="form-group">
  89. <label for="torque">所需扭矩 (N·m):</label>
  90. <input type="number" id="torque" step="0.1" value="1.0">
  91. </div>
  92. <div class="form-group">
  93. <label for="speed">所需转速 (rpm):</label>
  94. <input type="number" id="speed" value="1000">
  95. </div>
  96. <div class="form-group">
  97. <label for="safety">安全系数:</label>
  98. <input type="number" id="safety" step="0.1" value="1.5">
  99. </div>
  100. <button onclick="calculateSelection()">计算选型</button>
  101. <div id="results" class="results" style="display:none;"></div>
  102. </div>
  103. <script>
  104. async function calculateSelection() {
  105. const torque = document.getElementById('torque').value;
  106. const speed = document.getElementById('speed').value;
  107. const safety = document.getElementById('safety').value;
  108. const response = await fetch('/api/calculate', {
  109. method: 'POST',
  110. headers: {'Content-Type': 'application/json'},
  111. body: JSON.stringify({torque, speed, safety})
  112. });
  113. const data = await response.json();
  114. displayResults(data);
  115. }
  116. function displayResults(data) {
  117. const resultsDiv = document.getElementById('results');
  118. if (data.suitable_motors.length === 0) {
  119. resultsDiv.innerHTML = '<p>未找到合适的伺服电机型号。请调整参数或联系技术支持。</p>';
  120. } else {
  121. let html = `<p>找到 ${data.suitable_motors.length} 个合适的型号:</p>`;
  122. data.suitable_motors.forEach(motor => {
  123. html += `<div class="motor-item">
  124. <strong>${motor.model}</strong><br>
  125. 功率: ${motor.power}kW | 扭矩: ${motor.torque}N·m | 转速: ${motor.speed}rpm
  126. </div>`;
  127. });
  128. resultsDiv.innerHTML = html;
  129. }
  130. resultsDiv.style.display = 'block';
  131. }
  132. // 加载电机列表
  133. window.onload = function() {
  134. console.log('伺服驱动选型工具 - 超轻量版已加载');
  135. };
  136. </script>
  137. </body>
  138. </html>'''
  139. def run_server(port=8080):
  140. """运行服务器"""
  141. server_address = ('', port)
  142. httpd = HTTPServer(server_address, ServoHandler)
  143. print(f"🚀 启动伺服驱动选型工具 (超轻量版)...")
  144. print(f"📁 工作目录: {os.getcwd()}")
  145. print(f"🌐 访问地址: http://localhost:{port}")
  146. print(f"💡 提示: 按 Ctrl+C 停止服务器")
  147. try:
  148. httpd.serve_forever()
  149. except KeyboardInterrupt:
  150. print("\n👋 服务器已停止")
  151. httpd.shutdown()
  152. if __name__ == "__main__":
  153. port = 8080
  154. if len(sys.argv) > 1:
  155. port = int(sys.argv[1])
  156. run_server(port)