控制无人机无果,在油管评论区找到的思路
这篇文章主要讲的是emmm,如何在argos利用buzz脚本对无人机进行控制。流程清晰,按照我得方法指定能跑。第四部分为标题所对应的内容。
讲一下最近在干什么
这俩月老师给的需求是设计一种语言,对多个机器进行分布式控制、协调、调度。调研相关资料,问了一下gpt先生最相关的DSL(领域特定语言)有什么。BUZZ语言感觉是最贴切这个任务的,要把这个语言跑起来需要利用仿真器ARGoS3。OK那么进入正题 论文地址
确认一下环境
- A UNIX system (Linux or MacOSX; Microsoft Windows is not supported)
- g++ >= 4.3 (on Linux) or clang >= 3.1 (on MacOSX)
- cmake >= 2.8.12
安装仿真器ARGoS3
下载二进制文件argos3_simulator-3.0.0-x86_64-beta59.deb免去了cmke构建的过程
sudo apt install ./argos3_simulator-3.0.0-x86_64-beta59.deb
argos3 -v
验证完版本信息以后,需要看看这个argos3能不能用?github有一个仓库叫argos3-example有大量的例子,我们git clone一下
git clone https://github.com/ilpincy/argos3-examples.git argos3-examples
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make注意需要自己构建一下
遇到的问题:图形化界面弹不出来?缺少libglut.so.3 依赖
解决方法:
sudo apt update
sudo apt install -y libglut3.12 libglu1-mesa
ls -l /usr/lib/x86_64-linux-gnu/libglut.so*
ldconfig -p | grep libglut.so.3
sudo ln -sf /usr/lib/x86_64-linux-gnu/libglut.so.3.12.0 /usr/lib/x86_64-linux-gnu/libglut.so.3
sudo ln -sf /usr/lib/x86_64-linux-gnu/libglut.so.3.12.0 /lib/x86_64-linux-gnu/libglut.so.3
sudo ldconfig运行:
cd ~/argos3-examples
argos3 -c experiments/diffusion_1.argos
BUZZ获取
很好现在已经有仿真器了,如何得到buzz并且跑起来呢?
git clone https://github.com/buzz-lang/Buzz.git buzz
cd buzz
mkdir build && cd build
cmake ../src
make
sudo make install
sudo ldconfig构建完以后查看一下 
目录结构核对一下,解释一下里面的内容:
bzzrun→ Buzz 的解释器(运行.bzz程序的主入口,等价于你预期的buzz命令)。bzzasm→ Buzz 的汇编器,把 Buzz 汇编代码转成字节码。bzzdeasm→ Buzz 的反汇编器。bzzparse→ Buzz 解析器,用来调试语法。libbuzz.so/libbuzzdbg.so→ Buzz 的动态库。
如何在ARGoS中把Buzz脚本跑起来?
原理图:
来看一下buzz官方仓库的md文档,给的很笼统写不出demo例子。拷打了大模型先生两天无果,因为xml里面的一些组件根本就没有实现,当时怀疑是不是.so链接库和buzz版本不匹配实现不了?毕竟是十年前的产物,嫉妒怀疑自己。偶然间发现啊,Youtube视频下面讲buzz的有个人的评论

testing目录下面有buzz对应的例子,ok去找了一下
发现,
卧槽真能跑。OK了把argos文件和bzz喂给大模型,让他学习。 给了一个例子红蓝两队无人机,按照id进行分组利用buzz的swarm特性。
<?xml version="1.0" ?>
<argos-configuration>
<!-- ************************* -->
<!-- * General configuration * -->
<!-- ************************* -->
<framework>
<!--
system threads: 0 表示“使用所有可用 CPU 线程”,手动限核就填具体数字。
experiment:
length=0 表示“无限时长”,直到控制脚本主动停止或窗口关闭。
ticks_per_second: 仿真步频(Hz)。10 意味着每个 tick = 0.1s。
random_seed: 随机种子;固定种子可复现实验。
-->
<system threads="0" />
<experiment length="0"
ticks_per_second="10"
random_seed="123" />
</framework>
<!-- *************** -->
<!-- * Controllers * -->
<!-- *************** -->
<controllers>
<!-- Buzz 控制器(Spiri 四旋翼) -->
<buzz_controller_spiri id="bcs">
<actuators>
<!--
quadrotor_position: 位置控制执行 。
implementation="default" 常用即可。
-->
<quadrotor_position implementation="default" />
<!--
range_and_bearing: 近距通信与测距执行器(RAB 发射端)。
-->
<range_and_bearing implementation="default" />
</actuators>
<sensors>
<!--
RAB 传感器(接收端):
- implementation="medium" 代表该传感器连接到 id="rab" 的“通信媒介”。
- medium="rab" 必须与 <media> 中 id 匹配,否则无法通信。
- show_rays="false" 可视化时不画出射线。
-->
<range_and_bearing implementation="medium" medium="rab" show_rays="false" />
<!--
positioning: 位姿估计传感器;用于在Buzz中获取自身位姿。
-->
<positioning implementation="default" />
</sensors>
<!--
params:
- bytecode_file: Buzz 字节码文件,由 red_blue.bzz 编译而来。
- debug_file: 可选,记录 Buzz VM 调试信息,便于课后分析。
-->
<params bytecode_file="red_blue.bo"
debug_file="red_blue.bdb" />
</buzz_controller_spiri>
</controllers>
<!-- *********************** -->
<!-- * Arena configuration * -->
<!-- *********************** -->
<!--
arena: 尺寸与中心
- size="10, 10, 4" 表示 x=10m, y=10m, z=4m 的盒形空间。
- center="0,0,2" 将空间中心抬到 z=2,使地面位于 z=0。
教学建议:无人机默认在 z≈0 起始时要确保不与地面/障碍重叠;也可直接用定位控制上升到目标高度。
-->
<arena size="10, 10, 4" center="0,0,2">
<box id="wall_n" size="10, .1, 2" movable="false">
<body position="0, 4.95, 0" orientation="0,0,0" />
</box>
<box id="wall_s" size="10, .1, 2" movable="false">
<body position="0, -4.95, 0" orientation="0,0,0" />
</box>
<box id="wall_e" size=".1, 10, 2" movable="false">
<body position="4.95, 0, 0" orientation="0,0,0" />
</box>
<box id="wall_w" size=".1, 10, 2" movable="false">
<body position="-4.95, 0, 0" orientation="0,0,0" />
</box>
<!-- 随机投放 5 台机器人;数量要与 bzz 的 ROBOTS 一致
distribute: 在给定范围内“随机”投放实体。
position: 在 min/max 矩形内均匀采样 (z=0 表示从地面高度开始)。
orientation: 这里均匀分布在 yaw=0(固定朝向);如需随机朝向,把 max 改成 "0,0,360deg"。
entity quantity="5": 一次性生成 5 台 spiri;会自动生成 id: sp0..sp4。
-->
<distribute>
<position method="uniform" min="-1.5,-1.5,0" max="1.5,1.5,0" />
<orientation method="uniform" min="0,0,0" max="0,0,0" />
<entity quantity="5" max_trials="100">
<!--
spiri: 四旋翼机体
id="sp": 基名前缀,实际生成 sp0..sp4
rab_range="10": RAB 通信/感知半径(米);要覆盖全场可调大至 > 14 (对角线更长)。
rab_data_size="500": 单次发送的最大字节数;500 很大,演示富消息可用,但会增压性能。
<controller config="bcs" />: 绑定上面定义的 Buzz 控制器。
-->
<spiri id="sp" rab_range="10" rab_data_size="500">
<controller config="bcs" />
</spiri>
</entity>
</distribute>
</arena>
<!-- ******************* -->
<!-- * Physics engines * -->
<!-- ******************* -->
<physics_engines>
<pointmass3d id="pm3d" />
</physics_engines>
<!-- ********* -->
<!-- * Media * -->
<!-- ********* -->
<media>
<range_and_bearing id="rab" />
</media>
<!-- ****************** -->
<!-- * Visualization * -->
<!-- ****************** -->
<visualization>
<qt-opengl>
<camera>
<placement idx="0"
position="0,-12,7"
look_at="0,0,1"
lens_focal_length="15" />
<placement idx="1"
position="0,0,14"
look_at="0,0,0"
lens_focal_length="18" />
</camera>
<user_functions label="buzz_qt" />
</qt-opengl>
</visualization>
</argos-configuration>SPEED = 0.5 # 期望水平速度(m/s 近似;取决于底层控制器/物理引擎的解释)
LIM = 4.4 # “内缩边界”:场地墙在 ±4.95m,提前在 ±4.4m 处反弹,避免贴墙抖动
TARGET_RED = 1 # 红队枚举值
TARGET_BLUE = 2 # 蓝队枚举值
# 起飞阶段:起飞完成后分队并设定巡航方向
# 约定:takeoff() 在爬升过程返回 true,到达目标高度后返回 false
# 因此 not takeoff() 代表“起飞完成,可以切换状态”
# 分队规则:id 偶数 -> 红队(+X 方向),奇数 -> 蓝队(-X 方向)
function state_takeoff() {
if(not takeoff()) { # 起飞完成的那个 tick 进入分队初始化
if((id % 2) == 0) { # id 为内置的机器人唯一编号
mygroup = TARGET_RED
vx = SPEED; vy = 0.0 # 红队面向 +X 巡航
}
else {
mygroup = TARGET_BLUE
vx = -SPEED; vy = 0.0 # 蓝队面向 -X 巡航
}
statef = state_cruise # 状态机:函数指针切换到巡航
statestr = "cruise" # 记录文字状态,方便 debug 输出
}
}
# keep_inside:简单“弹性边界”
# 思路:若位置超出内缩阈值且速度仍朝外,就把该轴速度取反(镜像反弹)
# 使用 LIM=4.4 而不是 4.95,可显著降低贴墙卡顿和穿模风险
# 同一 tick 可同时触发 X/Y 两轴反弹(斜向撞边)
function keep_inside() {
var x = pose.position.x # pose 为定位传感器提供的自位姿;单位米
var y = pose.position.y
if(x > LIM and vx > 0.0) vx = -vx
if(x < -LIM and vx < 0.0) vx = -vx
if(y > LIM and vy > 0.0) vy = -vy
if(y < -LIM and vy < 0.0) vy = -vy
}
# 巡航状态:持续按 (vx, vy) 指定的平面速度飞行
# goto(vx, vy) 语义:水平速度指令(通常 m/s);高度由飞控/起飞逻辑维持
function state_cruise() {
keep_inside() # 每步先做边界约束,必要时反向
goto(vx, vy) # 下发速度指令;若 vx=vy=0 则悬停
}
# 初始化:设置状态机入口、清空分队与速度
function init() {
statef = state_takeoff # 初始进入起飞状态
statestr = "takeoff"
mygroup = 0 # 0 表示未分队
vx = 0.0; vy = 0.0
}
# 主循环:每个仿真 tick 调一次
# 先运行当前状态函数(statef)
# 再根据分队在调试通道打印状态与位置
function step() {
statef() # 调用当前状态
if(mygroup == TARGET_RED) {
debug.print(statestr, " RED pos=(", pose.position.x, ",", pose.position.y, ")")
}
else if(mygroup == TARGET_BLUE) {
debug.print(statestr, " BLUE pos=(", pose.position.x, ",", pose.position.y, ")")
}
else {
debug.print(statestr, " pos=(", pose.position.x, ",", pose.position.y, ")")
}
}
function destroy() { }执行一下:
bzzc red_blue.bzz
argos3 -c red_blue.argos 效果:
发现红的往一边飞,蓝的往一边飞。OK,后续继续拷打大模型,基础功能已经实现了。