跳到主要内容

例程

提供一个简易示例

准备工作

获取源代码

下载地址

获取控制台应用

下载地址

配置文件

使用配置文件对系统参数进行设置,详见Kernel通用配置MujocoKernel专有配置

主程序配置文件

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<bitbot>
<logger path="./log"/>

<backend port="12888" settings_file="./setting.json"/>

<mujoco file="./models/pendulum.xml"/>

<bus>
<device id="1" type="MujocoJoint" name="joint_x"
mode="position"
pos_kp='30' pos_kd='0' pos_ki='0' vel_kp='10' vel_kd='0'
/>
<device id="2" type="MujocoJoint" name="joint_y"
mode="position"
pos_kp='30' pos_kd='0' pos_ki='0' vel_kp='10' vel_kd='0'
/>
<device id="3" type="MujocoForceSensor" name="rfoot"
force="forcesensor" torque="torquesensor"
/>
<device id="4" type="MujocoImu" name="imu"
site="site_imu" acc="imu_acc" gyro="imu_gyro"
/>
</bus>
</bitbot>

后端配置文件

{
"control": [
{
"event": "enable_record",
"kb_key": "m"
},
{
"event": "stop",
"kb_key": " "
},
{
"event": "start",
"kb_key": "8"
},
{
"event": "test",
"kb_key": "t"
},
{
"event": "waiting",
"kb_key": "5"
},
{
"event": "add",
"kb_key": "1"
},
{
"event": "minus",
"kb_key": "2"
}
]
}

主程序

提示

请先阅读编程指南,熟悉相关概念

定义Kernel类型,可以简化后续的参数类型写法

struct UserData
{
double sin = 10;
};

using Kernel = bitbot::MujocoKernel<UserData, "time", "sin">;

主函数

int main(int argc, char const *argv[])
{
// 定义kernel对象,参数为配置文件
Kernel kernel("../../bitbot_pendulum.xml");

// 注册Config函数
kernel.RegisterConfigFunc(&ConfigFunc);
// 注册Finish函数
kernel.RegisterFinishFunc(&FinishFunc);

// 注册event
kernel.RegisterEvent("waiting", static_cast<bitbot::StateId>(Events::Wait), &EventWait, true);
kernel.RegisterEvent("test", static_cast<bitbot::StateId>(Events::Test), &EventTest);
kernel.RegisterEvent("add", static_cast<bitbot::StateId>(Events::Add), &EventAdd, true);
kernel.RegisterEvent("minus", static_cast<bitbot::StateId>(Events::Minus), &EventMinus, true);

// 注册state
kernel.RegisterState("waiting", static_cast<bitbot::StateId>(States::Waiting), &StateWaiting, {
static_cast<bitbot::StateId>(Events::Test)
});
kernel.RegisterState("joint_test", static_cast<bitbot::StateId>(States::JointSinPos), &StateJointSinPos, {});

// 设置用户的第一个state
kernel.SetFirstState(static_cast<bitbot::StateId>(States::Waiting));

// 运行
kernel.Run();

return 0;
}

配置函数

bitbot::MujocoJoint *joint_x, *joint_y;

void ConfigFunc(const bitbot::MujocoBus& bus, UserData&)
{
joint_x = bus.GetDevice<bitbot::MujocoJoint>(1).value();
joint_y = bus.GetDevice<bitbot::MujocoJoint>(2).value();
}

MujocoKernel使用MujocoBus总线管理器。通过GetDevice函数获取设备,需要指定设备对应类型,参数为设备id。

结束函数

void FinishFunc(UserData&)
{
std::cout << "finish" << std::endl;
}

程序退出时在终端打印finish

事件

EventWait

std::optional<bitbot::StateId> EventWait(bitbot::EventValue, UserData&)
{
return static_cast<bitbot::StateId>(States::Waiting);
}

转移至Waiting状态

EventTest

std::optional<bitbot::StateId> EventTest(bitbot::EventValue, UserData&)
{
return static_cast<bitbot::StateId>(States::JointSinPos);
}

转移至JointSinPos状态

EventAdd

std::optional<bitbot::StateId> EventAdd(bitbot::EventValue value, UserData& user_data)
{
if(user_data.sin < 60)
user_data.sin += 1;

return std::nullopt;
}

user_data进行操作,不发生状态转移

EventMinus

std::optional<bitbot::StateId> EventMinus(bitbot::EventValue value, UserData& user_data)
{
if(user_data.sin > 1)
user_data.sin -= 1;

return std::nullopt;
}

user_data进行操作,不发生状态转移

状态

StateWaiting

void StateWaiting(const bitbot::KernelInterface& kernel, Kernel::ExtraData& extra_data, UserData& user_data)
{
}

等待,不进行任何操作

StateJointSinPos

void StateJointSinPos(const bitbot::KernelInterface& kernel, Kernel::ExtraData& extra_data, UserData& user_data)
{
constexpr double deg2rad = M_PI / 180.0;
constexpr double rad2deg = 180.0 / M_PI;

static double start_time = 0;
static bool init = false;

if(joint_x->GetActualPosition()*rad2deg > 20)
{
std::cout << "stop!" << std::endl;
kernel.EmitEvent(static_cast<bitbot::EventId>(bitbot::KernelEvent::STOP), 0);
}

if(!init)
{
start_time = kernel.GetPeriodsCount()*0.004;
init=true;
}

double t = kernel.GetPeriodsCount()*0.004 - start_time;

joint_x->SetTargetPosition(user_data.sin*deg2rad*sin(4*M_PI*t));
extra_data.Set<0>(t);
extra_data.Set<"sin">(user_data.sin);
}

joint_x进行位置控制。更新extra_data值。