8.C_Demo_产生随机值

在Linux中,可以用时间函数time的返回值作为产生随机数的种子,使用srand将这个值设置为随机种子,使用rand来产生随机数。

time函数声明如下:

time_t time(time_t *result);

返回值:time_t 通常为long型,可用 sizeof 查看内存大小。返回值单位为s,错误时返回-1

result:用于存储时间值,单位为s。存储的值与返回值是同一个值,可以写NULL。

srand与rand函数声明如下:

//设置随机种子
void srand(unsigned int seed);
//产生随机数
int rand(void);

seed:随机种子,写入time(NULL)即可

示例代码如下:

具体代码实现如下:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main(){
	int num;
	int i;
	srand(time(NULL));
	for(i=0;i<3;i++){
		num = rand();
		num = num % 5 + 10;//产生10~14的随机数
		printf("%d ",num);
	}
	printf("\n");
	return 0;
}

代码运行结果如下:

做一个在mujoco上原生渲染的演示,来展示整个运动过程#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 人形机器人仿真演示 - 优化版本 """ import sys import os import time import json import numpy as np import matplotlib.pyplot as plt from typing import Dict, List, Tuple, Optional import threading import argparse import mujoco import pygame from pygame.locals import * import math import cv2 from PIL import Image import io import traceback import subprocess import ctypes import glfw # 检查OpenGL支持并尝试修复 def fix_opengl_issues(): """尝试解决OpenGL初始化问题""" print("🛠️ 尝试解决OpenGL初始化问题...") # 尝试设置不同的渲染后端 backends = ['glfw', 'osmesa', 'egl'] for backend in backends: glfw_initialized = False try: os.environ['MUJOCO_GL'] = backend print(f" 尝试使用 {backend} 渲染后端...") # 初始化GLFW窗口用于测试 if not glfw.init(): raise RuntimeError("GLFW初始化失败") glfw_initialized = True # 创建隐藏窗口 glfw.window_hint(glfw.VISIBLE, glfw.FALSE) window = glfw.create_window(640, 480, "OpenGL Test", None, None) if not window: raise RuntimeError("GLFW窗口创建失败") glfw.make_context_current(window) print(f"✅ 使用 {backend} 后端成功创建OpenGL上下文!") # 测试OpenGL功能 glClearColor = ctypes.CDLL(None).glClearColor glClearColor(0.2, 0.3, 0.4, 1.0) print("✅ OpenGL基本功能测试通过") glfw.destroy_window(window) glfw.terminate() glfw_initialized = False return True except Exception as e: print(f"⚠️ {backend} 后端失败: {e}") if 'window' in locals() and window: glfw.destroy_window(window) if glfw_initialized: glfw.terminate() # 尝试加载OpenGL库 try: print(" 尝试直接加载OpenGL库...") opengl_libs = [ 'libGL.so.1', # Linux '/usr/lib/x86_64-linux-gnu/libGL.so.1', # Ubuntu 'opengl32.dll', # Windows '/System/Library/Frameworks/OpenGL.framework/OpenGL' # macOS ] for lib in opengl_libs: try: ctypes.CDLL(lib) print(f"✅ 成功加载 {lib}") return True except Exception as e: print(f"⚠️ 加载 {lib} 失败: {e}") except Exception as e: print(f"⚠️ OpenGL库加载失败: {e}") print("💡 建议解决方案:") print(" 1. 更新显卡驱动程序") print(" 2. 安装系统OpenGL库 (Linux: libgl1-mesa-glx, Windows: OpenGL runtime)") print(" 3. 在虚拟环境中使用: conda install -c conda-forge glew glfw") return False # 导入自定义模块 try: from mujoco_simulation import HumanoidRobot from advanced_control import ( IntelligentDecisionSystem, PathPlanner, EnergyOptimizer, AdaptiveController, EnvironmentState, RobotState, TaskType, TerrainType ) except ImportError: # 创建模拟类以避免导入错误 class HumanoidRobot: def __init__(self): self.model = None self.data = None self.position = np.array([0.0, 0.0, 1.0]) self.velocity = np.zeros(3) self.orientation = np.array([1.0, 0.0, 0.0, 0.0]) class IntelligentDecisionSystem: pass class VisualizationSystem: """可视化系统 - 用于2D和3D渲染""" def __init__(self, model: Optional[mujoco.MjModel] = None, width: int = 1200, height: int = 800): """初始化可视化系统""" pygame.init() # 使用标准2D渲染模式,避免OpenGL模式冲突 self.screen = pygame.display.set_mode((width, height)) pygame.display.set_caption("人形机器人仿真演示") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont('SimHei', 20) self.title_font = pygame.font.SysFont('SimHei', 28, bold=True) # 地形颜色配置 self.terrain_colors = { 'flat': (180, 200, 180), 'slope': (160, 180, 200), 'stairs': (200, 180, 160), 'sand': (220, 200, 150), 'grass': (150, 200, 150) } self.obstacle_colors = { 'static': (200, 100, 100), 'dynamic': (100, 150, 200), 'moving': (150, 100, 200) } # 创建机器人图像 self.robot_img = self._create_robot_image() # 地形纹理缓存 self.terrain_textures = { 'flat': self._create_terrain_texture('flat'), 'slope': self._create_terrain_texture('slope'), 'stairs': self._create_terrain_texture('stairs'), 'sand': self._create_terrain_texture('sand'), 'grass': self._create_terrain_texture('grass') } # 尝试修复OpenGL问题 self.opengl_fixed = fix_opengl_issues() self.using_software_rendering = False # 初始化MuJoCo渲染组件 self.camera = mujoco.MjvCamera() self.opt = mujoco.MjvOption() self.scene = None self.context = None if model is not None and self.opengl_fixed: try: # 尝试创建渲染上下文 self.context = mujoco.MjrContext(model, mujoco.mjtFontScale.mjFONTSCALE_150) self.scene = mujoco.MjvScene(model=model, maxgeom=1000) print("✅ 成功初始化渲染上下文") # 设置相机位置 self.camera.distance = 5.0 self.camera.elevation = -20 self.camera.azimuth = 90 except Exception as e: print(f"⚠️ 渲染上下文初始化失败: {e}") self.scene = None self.context = None self.using_software_rendering = True else: print("⚠️ 无法修复OpenGL问题,使用软件渲染") self.using_software_rendering = True def _create_robot_image(self): """创建机器人图像""" surface = pygame.Surface((50, 80), pygame.SRCALPHA) # 绘制头部 pygame.draw.circle(surface, (100, 150, 255), (25, 15), 10) # 绘制身体 pygame.draw.rect(surface, (100, 200, 100), (15, 25, 20, 30)) # 绘制腿部 pygame.draw.line(surface, (0, 0, 0), (20, 55), (15, 75), 3) pygame.draw.line(surface, (0, 0, 0), (30, 55), (35, 75), 3) # 绘制手臂 pygame.draw.line(surface, (0, 0, 0), (15, 35), (5, 50), 3) pygame.draw.line(surface, (0, 0, 0), (35, 35), (45, 50), 3) return surface def _create_terrain_texture(self, terrain_type: str): """创建地形纹理""" size = (350, 100) texture = pygame.Surface(size, pygame.SRCALPHA) base_color = self.terrain_colors[terrain_type] if terrain_type == 'flat': # 平地的简单纹理 for i in range(0, size[0], 10): for j in range(0, size[1], 10): color_variation = np.random.randint(-10, 10) color = ( max(0, min(255, base_color[0] + color_variation)), max(0, min(255, base_color[1] + color_variation)), max(0, min(255, base_color[2] + color_variation)) ) pygame.draw.rect(texture, color, (i, j, 10, 10)) elif terrain_type == 'slope': # 斜坡纹理 for i in range(size[0]): height = int(size[1] * (1 - i / (size[0] * 1.5))) pygame.draw.line(texture, base_color, (i, height), (i, size[1]), 1) if i % 10 == 0: pygame.draw.line(texture, (150, 150, 150), (i, height), (i, size[1]), 1) elif terrain_type == 'stairs': # 楼梯纹理 step_height = 20 step_width = 70 for i in range(5): pygame.draw.rect(texture, (180, 160, 140), (i * step_width, size[1] - (i + 1) * step_height, step_width, step_height)) elif terrain_type == 'sand': # 沙地纹理 texture.fill(base_color) for _ in range(100): x = np.random.randint(0, size[0]) y = np.random.randint(0, size[1]) radius = np.random.randint(2, 5) shade = np.random.randint(-15, 15) color = ( max(0, min(255, base_color[0] + shade)), max(0, min(255, base_color[1] + shade)), max(0, min(255, base_color[2] + shade)) ) pygame.draw.circle(texture, color, (x, y), radius) elif terrain_type == 'grass': # 草地纹理 texture.fill(base_color) for i in range(0, size[0], 5): for j in range(0, size[1], 15): pygame.draw.line(texture, (100, 180, 100), (i, j), (i + np.random.randint(-2, 2), j - np.random.randint(5, 10)), 1) return texture def render_2d(self, demo, current_time: float): """渲染2D可视化界面""" self.screen.fill((240, 240, 245)) # 获取当前场景状态 scenario_state = demo.get_current_scenario_state(current_time) # 绘制标题 title = self.title_font.render("人形机器人仿真演示系统", True, (30, 30, 100)) self.screen.blit(title, (20, 15)) # 绘制状态面板 self._render_status_panel(demo, scenario_state, current_time) # 绘制场景可视化 self._render_scenario_visualization(demo, scenario_state, current_time) # 绘制3D渲染窗口 self._render_3d_view(demo) # 绘制性能图表 self._render_performance_charts(demo) # 绘制控制说明 self._render_instructions() pygame.display.flip() def _render_status_panel(self, demo, scenario_state: Dict, current_time: float): """渲染状态面板""" # 状态面板背景 pygame.draw.rect(self.screen, (250, 250, 255), (20, 70, 450, 180), 0, 10) pygame.draw.rect(self.screen, (200, 200, 220), (20, 70, 450, 180), 2, 10) # 场景信息 scene_text = self.font.render(f"场景: {scenario_state['description']}", True, (30, 30, 30)) self.screen.blit(scene_text, (40, 90)) # 地形信息 terrain_text = self.font.render(f"地形: {scenario_state['terrain']}", True, (30, 30, 30)) self.screen.blit(terrain_text, (40, 120)) # 时间信息 time_text = self.font.render(f"时间: {current_time:.1f}s / {demo.demo_config['duration']:.1f}s", True, (30, 30, 30)) self.screen.blit(time_text, (40, 150)) # 能量消耗 energy_text = self.font.render( f"能量消耗: {demo.energy_consumption[-1] if demo.energy_consumption else 0:.2f} J", True, (30, 30, 30)) self.screen.blit(energy_text, (40, 180)) # 控制模式 mode_text = self.font.render(f"控制模式: {'AI控制' if demo.demo_config['enable_ai'] else '手动控制'}", True, (30, 30, 30)) self.screen.blit(mode_text, (40, 210)) # 渲染状态 render_status = "硬件加速" if not self.using_software_rendering else "软件渲染" render_text = self.font.render(f"渲染模式: {render_status}", True, (30, 30, 30)) self.screen.blit(render_text, (250, 180)) # 状态指示器 status_color = (100, 200, 100) if demo.is_running else (200, 100, 100) pygame.draw.circle(self.screen, status_color, (400, 100), 10) status_text = self.font.render("运行中" if demo.is_running else "已停止", True, (30, 30, 30)) self.screen.blit(status_text, (415, 95)) # 暂停状态 if demo.paused: pause_text = self.font.render("已暂停", True, (200, 100, 50)) self.screen.blit(pause_text, (400, 130)) def _render_scenario_visualization(self, demo, scenario_state: Dict, current_time: float): """渲染场景可视化""" # 场景可视化背景 pygame.draw.rect(self.screen, (250, 250, 255), (20, 270, 450, 300), 0, 10) pygame.draw.rect(self.screen, (200, 200, 220), (20, 270, 450, 300), 2, 10) # 使用预生成的地形纹理 terrain_type = scenario_state['terrain'] if terrain_type in self.terrain_textures: terrain_img = self.terrain_textures[terrain_type] self.screen.blit(terrain_img, (50, 350)) else: # 默认地形 terrain_color = self.terrain_colors.get(terrain_type, (180, 180, 180)) pygame.draw.rect(self.screen, terrain_color, (50, 350, 350, 100)) # 绘制障碍物 for obs in scenario_state['obstacles']: color = self.obstacle_colors.get(obs['type'], (150, 150, 150)) x = 50 + (obs['position'][0] / 10) * 350 y = 400 - (obs['position'][1] / 2) * 50 radius = obs['radius'] * 50 # 绘制障碍物阴影增加深度感 pygame.draw.circle(self.screen, (100, 100, 100), (int(x - 3), int(y + 3)), int(radius)) pygame.draw.circle(self.screen, color, (int(x), int(y)), int(radius)) # 动态障碍物标记 if obs['type'] == 'dynamic': pygame.draw.circle(self.screen, (255, 255, 0), (int(x + radius * 0.6), int(y - radius * 0.6)), int(radius * 0.3)) # 绘制机器人 progress = min(current_time / demo.demo_config['duration'], 1.0) robot_x = 50 + progress * 350 robot_y = 400 - 30 * math.sin(progress * 20) # 添加行走动画效果 self.screen.blit(self.robot_img, (robot_x - 25, robot_y - 40)) # 绘制风力效果 if np.linalg.norm(scenario_state['wind']) > 0.1: wind_dir = scenario_state['wind'] / np.linalg.norm(scenario_state['wind']) for i in range(5): offset = i * 20 pygame.draw.line(self.screen, (100, 150, 255), (robot_x + 30 + offset, robot_y - 20), (robot_x + 50 + offset + wind_dir[0] * 10, robot_y - 20 + wind_dir[1] * 10), 2) pygame.draw.polygon(self.screen, (100, 150, 255), [ (robot_x + 50 + offset + wind_dir[0] * 10, robot_y - 20 + wind_dir[1] * 10), (robot_x + 45 + offset + wind_dir[0] * 15, robot_y - 25 + wind_dir[1] * 15), (robot_x + 45 + offset + wind_dir[0] * 15, robot_y - 15 + wind_dir[1] * 15) ]) # 场景标题 scene_title = self.font.render(f"当前场景: {scenario_state['description']}", True, (30, 30, 100)) self.screen.blit(scene_title, (40, 290)) def _render_3d_view(self, demo): """渲染3D视图""" # 3D视图背景 pygame.draw.rect(self.screen, (250, 250, 255), (500, 70, 680, 300), 0, 10) pygame.draw.rect(self.screen, (200, 200, 220), (500, 70, 680, 300), 2, 10) # 添加标题 title = self.font.render("机器人3D视图", True, (30, 30, 100)) self.screen.blit(title, (510, 80)) # 检查渲染组件是否可用 if self.scene is None or self.context is None or demo.robot.model is None or self.using_software_rendering: error_text = self.font.render("3D渲染不可用: 使用软件渲染模式", True, (100, 100, 200)) self.screen.blit(error_text, (520, 150)) # 显示替代图像 pygame.draw.rect(self.screen, (200, 220, 240), (550, 150, 580, 200)) pygame.draw.circle(self.screen, (100, 150, 255), (700, 250), 60) pygame.draw.rect(self.screen, (100, 200, 100), (660, 200, 80, 100)) pygame.draw.line(self.screen, (0, 0, 0), (670, 300), (650, 350), 4) pygame.draw.line(self.screen, (0, 0, 0), (730, 300), (750, 350), 4) pygame.draw.line(self.screen, (0, 0, 0), (660, 230), (600, 250), 4) pygame.draw.line(self.screen, (0, 0, 0), (740, 230), (780, 250), 4) return try: # 更新3D场景 mujoco.mjv_updateScene( demo.robot.model, demo.robot.data, self.opt, None, self.camera, mujoco.mjtCatBit.mjCAT_ALL, self.scene) # 渲染到内存缓冲区 width, height = 680, 300 buffer = np.zeros((height, width, 3), dtype=np.uint8) viewport = mujoco.MjrRect(0, 0, width, height) mujoco.mjr_render(viewport, self.scene, self.context) # 获取渲染图像 mujoco.mjr_readPixels(buffer, None, viewport, self.context) # 转换为Pygame表面 img = Image.fromarray(buffer, 'RGB') img = img.transpose(Image.FLIP_TOP_BOTTOM) img_bytes = img.tobytes() py_image = pygame.image.fromstring(img_bytes, (width, height), 'RGB') # 绘制到屏幕 self.screen.blit(py_image, (500, 70)) except Exception as e: # 显示错误信息 error_text = self.font.render(f"3D渲染错误: {str(e)}", True, (255, 0, 0)) self.screen.blit(error_text, (510, 150)) # 记录详细错误日志 print(f"⚠️ 3D渲染错误详情: {traceback.format_exc()}") def _render_performance_charts(self, demo): """渲染性能图表""" # 性能面板背景 pygame.draw.rect(self.screen, (250, 250, 255), (500, 390, 680, 180), 0, 10) pygame.draw.rect(self.screen, (200, 200, 220), (500, 390, 680, 180), 2, 10) # 标题 title = self.font.render("性能指标", True, (30, 30, 100)) self.screen.blit(title, (510, 400)) # 绘制能量消耗图表 if len(demo.energy_consumption) > 1: points = [] max_energy = max(demo.energy_consumption) if max(demo.energy_consumption) > 0 else 1 for i, val in enumerate(demo.energy_consumption): x = 520 + (i / (len(demo.energy_consumption) - 1)) * 300 y = 550 - (val / max_energy) * 100 points.append((x, y)) if len(points) > 1: pygame.draw.lines(self.screen, (100, 150, 255), False, points, 2) # 绘制最后一个点 pygame.draw.circle(self.screen, (100, 150, 255), (int(points[-1][0]), int(points[-1][1])), 4) # 添加当前标签 value_text = self.font.render(f"{val:.1f}J", True, (100, 150, 255)) self.screen.blit(value_text, (int(points[-1][0]) + 5, int(points[-1][1]) - 10)) # 绘制稳定性图表 if len(demo.performance_metrics) > 1: points = [] max_stability = max([m['stability'] for m in demo.performance_metrics]) or 1 for i, metric in enumerate(demo.performance_metrics): x = 850 + (i / (len(demo.performance_metrics) - 1)) * 300 y = 550 - (metric['stability'] / max_stability) * 100 points.append((x, y)) if len(points) > 1: pygame.draw.lines(self.screen, (255, 150, 100), False, points, 2) # 绘制最后一个点 pygame.draw.circle(self.screen, (255, 150, 100), (int(points[-1][0]), int(points[-1][1])), 4) # 添加当前标签 value_text = self.font.render(f"{metric['stability']:.2f}", True, (255, 150, 100)) self.screen.blit(value_text, (int(points[-1][0]) + 5, int(points[-1][1]) - 10)) # 图表标签 energy_label = self.font.render("能量消耗", True, (100, 150, 255)) self.screen.blit(energy_label, (520, 560)) stability_label = self.font.render("稳定性指标", True, (255, 150, 100)) self.screen.blit(stability_label, (850, 560)) # 添加图表标题 pygame.draw.line(self.screen, (100, 150, 255), (520, 530), (540, 530), 3) pygame.draw.line(self.screen, (255, 150, 100), (850, 530), (870, 530), 3) def _render_instructions(self): """渲染控制说明""" # 控制说明背景 pygame.draw.rect(self.screen, (250, 250, 255), (20, 580, 1160, 100), 0, 10) pygame.draw.rect(self.screen, (200, 200, 220), (20, 580, 1160, 100), 2, 10) # 控制说明 instructions = [ "ESC: 退出程序", "空格键: 暂停/继续", "R键: 重置演示", "↑↓←→: 控制机器人移动", "C键: 切换摄像头视角", "S键: 保存性能数据" ] for i, text in enumerate(instructions): inst_text = self.font.render(text, True, (80, 80, 180)) self.screen.blit(inst_text, (40 + (i % 3) * 380, 600 + (i // 3) * 30)) def handle_events(self): """处理Pygame事件""" for event in pygame.event.get(): if event.type == QUIT: return False elif event.type == KEYDOWN: if event.key == K_ESCAPE: return False if event.key == K_SPACE: return "pause" elif event.key == K_r: return "reset" elif event.key == K_UP: return "move_forward" elif event.key == K_DOWN: return "move_backward" elif event.key == K_LEFT: return "move_left" elif event.key == K_RIGHT: return "move_right" elif event.key == K_c: return "change_camera" elif event.key == K_s: return "save_data" return True class HumanoidDemo: """人形机器人仿真演示类""" def __init__(self): """初始化演示系统""" print("🤖 人形机器人仿真演示系统") print("=" * 60) # 创建人形机器人 self.robot = self._create_robot() # 创建高级控制模块 self.decision_system = IntelligentDecisionSystem() self.path_planner = PathPlanner() self.energy_optimizer = EnergyOptimizer() self.adaptive_controller = AdaptiveController() # 创建可视化系统 - 传递机器人模型 self.visualization = VisualizationSystem( self.robot.model if hasattr(self.robot, 'model') else None ) # 演示配置 self.demo_config = { 'duration': 30.0, 'enable_ai': True, 'enable_optimization': True, 'enable_adaptation': True, 'record_data': True, 'save_video': False } # 演示数据 self.demo_data = { 'timestamps': [], 'robot_states': [], 'environment_states': [], 'decisions': [], 'energy_consumption': [0.0], 'performance_metrics': [{'stability': 1.0, 'efficiency': 1.0}] } # 运行状态 self.is_running = False self.current_time = 0.0 self.paused = False self.camera_mode = 0 # 0: 默认, 1: 跟随, 2: 第一人称 print("✅ 演示系统初始化完成") def _create_robot(self): """创建机器人实例,处理可能的错误""" try: return HumanoidRobot() except Exception as e: print(f"⚠️ 创建机器人时出错: {e}") print("⚠️ 使用模拟机器人替代") return HumanoidRobot() # 使用之前定义的模拟类 @property def energy_consumption(self): return self.demo_data['energy_consumption'] @property def performance_metrics(self): return self.demo_data['performance_metrics'] def setup_demo_scenario(self, scenario_type: str = "comprehensive"): """设置演示场景""" scenarios = { "comprehensive": self._setup_comprehensive_scenario, "walking": self._setup_walking_scenario, "obstacle": self._setup_obstacle_scenario, "terrain": self._setup_terrain_scenario, "interference": self._setup_interference_scenario } if scenario_type in scenarios: print(f"🎬 设置 {scenario_type} 演示场景...") scenarios[scenario_type]() else: print(f"⚠️ 未知场景类型: {scenario_type},使用综合场景") self._setup_comprehensive_scenario() def _setup_comprehensive_scenario(self): """设置综合演示场景""" self.scenario_timeline = [ [0, 5, "walking", "平地行走"], [5, 10, "obstacle", "动态避障"], [10, 15, "terrain", "斜坡行走"], [15, 20, "terrain", "楼梯攀爬"], [20, 25, "interference", "风力干扰"], [25, 30, "walking", "恢复行走"] ] self.environment_config = { 'obstacles': [ {'position': [2, 0, 0.5], 'radius': 0.3, 'type': 'static'}, {'position': [4, 1, 0.3], 'radius': 0.3, 'type': 'dynamic'}, {'position': [6, -1, 0.4], 'radius': 0.2, 'type': 'moving'} ], 'terrain_sequence': ['flat', 'slope', 'stairs', 'sand', 'flat'], 'wind_patterns': [ {'time': [20, 25], 'force': [50, 0, 0], 'type': 'gust'}, {'time': [25, 30], 'force': [20, 10, 0], 'type': 'steady'} ], 'light_patterns': [ {'time': [22, 24], 'intensity': 0.2, 'type': 'dim'}, {'time': [24, 26], 'intensity': 0.9, 'type': 'bright'} ] } def _setup_walking_scenario(self): """设置行走演示场景""" self.scenario_t极line = [ [0, 10, "walking", "基础行走"], [10, 20, "walking", "快速行走"], [20, 30, "walking", "慢速行走"] ] self.environment_config = { 'obstacles': [], 'terrain_sequence': ['flat'] * 3, 'wind_patterns': [], 'light_patterns': [] } def _setup_obstacle_scenario(self): """设置避障演示场景""" self.scenario_timeline = [ [0, 10, "obstacle", "静态障碍物"], [10, 20, "obstacle", "动态障碍物"], [20, 30, "obstacle", "复杂障碍物"] ] self.environment_config = { 'obstacles': [ {'position': [1, 0, 0.5], 'radius': 0.3, 'type': 'static'}, {'position': [3, 0, 0.3], 'radius': 0.2, 'type': 'dynamic'}, {'position': [5, 0, 0.4], 'radius': 0.25, 'type': 'moving'} ], 'terrain_sequence': ['flat'] * 3, 'wind_patterns': [], 'light_patterns': [] } def _setup_terrain_scenario(self): """设置地形演示场景""" self.scenario_timeline = [ [0, 6, "terrain", "平地"], [6, 12, "terrain", "斜坡"], [12, 18, "terrain", "楼梯"], [极8, 24, "terrain", "沙地"], [24, 30, "terrain", "平地"] ] self.environment_config = { 'obstacles': [], 'terrain_sequence': ['flat', 'slope', 'stairs', 'sand', 'flat'], 'wind_patterns': [], 'light_patterns': [] } def _setup_interference_scenario(self): """设置干扰演示场景""" self.scenario_timeline = [ [0, 10, "walking", "正常行走"], [10, 20, "interference", "风力干扰"], [20, 30, "interference", "光照干扰"] ] self.environment_config = { 'obstacles': [], 'terrain_sequence': ['flat'] * 3, 'wind_patterns': [ {'time': [10, 20], 'force': [80, 0, 0], 'type': 'strong_wind'} ], 'light_patterns': [ {'time': [20, 30], 'intensity': 0.1, 'type': 'low_light'} ] } def get_current_scenario_state(self, current_time: float) -> Dict: """获取当前场景状态""" current_task = "idle" task_description = "待机" # 确定当前任务 for start_time, end_time, task, description in self.scenario_timeline: if start_time <= current_time < end_time: current_task = task task_description = description break # 确定当前地形 terrain_index = min(int(current_time / 6), len(self.environment_config['terrain_sequence']) - 1) current_terrain = self.environment_config['terrain_sequence'][terrain_index] # 计算当前风力 current_wind = np.zeros(3) for wind_pattern in self.environment_config['wind_patterns']: if wind_pattern['time'][0] <= current_time < wind_pattern['time'][1]: current_wind = np.array(wind_pattern['force']) break # 计算当前光照 current_light = 1.0 for light_pattern in self.environment_config['light_patterns']: if light_pattern['time'][0] <= current_time < light_pattern['time'][1]: current_light = light_pattern['intensity'] break return { 'task': current_task, 'description': task_description, 'terrain': current_terrain, 'wind': current_wind, 'light': current_light, 'obstacles': self.environment_config['obstacles'].copy(), 'time': current_time } def update_robot_state(self): """更新机器人状态""" # 模拟机器人控制逻辑 # 这里应该调用实际的机器人控制模块 pass def change_camera_mode(self): """切换摄像头视角""" self.camera_mode = (self.camera_mode + 1) % 3 if self.visualization.camera: if self.camera_mode == 0: # 默认视角 self.visualization.camera.distance = 5.0 self.visualization.camera.elevation = -20 self.visualization.camera.azimuth = 90 elif self.camera_mode == 1: # 跟随视角 self.visualization.camera.distance = 3.0 self.visualization.camera.elevation = -10 self.visualization.camera.azimuth = 45 elif self.camera_mode == 2: # 第一人称视角 self.visualization.camera.distance = 1.5 self.visualization.camera.elevation = 0 self.visualization.camera.azimuth = 0 def record_data(self, current_time): """记录演示数据""" self.demo_data['timestamps'].append(current_time) # 模拟能量消耗 - 根据地形和任务类型变化 energy_factor = 1.0 if self.get_current_scenario_state(current_time)['terrain'] == 'slope': energy_factor = 1.5 elif self.get_current_scenario_state(current_time)['terrain'] == 'stairs': energy_factor = 1.8 elif self.get_current_scenario_state(current_time)['terrain'] == 'sand': energy_factor = 2.0 new_energy = self.energy_consumption[-1] + 0.1 * energy_factor self.energy_consumption.append(new_energy) # 模拟性能指标 stability = 1.0 - np.random.uniform(0, 0.1) efficiency = 1.0 - np.random.uniform(0, 0.05) self.performance_metrics.append({ 'stability': max(0.1, stability), 'efficiency': max(0.1, efficiency) }) def save_performance_data(self): """保存性能数据""" filename = f"performance_data_{time.strftime('%Y%m%d_%H%M%S')}.json" try: with open(filename, 'w') as f: json.dump({ 'timestamps': self.demo_data['timestamps'], 'energy_consumption': self.demo_data['energy_consumption'], 'performance_metrics': self.demo_data['performance_metrics'] }, f, indent=2) print(f"✅ 性能数据已保存到 {filename}") return True except Exception as e: print(f"⚠️ 保存性能数据失败: {e}") return False def run_demo(self): """运行演示""" print(f"🚀 开始演示,持续时间: {self.demo_config['duration']}秒") print("=" * 60) self.is_running = True start_time = time.time() try: while self.current_time < self.demo_config['duration']: # 处理事件 event_result = self.visualization.handle_events() if event_result == False: break elif event_result == "pause": self.paused = not self.paused elif event_result == "reset": start_time = time.time() self.current_time = 0.0 self.demo_data = { 'timestamps': [], 'energy_consumption': [0.0], 'performance_metrics': [{'stability': 1.0, 'efficiency': 1.0}] } elif event_result == "change_camera": self.change_camera_mode() elif event_result == "save_data": self.save_performance_data() if self.paused: time.sleep(0.1) continue # 更新当前时间 self.current_time = time.time() - start_time # 更新机器人状态 self.update_robot_state() # 记录数据 if self.demo_config['record_data']: self.record_data(self.current_time) # 渲染可视化界面 self.visualization.render_2d(self, self.current_time) # 控制帧率 self.visualization.clock.tick(30) self.is_running = False print("\n✅ 演示完成!") # 自动保存性能数据 if self.demo_config['record_data']: self.save_performance_data() except Exception as e: self.is_running = False print(f"\n⛔ 演示出错: {e}") traceback.print_exc() # 出错时保存当前数据 if self.demo_config['record_data']: print("⚠️ 尝试保存当前性能数据...") self.save_performance_data() finally: pygame.quit() def main(): """主函数""" parser = argparse.ArgumentParser(description='人形机器人仿真演示') parser.add_argument('--scenario', type=str, default='comprehensive', choices=['comprehensive', 'walking', 'obstacle', 'terrain', 'interference'], help='演示场景类型') parser.add_argument('--duration', type=float, default=30.0, help='演示持续时间(秒)') parser.add_argument('--no-opengl', action='store_true', help='强制禁用OpenGL加速') args = parser.parse_args() # 创建演示实例 demo = HumanoidDemo() demo.demo_config['duration'] = args.duration # 如果指定禁用OpenGL if args.no_opengl: os.environ['MUJOCO_GL'] = 'osmesa' print("⚠️ 已禁用OpenGL硬件加速") # 设置场景 demo.setup_demo_scenario(args.scenario) # 运行演示 demo.run_demo() if __name__ == "__main__": main()
07-31
# -*- coding: utf-8 -*- """ ============================ Python 导入机制详解 ============================ 版本:3.0 | 导入机制核心用法详解 """ # ==================== # 第一部分:导入机制概述 # ==================== """ Python导入机制的核心功能: 1. 代码复用:避免重复编写相同功能 2. 模块化组织:将功能拆分为独立模块 3. 命名空间管理:防止命名冲突 Python支持多种导入方式,主要包括以下8种: 1. 基本导入 (import module) 2. 别名导入 (import module as alias) 3. 选择性导入 (from module import name) 4. 多对象导入 (from module import name1, name2) 5. 通配符导入 (from module import *)【不推荐】 6. 相对导入 (from .module import name)【仅限包内】 7. 动态导入 (importlib.import_module("module")) 8. 延迟导入(函数/条件内部导入) """ # ==================== # 第二部分:导入方式详解 # ==================== # -------------------- # 1. 基本导入 (import) # -------------------- """ 基本导入将整个模块加载到当前命名空间 • 语法: import module_name • 访问方式: module_name.function() • 优点: 避免命名冲突 • 缺点: 代码稍长 """ import random # 导入随机数生成模块 def calculate_circle_area(radius): """基本导入示例1:计算圆面积""" # 使用math模块的pi常量 area = math.pi * radius ** 2 return area def generate_random_number(): """基本导入示例2:生成随机数""" # 使用random模块的randint函数 return random.randint(1, 100) # -------------------- # 2. 别名导入 (import as) # -------------------- """ 别名导入简化长模块名 • 语法: import module_name as alias • 访问方式: alias.function() • 优点: 简化代码,解决命名冲突 """ import datetime as dt # 导入datetime模块并使用别名dt import statistics as stats # 导入统计模块并使用别名stats def get_current_date(): """别名导入示例1:获取当前日期""" # 使用别名访问today()方法 return dt.date.today() def calculate_average(numbers): """别名导入示例2:计算平均""" # 使用别名调用mean函数 return stats.mean(numbers) # -------------------- # 3. 选择性导入 (from import) # -------------------- """ 选择性导入仅导入需要的部分 • 语法: from module_name import function_name • 访问方式: 直接使用函数名 • 优点: 代码简洁 • 缺点: 可能导致命名冲突 """ import math print(dir(math)) from math import sqrt # 仅导入平方根和阶乘函数 from collections import Counter # 仅导入Counter类 def calculate_square_root(number): """选择性导入示例1:计算平方根""" # 直接使用导入的sqrt函数 return sqrt(number) def count_word_frequency(words): """选择性导入示例2:统计词频""" # 直接使用导入的Counter类 return Counter(words) # -------------------- # 4. 多对象导入 (from import) # -------------------- """ 一次性导入多个对象 • 语法: from module import name1, name2 • 优点: 减少导入行数 • 缺点: 可能增加命名冲突风险 """ from math import pi # 导入多个数学常量/函数 from random import shuffle # 导入多个随机函数 def calculate_hypotenuse(a, b): """多对象导入示例1:计算斜边""" # 使用导入的sqrt函数(需导入) return sqrt(a ** 2 + b ** 2) def randomize_list(items): """多对象导入示例2:随机化列表""" # 复制列表避免修改原数据 copy = items[:] # 使用导入的shuffle函数 shuffle(copy) return copy # -------------------- # 5. 通配符导入 (from import *) # -------------------- """ 导入模块所有公共对象(不推荐) • 语法: from module import * • 优点: 快速访问所有功能 • 缺点: 易导致命名空间污染 • 建议: 仅用于交互式环境,生产代码避免使用 """ # 演示目的,实际不推荐使用 from math import * # 导入所有数学函数和常量 def calculate_circle_properties(radius): """通配符导入示例:计算圆属性""" # 直接使用导入的数学函数和常量 circumference = 2 * pi * radius area = pi * radius ** 2 return circumference, area # -------------------- # 6. 相对导入 (包内使用) # -------------------- """ 相对导入在包内部使用 • 语法: from . import module (同级模块) from .. import module (上级模块) from .submodule import func (子模块) • 优点: 避免绝对路径冲突 • 限制: 只能在包内使用,不能直接运行 相对导入是Python包内部模块间引用的核心机制,使用点号表示相对路径: 语法: 1. from . import module # 导入同级模块 2. from .module import function # 导入同级模块中的函数 3. from .. import parent_module # 导入上级模块 4. from ..subpackage import util # 导入上级目录的子包 5. from .submodule import Class # 导入当前包的子模块 关键限制: • 只能在包含__init__.py的包内使用 • 不能直接运行包含相对导入的模块 • 点号数量不能超过包层级 """ # 假设包结构: # my_package/ # ├── __init__.py # ├── utils.py # └── helpers/ # ├── __init__.py # └── calculations.py # 在utils.py中: # 导入同级 # 为什么需要演示脚本? # 当你在模块中使用 相对导入(from . import xxx) 时,Python 要求该模块必须作为包的一部分被导入,而不是直接运行。如果你直接运行这个模块(如 python module.py),Python 会把它当作 __main__ 模块,导致相对导入失败。 # # 为了解决这个问题,我们可以写一个独立的演示脚本(demo.py),作为程序的入口,来导入并运行你的模块。 # # from . import lesson4_1_function2 # 意思是:“从当前模块所在的包中导入另一个模块”。但如果这个模块是 __main__,它不是包的一部分,所以 Python 不知道 .(当前包)指的是什么。 """ __main__ 是什么? __main__ 是 Python 的一个特殊模块名。 当你执行命令如 python myfile.py,Python 会把 myfile.py 当作 __main__ 模块加载。 这时,在 myfile.py 中打印 __name__,结果就是 '__main__'。 __main__ 不属于任何包 由于 __main__ 是顶层模块,它没有所属的包信息。 所以在 __main__ 模块中使用相对导入(如 from . import xxx)会失败。 """ # # a = lesson4_1_function2.a() # # b = lesson4_1_function2.a # print("模块中打印的 b =", b) # # from 第四课 import module3_basic # # c = module3_basic.a() # -------------------- # 7. 动态导入(按需加载模块) # -------------------- # -*- coding: utf-8 -*- """ # 🧩 第7章:动态导入(按需加载模块) # 修正版:使用标准库模块演示动态导入 """ from textwrap import dedent # ================== 📚 理论讲解 ================== def explain_dynamic_import(): """ 🧠 什么是动态导入? 动态导入是指在运行时(Runtime)根据字符串动态加载模块的方式, 与传统的静态导入(import xxx)不同,它允许我们在程序运行过程中 灵活决定要加载哪个模块。 """ print(dedent(explain_dynamic_import.__doc__)) def when_to_use(): """ 🤔 什么时候用动态导入? - 需要根据配置、用户输入或环境决定模块 - 实现插件系统(如加载不同格式的解析器) - 模块体积大,需要按需加载 - 不同平台需要不同实现(如 Windows/Linux 工具) - 模块可能缺失,需要容错处理 """ print(dedent(when_to_use.__doc__)) def why_use_it(): """ ✅ 为什么用动态导入? - ✅ 灵活:运行时决定模块,支持插件化架构 - ✅ 解耦:主程序不依赖具体模块 - ✅ 节省内存:只在需要时加载模块 - ✅ 可扩展:新增模块无需修改主逻辑 - ✅ 容错:可优雅降级处理模块缺失或错误 """ print(dedent(why_use_it.__doc__)) def how_to_use(): """ 🛠️ 怎么用动态导入? Python 提供了多种动态导入方式: - 推荐方式:importlib.import_module() - 兼容方式:__import__() - 特殊方式(不推荐):exec("import xxx") 推荐优先使用 importlib.import_module() """ print(dedent(how_to_use.__doc__)) import importlib def dynamic_random(): """ 使用 importlib 动态导入 random 模块 并调用 randint 函数生成随机整数 """ try: # 动态导入 random 模块 """ importlib.import_module("math") import math importlib.import_module("pkg.math") from pkg import math importlib.import_module("math", package="pkg") from pkg import math(主要用于相对导入) """ module = importlib.import_module("random") # 调用 random.randint 函数 return module.randint(1, 100) except ImportError: return "错误:无法导入 random 模块" except AttributeError: return "错误:random 模块中没有该函数" # ================== 🔍 简化版演示 ================== def run_demo(): print("🧪 动态导入 random 模块演示:") # 生成一个随机数 result = dynamic_random() print(f"生成的随机数是:{result}") run_demo() # -------------------- # 8. 延迟导入 # -------------------- """ 延迟导入教学示例(Lazy Import) 展示模块在函数内部导入的用法及其优势 """ # ================== 🧠 理论讲解 ================== def explain_lazy_import(): print(""" ### 🕒 什么是延迟导入? 延迟导入(Lazy Import)是指将模块的导入操作推迟到**真正需要使用时**才执行, 而不是在程序启动或函数定义时立即导入。 """) print(""" ### ✅ 优点: - 减少程序启动时间 - 避免不必要的依赖加载 - 解决模块间的循环导入问题 """) # ================== 🧪 示例演示 ================== def generate_plot(x_values, y_values): """延迟导入示例:生成图表""" # matplotlib 体积较大,仅在需要绘图时导入 import matplotlib.pyplot as plt plt.plot(x_values, y_values) plt.title("函数关系图") plt.xlabel("X轴") plt.ylabel("Y轴") plt.show() def process_text(text): """延迟导入示例:文本处理""" # re 模块体积小,但只在需要文本处理时导入 import re # 正则表达式模块 # 移除多余空格 cleaned = re.sub(r'\s+', ' ', text) return cleaned.strip() # ================== 📋 演示主流程 ================== def run_demo(): print("🧪 延迟导入示例演示:\n") print("👉 示例 1:文本处理") sample_text = " 这是 一个 测试文本 " cleaned_text = process_text(sample_text) print(f"原始文本:'{sample_text}'") print(f"清理后:'{cleaned_text}'\n") print("👉 示例 2:生成图表(需要 matplotlib)") try: generate_plot([1, 2, 3, 4], [1, 4, 9, 16]) except ImportError: print("⚠️ matplotlib 未安装,请先使用 pip install matplotlib 安装\n") # ================== 🔄 延迟导入 vs 动态导入 ================== def compare_lazy_and_dynamic_import(): print("📌 延迟导入 vs 动态导入 的区别:\n") print(""" | 特性 | 延迟导入 | 动态导入 | |---------------------|----------------------------------|----------------------------------| | 实现方式 | 在函数中使用 import | 使用 importlib.import_module() | | 是否知道模块名 | 是,编译时已知 | 否,运行时决定 | | 是否提升启动性能 | 是 | 是 | | 是否支持插件系统 | 否 | 是 | | 是否解决循环导入 | 是 | 否(通常不用于此目的) | | 典型用途 | 按需加载功能模块 | 动态加载插件、配置驱动模块加载 | """) # ================== 📌 启动教学流程 ================== explain_lazy_import() print("=" * 50) run_demo() print("=" * 50) compare_lazy_and_dynamic_import() # ==================== # 第三部分:导入最佳实践 # ==================== """ 1. 导入顺序规范: a. Python标准库 (import os, sys) b. 第三方库 (import requests, pandas) c. 本地应用模块 (from myapp import utils) 2. 避免通配符导入: # 不推荐 from module import * # 推荐 from module import specific_function 3. 处理命名冲突: • 使用别名解决冲突 • 使用模块名前缀 4. 相对导入 vs 绝对导入: • 包内模块:优先使用相对导入 • 包外模块:使用绝对导入 5. 延迟导入技巧: • 在函数内部导入不常用的大模块 • 在条件分支中导入可选依赖 """ # ==================== # 总结 # ==================== """ Python导入机制要点: • 基本导入:适合大型模块,避免命名冲突 • 别名导入:简化长模块名,提高可读性 • 选择性导入:精简代码,但需注意命名空间 • 多对象导入:减少导入行数 • 通配符导入:仅建议在交互环境中使用 • 相对导入:包内模块引用的首选方式 • 动态导入:灵活加载模块 • 延迟导入:优化启动时间和解决循环依赖 合理选择导入方式,编写清晰、可维护的代码。 """ # 主程序入口 """ 防止导入时自动执行 当其他模块import当前脚本时,直接写在全局作用域的函数调用会立即执行。而使用if __name__...可将执行逻辑隔离,确保只有直接运行脚本时才触发。 提高代码复用性 你的脚本既能作为独立程序运行(python script.py),又能作为库被其他模块调用(import script),此时条件块外的函数/类可被复用,而条件块内的启动逻辑不会干扰导入方。 避免副作用污染 直接调用可能产生全局变量修改、资源占用等副作用 """ if __name__ == "__main__": print("=" * 50) print("导入机制演示开始") print("=" * 50) # 演示基本导入 print(f"半径为5的圆面积: {calculate_circle_area(5):.2f}") print(f"随机数: {generate_random_number()}") # 演示别名导入 print(f"当前日期: {get_current_date()}") print(f"平均: {calculate_average([10, 20, 30, 40]):.2f}") # 演示选择性导入 print(f"25的平方根: {calculate_square_root(25)}") word_count = count_word_frequency(["apple", "banana", "apple", "orange"]) print(f"词频统计: {dict(word_count)}") # 演示多对象导入 print(f"斜边长度(3,4): {calculate_hypotenuse(3, 4):.2f}") original = [1, 2, 3, 4, 5] print(f"随机化列表: {randomize_list(original)} (原列表: {original})") # 演示通配符导入 circumference, area = calculate_circle_properties(3) print(f"半径3的圆周长: {circumference:.2f}, 面积: {area:.2f}") # 演示动态导入 data = {"name": "Python", "version": 3.10} print(f"JSON格式数据: {format_data(data, 'json')}") # 演示延迟导入 text = "Python 是一种广泛使用的编程语言" print(f"处理后的文本: '{process_text(text)}'") print("=" * 50) print("导入演示完成") print("=" * 50) 代码报错了改下Traceback (most recent call last): File "C:\Users\Admin\Desktop\python自动化系列课程\第四课\lesson4\ceshi_1.py", line 508, in <module> print(f"JSON格式数据: {format_data(data, 'json')}") ^^^^^^^^^^^ NameError: name 'format_data' is not defined
最新发布
08-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值