AMBF 简介
Asynchronous Multi-Body Framework (AMBF) 是一款用于机器人仿真的框架,采用了 Bullet 作为物理引擎,参照了 Gazebo 的仿真框架。其源代码参见 WPI-AIM/ambf
1. 总体简介
感觉 ambf 借鉴了 Gazebo 的框架,采用的是 World、Model、Object 的结构,附加各种 Plugin 模块,并扩展了 ROS 通信,可视化部分采用了 chai3d。基于 ambf 可快速搭建机器人仿真平台。ambf 的核心功能主要包括以下几个方面:
-
场景构建。与 Gazebo 类似,ambf 的场景包含在 world 中,并基于配置文件创建场景中的机器人、刚体、软体等对象。一般来说,机器人对象由 Model 表示,包含了各个刚体(连杆)、关节、传感器、驱动器等。每个 Model 一般由单独的 yaml 来配置。通过
xxx::createFromAttribute(..)
函数来创建。 -
物理仿真。创建好场景后,基于 bullet 实现物理仿真。
-
驱动器。可以理解成电机,或者是人为的夹持点,能够驱动物体产生位移/形变的给。
-
关节控制器。根据输入的指令和物体当前的状态,输出当前应施加在物体上的量(力、速度等),从而控制物体运动。
-
Plugin。主要的是 CommunicationPlugin,用于 ROS 通信等。
为了便于和 gym 等框架联合,还在 ambf_ros_modules 基础上创建了 AmbfEnv
,用于建立仿真环境。
2. afController / 关节控制器
在 AMBF 中,提供了两种控制器:afJointController
和 afCartesianController
,分别用于关节和刚体的控制。具体来说,是在每个控制器中设置了一组PID参数,在每个仿真布,根据当前值和设定值,计算当前应输出(向物理引擎写入的值)。例如:
double afJointController::computeOutput(double process_val, double set_point, double current_time){
uint n = queue_length - 1;
for (uint i = 0 ; i < n ; i++){
t[i] = t[i+1];
e[i] = e[i+1];
de[i] = de[i+1];
ie[i] = ie[i+1];
}
t[n] = current_time;
e[n] = set_point - process_val;
// Clamp freq to 10 KHZ
double dt = t[n] - t[n-1];
if (dt <= m_min_dt){
cerr << "WARNING! JOINT CONTROLLER dt = " << dt << " Sec. Clamping to " << m_min_dt << " Sec." << endl;
dt = m_min_dt;
}
de[n] = (e[n] - e[n-1]) / dt;
ie[n] = Ie_sum + ((e[n] + e[n-1]) / 2 * dt);
Ie_sum = ie[n];
output = (m_P * e[n]) + (m_I * ie[n]) + (m_D * de[n]);
return output;
}
btVector3 afCartesianController::computeOutput<btVector3, btVector3>(const btVector3 &process_val, const btVector3 &set_point, const double &dt, const double &ts){
btVector3 output(0, 0, 0); // Initialize the output to zero
if (isEnabled()){
btVector3 dPos_prev, ddPos;
dPos_prev = m_dPos;
m_dPos = set_point - process_val;
ddPos = (m_dPos - dPos_prev) / dt;
output = P_lin * (m_dPos) * ts + D_lin * (ddPos);
}
else{
// Maybe throw a console warning to notify the user that this controller is disabled
}
return output;
}
具体的工作流程一般是这样的,在 ModelCommunicationPlugin 等插件类中,会实时地从通信接口(如ambf_server)读取控制指令(位置信息),然后调用 commandPosition(...)
函数,在该函数中,调用 m_controller->computeOutput(..)
并将结果写入物理引擎(如对刚体/关机施加一定地力矩)。
那么,控制指令地传递流程为:用户 -> ambf_client -> ambf_server -> XxxCommunicationPlugin -> afObject::commandPosition -> afController::computeOutput -> Bullet::ApplyEffort
ROS 通信部分可参见 AMBF ROS通信模块 / ambf_ros_modules
3. ambf_controller
在 ambf_controller/rave2/ 中,提供了一款机器人控制器,能够实现目标跟随 trace_cube、贵为 go_home 和 sine_dance 等功能。其思路是,与 ambf_client 类似,通过 ros 与 机器人的 ambf_server 通信。接收机器人的位置,并给到 planner,并计算出机器人的设定位置,通过 ros 发送给 ambf_server。从而实现了机器人任务的控制。这里面主要涉及的内容,一方面是ros通信,另一方面就是机器人运动的正解/逆解。
与 Client 相比,ambf_controller 能实现任务逻辑,而 Client 仅是通信/发送指令。
4. afSensor
在 AMBF 中,Sensor 和物体类似,是继承自 afBaseObject
。在每个仿真步骤中,通过执行 afSensor::update(..)
来执行具体的操作,比如,检测传感器状态,执行判断逻辑等。