第十四节:物理引擎集成:Cannon.js入门

引言

物理引擎为3D世界注入真实感,让物体遵循重力、碰撞和动量等物理规律。Cannon.js是Three.js生态中最强大的物理引擎之一,本文将深入解析其核心机制,并通过Vue3实现物理沙盒系统,让你掌握动态仿真的核心技术。


在这里插入图片描述

1. 物理引擎基础
1.1 核心概念
物理世界
刚体
碰撞形状
约束
质量/位置/旋转
盒子/球体/圆柱
铰链/滑块/弹簧
1.2 工作流程
ThreeJSCannonJSRenderer创建物理体物理模拟更新位置/旋转渲染新状态ThreeJSCannonJSRenderer

2. Cannon.js核心API
2.1 初始化物理世界
<script setup>
import * as CANNON from 'cannon';
import * as THREE from 'three';// 创建物理世界
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0); // 设置重力
world.broadphase = new CANNON.NaiveBroadphase(); // 碰撞检测算法
world.solver.iterations = 10; // 求解器迭代次数
</script>
2.2 刚体与形状
// 创建刚体
const body = new CANNON.Body({mass: 5, // 质量 (0 = 静态)position: new CANNON.Vec3(0, 10, 0),shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1)) // 盒子形状
});// 添加物理世界
world.addBody(body);// 更多形状:
const sphereShape = new CANNON.Sphere(0.5); // 球体
const cylinderShape = new CANNON.Cylinder(0.5, 0.5, 2, 16); // 圆柱
const planeShape = new CANNON.Plane(); // 平面
2.3 材质与碰撞
// 创建材质
const concrete = new CANNON.Material('concrete');
const rubber = new CANNON.Material('rubber');// 定义接触材质
const concreteRubberContact = new CANNON.ContactMaterial(concrete,rubber,{friction: 0.8, // 摩擦系数restitution: 0.5 // 弹性系数}
);world.addContactMaterial(concreteRubberContact);

3. Three.js集成
3.1 物理-视觉同步
<script setup>
import { ref, onMounted } from 'vue';const physicsObjects = ref([]);// 添加物理对象
function addPhysicsObject(threeMesh, cannonBody) {physicsObjects.value.push({mesh: threeMesh,body: cannonBody});scene.add(threeMesh);world.addBody(cannonBody);
}// 同步位置
function syncPhysics() {physicsObjects.value.forEach(obj => {obj.mesh.position.copy(obj.body.position);obj.mesh.quaternion.copy(obj.body.quaternion);});
}// 物理更新循环
function physicsStep() {world.step(1/60); // 60FPSsyncPhysics();requestAnimationFrame(physicsStep);
}onMounted(physicsStep);
</script>
3.2 碰撞事件处理
// 碰撞事件监听
body.addEventListener('collide', (e) => {const impactStrength = e.contact.getImpactVelocityAlongNormal();// 播放声音if (impactStrength > 2) {playCollisionSound(impactStrength);}// 视觉反馈gsap.to(mesh.material.color, {r: 1, g: 0, b: 0,duration: 0.3,yoyo: true,repeat: 1});
});
3.3 射线检测
const raycaster = new CANNON.Ray();
const rayResult = new CANNON.RaycastResult();function castRay(from, to) {raycaster.origin.copy(from);raycaster.direction.copy(to).sub(from).normalize();raycaster.collisionMask = 1; // 碰撞组rayResult.reset();world.raycastClosest(raycaster, rayResult);if (rayResult.hasHit) {return {hitPoint: rayResult.hitPointWorld,body: rayResult.body};}return null;
}

4. 约束与关节
4.1 铰链关节
// 创建两个刚体
const bodyA = new CANNON.Body({ mass: 0 }); // 固定基座
const bodyB = new CANNON.Body({ mass: 1 }); // 可动部分// 创建铰链约束
const hinge = new CANNON.HingeConstraint(bodyA,bodyB,{pivotA: new CANNON.Vec3(0, 0, 0), // 基座连接点pivotB: new CANNON.Vec3(0, -1, 0), // 可动部分连接点axisA: new CANNON.Vec3(0, 0, 1), // 基座旋转轴axisB: new CANNON.Vec3(0, 0, 1)  // 可动部分旋转轴}
);// 添加约束
world.addConstraint(hinge);// 添加马达驱动
hinge.enableMotor();
hinge.setMotorSpeed(Math.PI); // 1转/秒
hinge.setMotorMaxForce(100);
4.2 弹簧约束
const spring = new CANNON.Spring(bodyA, // 物体AbodyB, // 物体B{localAnchorA: new CANNON.Vec3(0,0,0),localAnchorB: new CANNON.Vec3(0,0,0),restLength: 5, // 自然长度stiffness: 50,  // 刚度damping: 5      // 阻尼}
);// 手动更新(需每帧调用)
function updateSprings() {spring.applyForce();
}
4.3 点对点约束
const p2p = new CANNON.PointToPointConstraint(bodyA,new CANNON.Vec3(0,1,0), // 物体A连接点bodyB,new CANNON.Vec3(0,-1,0) // 物体B连接点
);// 设置最大力
p2p.maxForce = 100;
world.addConstraint(p2p);

5. 车辆控制器
5.1 车辆组装
function createCar() {const carBody = new CANNON.Body({ mass: 1000 });carBody.addShape(new CANNON.Box(new CANNON.Vec3(1.5, 0.5, 3)));const wheelBodies = [];const wheelPositions = [new CANNON.Vec3(-1, -0.5, 1.5),  // 前左new CANNON.Vec3(1, -0.5, 1.5),   // 前右new CANNON.Vec3(-1, -0.5, -1.5), // 后左new CANNON.Vec3(1, -0.5, -1.5)   // 后右];wheelPositions.forEach(pos => {const wheelBody = new CANNON.Body({ mass: 20 });wheelBody.addShape(new CANNON.Sphere(0.4));wheelBody.position.copy(pos);// 车轮约束const constraint = new CANNON.PointToPointConstraint(carBody,pos.clone(),wheelBody,new CANNON.Vec3(0,0,0));wheelBodies.push(wheelBody);world.addBody(wheelBody);world.addConstraint(constraint);});return { carBody, wheelBodies };
}
5.2 车辆控制
<script setup>
import { onMounted, onUnmounted } from 'vue';const car = ref(null);
const steering = ref(0);
const engineForce = ref(0);function initCar() {car.value = createCar();scene.add(createCarVisual(car.value));
}// 键盘控制
function onKeyDown(event) {switch(event.key) {case 'ArrowUp':engineForce.value = 500;break;case 'ArrowDown':engineForce.value = -300;break;case 'ArrowLeft':steering.value = Math.PI/8;break;case 'ArrowRight':steering.value = -Math.PI/8;break;}
}// 更新车辆
function updateCar() {if (!car.value) return;// 应用引擎力car.value.wheelBodies[0].applyLocalForce(new CANNON.Vec3(engineForce.value, 0, 0),new CANNON.Vec3(0,0,0));// 转向car.value.wheelBodies[0].quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0), steering.value);// 重置控制engineForce.value = 0;steering.value = 0;
}onMounted(() => {window.addEventListener('keydown', onKeyDown);world.addEventListener('postStep', updateCar);
});onUnmounted(() => {window.removeEventListener('keydown', onKeyDown);world.removeEventListener('postStep', updateCar);
});
</script>

6. 角色控制器
6.1 角色物理体
function createCharacter() {const body = new CANNON.Body({mass: 70, // 70kgposition: new CANNON.Vec3(0, 5, 0),fixedRotation: true // 防止摔倒});// 胶囊体形状const capsule = new CANNON.Capsule(0.3, 1.6);body.addShape(capsule);// 角色状态body.velocity = new CANNON.Vec3();body.canJump = true;return body;
}
6.2 角色移动控制
function updateCharacter(deltaTime) {if (!characterBody) return;// 键盘输入const direction = new CANNON.Vec3();if (keys.ArrowUp) direction.z = -1;if (keys.ArrowDown) direction.z = 1;if (keys.ArrowLeft) direction.x = -1;if (keys.ArrowRight) direction.x = 1;// 标准化方向if (direction.length() > 0) {direction.normalize();// 根据相机方向旋转移动向量const cameraQuat = new THREE.Quaternion();camera.getWorldQuaternion(cameraQuat);const rotatedDirection = direction.applyQuaternion(cameraQuat);// 应用移动力characterBody.velocity.x = rotatedDirection.x * 5;characterBody.velocity.z = rotatedDirection.z * 5;} else {// 摩擦力停止characterBody.velocity.x *= 0.9;characterBody.velocity.z *= 0.9;}// 跳跃if (keys.Space && characterBody.canJump) {characterBody.velocity.y = 8;characterBody.canJump = false;}// 检测地面const rayStart = characterBody.position.clone();rayStart.y -= 1.8; // 脚部位置const rayEnd = rayStart.clone();rayEnd.y -= 0.1;const result = castRay(rayStart, rayEnd);characterBody.canJump = result?.body?.material?.name === 'ground';
}
6.3 相机跟随
function updateCamera() {const charPos = characterBody.position;// 第三人称相机const offset = new THREE.Vector3(0, 2, 5);offset.applyQuaternion(camera.quaternion);camera.position.copy(charPos).add(offset);camera.lookAt(charPos.x, charPos.y + 1.6, charPos.z);
}

7. Vue3物理沙盒系统
7.1 项目结构
src/├── components/│    ├── PhysicsSandbox.vue  // 主沙盒│    ├── ObjectSpawner.vue   // 物体生成器│    ├── ConstraintCreator.vue // 约束工具│    └── PhysicsDebugger.vue // 物理调试└── App.vue
7.2 物理沙盒主组件
<!-- PhysicsSandbox.vue -->
<template><div class="physics-sandbox"><canvas ref="canvasRef"></canvas><div class="controls"><ObjectSpawner @spawn="spawnObject" /><ConstraintCreator :objects="sceneObjects" @create-constraint="createConstraint"/><PhysicsDebugger :world="world" /></div><div class="stats"><div>FPS: {{ stats.fps }}</div><div>物体数: {{ sceneObjects.length }}</div></div></div>
</template><script setup>
import { ref, reactive, onMounted } from 'vue';
import * as THREE from 'three';
import * as CANNON from 'cannon';
import { PhysicsDebugger } from './PhysicsDebugger.vue';// 物理世界
const world = ref(new CANNON.World());
world.value.gravity.set(0, -9.82, 0);// 场景对象
const sceneObjects = reactive([]);
const physicsObjects = ref([]);// 初始化场景
onMounted(() => {initScene();initGround();startPhysicsLoop();
});// 生成物体
function spawnObject(type) {const position = new THREE.Vector3(Math.random() * 10 - 5,10,Math.random() * 10 - 5);let threeObj, cannonBody;switch(type) {case 'box':threeObj = new THREE.Mesh(new THREE.BoxGeometry(1,1,1),new THREE.MeshStandardMaterial({ color: 0xff0000 }));cannonBody = new CANNON.Body({mass: 1,shape: new CANNON.Box(new CANNON.Vec3(0.5,0.5,0.5))});break;case 'sphere':threeObj = new THREE.Mesh(new THREE.SphereGeometry(0.5),new THREE.MeshStandardMaterial({ color: 0x00ff00 }));cannonBody = new CANNON.Body({mass: 1,shape: new CANNON.Sphere(0.5)});break;// 其他类型...}threeObj.position.copy(position);cannonBody.position.copy(position);scene.add(threeObj);world.value.addBody(cannonBody);sceneObjects.push(threeObj);physicsObjects.value.push({mesh: threeObj,body: cannonBody});
}// 创建约束
function createConstraint({ objectA, objectB, type }) {const bodyA = physicsObjects.value.find(o => o.mesh === objectA).body;const bodyB = physicsObjects.value.find(o => o.mesh === objectB).body;let constraint;switch(type) {case 'hinge':constraint = new CANNON.HingeConstraint(bodyA,bodyB,// 参数...);break;case 'spring':constraint = new CANNON.Spring(bodyA,bodyB,// 参数...);break;}world.value.addConstraint(constraint);
}
</script>
7.3 物理调试器
<!-- PhysicsDebugger.vue -->
<template><div class="physics-debugger"><button @click="toggleDebug">调试模式: {{ debugMode ? '开启' : '关闭' }}</button><div v-if="debugMode" class="debug-options"><label><input type="checkbox" v-model="showColliders">显示碰撞体</label><label><input type="checkbox" v-model="showContacts">显示接触点</label></div></div>
</template><script setup>
import { ref, watch } from 'vue';
import { CannonDebugger } from 'cannon-es-debugger';const props = defineProps(['world']);
const debugMode = ref(false);
const showColliders = ref(true);
const showContacts = ref(false);let debugRenderer = null;// 切换调试模式
function toggleDebug() {debugMode.value = !debugMode.value;
}// 初始化调试渲染器
watch(debugMode, (enabled) => {if (enabled && !debugRenderer) {debugRenderer = new CannonDebugger(scene, props.world, {color: 0x00ff00,scale: 1.0});}
});// 更新调试选项
watch([showColliders, showContacts], () => {if (debugRenderer) {debugRenderer.update(); // 需要自定义实现}
});
</script>
7.4 物体生成器
<!-- ObjectSpawner.vue -->
<template><div class="object-spawner"><button v-for="type in objectTypes" :key="type"@click="spawn(type)">{{ type }}</button></div>
</template><script setup>
const objectTypes = ['box', 'sphere', 'cylinder', 'car', 'character', 'chain'
];const emit = defineEmits(['spawn']);function spawn(type) {emit('spawn', type);
}
</script>
7.5 约束创建器
<!-- ConstraintCreator.vue -->
<template><div class="constraint-creator"><select v-model="selectedType"><option v-for="type in constraintTypes" :value="type">{{ type }}</option></select><div v-if="selectedObjectA && selectedObjectB">已选择: {{ selectedObjectA.name }} 和 {{ selectedObjectB.name }}<button @click="create">创建约束</button></div><div v-else><p>选择第一个物体</p><div class="object-list"><div v-for="obj in objects" :key="obj.uuid":class="{ selected: obj === selectedObjectA }"@click="selectObjectA(obj)">{{ obj.name || obj.type }}</div></div><div v-if="selectedObjectA"><p>选择第二个物体</p><div class="object-list"><div v-for="obj in objects" :key="obj.uuid":class="{ selected: obj === selectedObjectB }"@click="selectObjectB(obj)">{{ obj.name || obj.type }}</div></div></div></div></div>
</template><script setup>
import { ref } from 'vue';const props = defineProps(['objects']);
const emit = defineEmits(['create-constraint']);const constraintTypes = ['hinge', 'point', 'spring', 'slider'];
const selectedType = ref('hinge');
const selectedObjectA = ref(null);
const selectedObjectB = ref(null);function selectObjectA(obj) {selectedObjectA.value = obj;
}function selectObjectB(obj) {selectedObjectB.value = obj;
}function create() {if (selectedObjectA.value && selectedObjectB.value) {emit('create-constraint', {type: selectedType.value,objectA: selectedObjectA.value,objectB: selectedObjectB.value});resetSelection();}
}function resetSelection() {selectedObjectA.value = null;selectedObjectB.value = null;
}
</script>

8. 性能优化
8.1 碰撞检测优化
// 使用SAPBroadphase
world.broadphase = new CANNON.SAPBroadphase(world);
world.broadphase.useBoundingBoxes = true;// 设置碰撞组
const STATIC_GROUP = 1;
const DYNAMIC_GROUP = 2;
const CHARACTER_GROUP = 4;groundBody.collisionFilterGroup = STATIC_GROUP;
groundBody.collisionFilterMask = DYNAMIC_GROUP | CHARACTER_GROUP;characterBody.collisionFilterGroup = CHARACTER_GROUP;
characterBody.collisionFilterMask = STATIC_GROUP | DYNAMIC_GROUP;
8.2 休眠系统
// 启用休眠
world.allowSleep = true;// 设置休眠参数
body.sleepSpeedLimit = 0.1; // 速度阈值
body.sleepTimeLimit = 1.0;  // 休眠时间// 手动唤醒
body.wakeUp();
8.3 时间缩放
// 慢动作效果
world.timeScale = 0.5;// 暂停物理
world.pause();// 恢复物理
world.resume();
8.4 多线程计算
// 在Web Worker中运行物理
const physicsWorker = new Worker('physics-worker.js');function initPhysicsWorker() {physicsWorker.postMessage({type: 'init',gravity: [0, -9.82, 0]});
}function updatePhysics() {physicsWorker.postMessage({type: 'step',dt: 1/60,objects: getObjectStates()});physicsWorker.onmessage = (e) => {applyObjectStates(e.data);};
}// physics-worker.js
self.onmessage = (e) => {if (e.data.type === 'init') {world = new CANNON.World();world.gravity.set(...e.data.gravity);} else if (e.data.type === 'step') {// 更新物体状态e.data.objects.forEach(obj => {const body = getBodyById(obj.id);body.position.copy(obj.position);body.velocity.copy(obj.velocity);});// 物理步进world.step(e.data.dt);// 返回新状态const states = world.bodies.map(body => ({id: body.id,position: body.position,quaternion: body.quaternion}));self.postMessage(states);}
};

9. 常见问题解答

Q1:物体穿透怎么办?

  1. 增加求解器迭代次数:
    world.solver.iterations = 20;
    
  2. 减少时间步长:
    // 使用固定时间步长
    const fixedTimeStep = 1/120;
    world.step(fixedTimeStep);
    
  3. 使用连续碰撞检测:
    body.collisionResponse = true;
    body.ccdSpeedThreshold = 1.0;
    body.ccdIterations = 10;
    

Q2:如何优化大量物体的性能?

  1. 使用SAPBroadphase
  2. 启用休眠系统
  3. 简化碰撞形状
  4. 静态物体设为mass=0

Q3:角色控制器卡顿问题?

  1. 使用固定时间步长:
    const fixedTimeStep = 1/60;
    let accumulatedTime = 0;function animate(time) {accumulatedTime += deltaTime;while (accumulatedTime >= fixedTimeStep) {world.step(fixedTimeStep);accumulatedTime -= fixedTimeStep;}
    }
    
  2. 减少角色碰撞形状复杂度
  3. 限制物理更新频率

10. 总结

通过本文,你已掌握:

  1. 物理引擎核心概念与Cannon.js架构
  2. Three.js与Cannon.js集成技术
  3. 刚体、约束与关节系统
  4. 车辆与角色控制器实现
  5. 碰撞检测与物理事件处理
  6. Vue3物理沙盒系统开发
  7. 物理性能优化策略

核心价值:Cannon.js为Three.js应用带来真实物理行为,结合Vue3的响应式系统,实现交互式物理仿真环境,为游戏、模拟和可视化应用提供坚实基础。


下一篇预告

第十五篇:第一阶段总结:你的第一个3D网页
你将学习:

  • 综合应用前14篇知识
  • 产品级3D展示页开发
  • 响应式设计适配多端
  • 性能优化最佳实践
  • 部署与SEO优化
  • Vue3+Three.js项目架构

准备好将所学知识融会贯通了吗?让我们打造一个令人惊叹的3D产品展示页!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93456.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93456.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/93456.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二十四、Mybatis-基础操作-删除(预编译SQL)

mybatis环境准备概述与注意事项&#xff08;springboot项目引入三项必要的起步依赖&#xff09;项目目录结构mybatis基础操作-删除对应EmpMapper&#xff08;接口&#xff09;代码 package com.itheima.mapper;import org.apache.ibatis.annotations.*;Mapper public interface…

JavaScript 核心基础:类型检测、DOM 操作与事件处理

JavaScript 作为松散类型语言&#xff0c;掌握类型检测规则、DOM 元素获取方式及事件处理逻辑&#xff0c;是写出健壮代码的基础。本文系统梳理 JS 高频基础知识点&#xff0c;结合实战场景解析原理与用法&#xff0c;帮你建立清晰的知识框架。 一、JS 数据类型与类型检测&…

软件开发过程中的维护活动

软件开发过程中的维护活动软件维护是软件生命周期中持续时间最长、成本最高的阶段&#xff0c;它并非简单的“修理”&#xff0c;而是一系列旨在延长软件生命周期、保持其价值和适应性的工程化活动。研究表明&#xff0c;软件维护成本可占总成本的60%以上。理解并有效管理维护活…

STC8单片机驱动I2C屏幕:实现时间、日期与温湿度显示

STC8 单片机驱动 I2C 屏幕&#xff1a;实现时间、日期与温湿度显示 在单片机项目中&#xff0c;“数据可视化” 是核心需求之一 —— 将时间、温湿度等关键信息实时显示在屏幕上&#xff0c;能让项目更具实用性。本文以STC8 系列单片机为核心&#xff0c;搭配 I2C 接口的 OLED…

基于SpringBoot+Vue的智能消费记账系统(AI问答、WebSocket即时通讯、Echarts图形化分析)

&#x1f388;系统亮点&#xff1a;AI问答、WebSocket即时通讯、Echarts图形化分析&#xff1b;一.系统开发工具与环境搭建1.系统设计开发工具后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17前端&#xff1a; 技术…

[论文笔记] WiscKey: Separating Keys from Values in SSD-Conscious Storage

阅读 WiscKey 论文时随手记录一些笔记。 这篇论文的核心思想理解起来还是很简单的&#xff0c;但是具体涉及到实现还有一些想不明白的地方&#xff0c;后来看到 TiKV 的 Titan 实现也很有趣&#xff0c;索性把这些问题都记录下来并抛出来。 本文中和论文相关的内容&#xff0…

week1-[循环嵌套]画正方形

week1-[循环嵌套]画正方形 题目描述 输入一个正整数 nnn&#xff0c;请使用数字 000 到 999 拼成一个这样的正方形图案&#xff08;参考样例输入输出&#xff09;&#xff1a;由上至下、由左至右依次由数字 000 到 999 填充。每次使用数字 999 填充后&#xff0c;将从头使用数字…

在 Vue2 中使用 pdf.js + pdf-lib 实现 PDF 预览、手写签名、文字批注与高保真导出

本文演示如何在前端&#xff08;Vue.js&#xff09;中结合 pdf.js、pdf-lib 与 Canvas 技术实现 PDF 预览、图片签名、手写批注、文字标注&#xff0c;并导出高保真 PDF。 先上demo截图&#xff0c;后续会附上代码仓库地址&#xff08;目前还有部分问题暂未进行优化&#xff0…

tomcat 定时重启

tomcat 定时重启 定时重启的目的是:修复内存泄漏等问题,tomcat 长时间未重启,导致页面卡顿,卡死,无法访问,影响用户访问 1.编写脚本 su - tomcat [tomcat@u1abomap02 ~]$ ls restart_tomcat_gosi.sh tomcat_gosi.log vi restart_tomcat_gosi.sh #!/bin/bash# 定义日志目…

WinForm 简单用户登录记录器实现教程

目录 功能概述 实现思路 一、程序入口&#xff08;Program.cs&#xff09; 二、登录用户控件&#xff08;Login.cs&#xff09; 2.1 控件初始化与密码显示逻辑 2.2 登录控件设计器&#xff08;Login.Designer.cs&#xff09; 三、主窗体&#xff08;Form1.cs&#xff09…

docker 安装 使用

Docker安装 一键安装命令 sudo curl -fsSL https://get.docker.com| bash -s docker --mirror Aliyun启动docker sudo service docker startpull镜像加速配置 sudo vi /etc/docker/daemon.json输入下列内容&#xff0c;最后按ESC&#xff0c;输入 :wq! 保存退出。 {"regis…

无人机探测器技术解析

一、工作模式 无人机探测器通过多模式协同实现全流程防御闭环&#xff1a; 1. 主动扫描模式 雷达主动探测&#xff1a;发射电磁波&#xff08;如Ka/Ku波段&#xff09;&#xff0c;通过回波时差与多普勒频移计算目标距离、速度及航向&#xff0c;适用于广域扫描&#xff08;…

Linux学习-软件编程(进程与线程)

进程回收wait原型&#xff1a;pid_t wait(int *wstatus); 功能&#xff1a;回收子进程空间 参数&#xff1a;wstatus&#xff1a;存放子进程结束状态空间的首地址 返回值&#xff1a;成功返回回收到的子进程的PID失败返回-1WIFEXITED(wstatus)&#xff1a;测试进程是否正常结束…

大模型微调分布式训练-大模型压缩训练(知识蒸馏)-大模型推理部署(分布式推理与量化部署)-大模型评估测试(OpenCompass)

大模型微调分布式训练 LLama Factory与Xtuner分布式微调大模型 大模型分布式微调训练的基本概念 为什么需要分布式训练&#xff1f; 模型规模爆炸&#xff1a;现代大模型&#xff08;如GPT-3、LLaMA等&#xff09;参数量达千亿级别&#xff0c;单卡GPU无法存储完整模型。 …

物联网、大数据与云计算持续发展,楼宇自控系统应用日益广泛

在深圳某智慧园区的控制中心&#xff0c;管理人员通过云端平台实时监控着5公里外园区内每台空调的运行参数、每盏路灯的开关状态和每个区域的能耗数据。当系统检测到某栋楼宇的电梯运行振动异常时&#xff0c;大数据算法自动预判可能的故障点并推送维修建议&#xff1b;物联网传…

在实验室连接地下车库工控机及其数据采集设备

在实验室连接地下车库工控机及其数据采集设备 我们小组为项目的数据采集组&#xff0c;目前在车顶集成了一个工控机、两个激光雷达、两个摄像头、一个户外电源 由于地下车库蚊子太多了&#xff0c;我们可受不了这个苦&#xff0c;所以想坐在实验室吹着空调就能连接工控机来修改…

icmpsh、PingTunnel--安装、使用

用途限制声明&#xff0c;本文仅用于网络安全技术研究、教育与知识分享。文中涉及的渗透测试方法与工具&#xff0c;严禁用于未经授权的网络攻击、数据窃取或任何违法活动。任何因不当使用本文内容导致的法律后果&#xff0c;作者及发布平台不承担任何责任。渗透测试涉及复杂技…

系统思考:情绪内耗与思维模式

我们正在努力解决的问题&#xff0c;很多时候&#xff0c;根源就在我们自己。 在日常的工作和生活中&#xff0c;我们常常感到焦虑、内耗和失控。这些情绪和状态&#xff0c;似乎总是在不断循环。但如果停下来仔细思考&#xff0c;会发现&#xff0c;问题的背后&#xff0c;并不…

详解grafana k6 中stage的核心概念与作用

在Grafana k6中&#xff0c;​​Stage&#xff08;阶段&#xff09;​​ 是负载测试脚本的核心配置概念&#xff0c;用于动态控制虚拟用户&#xff08;VUs&#xff09;的数量随时间的变化。通过定义多个阶段&#xff0c;用户可以模拟真实场景中的流量波动&#xff08;如用户逐步…

JS 和 JSX 的区别

JS 和 JSX 是两种不同的概念&#xff0c;尽管它们都与 JavaScript 密切相关&#xff0c;尤其是在 React 开发中。以下是它们的主要区别&#xff1a;1. 定义JS (JavaScript): 一种通用的编程语言&#xff0c;用于开发动态网页、服务器端应用程序等。它是标准的 ECMAScript 语言。…