Isaac ENGINE入门教程-介绍
Isaac ENGINE入门教程-介绍
说明:
- 介绍Isaac Robotics Engine的使用方法,相关术语并解释了Isaac应用程序的结构。
Isaac Robotics Engine:
- Isaac应用程序由JavaScript Object Notation(JSON)文件定义。
- 以下示例位于Isaac SDK中apps/tutorials/ping/ping.app.json,显示了基本格式。
{
"name": "ping",
"modules": [
"//apps/tutorials/ping:ping_components"
],
"graph": {
"nodes": [
{
"name": "ping",
"components": [
{
"name": "ping",
"type": "isaac::Ping"
}
]
}
],
"edges": []
},
"config": {
"ping" : {
"ping" : {
"tick_period" : "1Hz"
}
}
}
}
- Isaac应用程序由四个部分定义:
name
是一个带有应用程序名称的字符串。modules
是正在使用的库列表。 在上面的例子中,我们包括:
//apps/tutorials/ping:ping_components
以便“apps/tutorials/ping/Ping.cpp”可用。- Isaac SDK附带高质量且经过良好测试的软件包,我们可以将其作为模块导入。
- 较长的模块示例将在本教程的后面部分中显示。
graph
有两个子部分来定义应用程序的功能:
nodes
是我们应用程序的基本块。- 在这个简单的例子中,我们只有一个名为“ping”的节点,它有一个组件。
- 请注意,此组件的类型
isaac::Ping
与apps/tutorials/ping/Ping.hpp
的最后一行匹配。 - 典型的Isaac应用程序具有多个节点,并且每个节点通常具有多个组件。
edges
将组件连接在一起并实现它们之间的通信。- 此示例不需要连接任何组件。
config
允许您根据我们的用例调整每个节点的参数。
在此示例中,指定ping组件应以1赫兹为单位。
定义了应用程序后,接下来需要创建一个makefile。
以下是与ping应用程序关联的BUILD文件。
load("//engine/build:isaac.bzl", "isaac_app", "isaac_cc_module")
isaac_cc_module(
name = "ping_components",
srcs = ["Ping.cpp"],
hdrs = ["Ping.hpp"],
visibility = ["//visibility:public"],
deps = ["//engine/alice"],
)
isaac_app(
name = "ping",
data = ["fast_ping.json"],
modules = [
"//apps/tutorials/ping:ping_components",
],
)
Codelets说明
Codelet是使用Isaac构建的机器人应用程序的基本构建块。
Isaac SDK包含可在您的应用程序中使用的各种codelet。
导出您的codelet,如下例所示。
有关更好地理解codelet的信息,请参阅了解Codelet部分。
以下Ping.hpp和Ping.cpp列表显示了apps/tutorials/ping示例codelet的源代码:
Ping.hpp源代码
// This is the header file located at apps/tutorials/ping/Ping.hpp
#pragma once
#include <string>
#include "engine/alice/alice.hpp"
namespace isaac {
// A simple C++ codelet that prints periodically
class Ping : public alice::Codelet {
public:
// Has whatever needs to be run in the beginning of the program
void start() override;
// Has whatever needs to be run repeatedly
void tick() override;
// Message to be printed at every tick
ISAAC_PARAM(std::string, message, "Hello World!");
};
} // namespace isaac
ISAAC_ALICE_REGISTER_CODELET(isaac::Ping);
- Ping.cpp源代码
// This is the C++ file located at apps/tutorials/ping/Ping.cpp
#include "Ping.hpp"
namespace isaac {
void Ping::start() {
// This part will be run once in the beginning of the program
// We can tick periodically, on every message, or blocking. The tick period is set in the
// json ping.app.json file. You can for example change the value there to change the tick
// frequency of the node.
// Alternatively you can also overwrite configuration with an existing configuration file
// like in the example file fast_ping.json. Run the application like this to use an
// additional config file:
// bazel run //apps/tutorials/ping -- --config apps/tutorials/ping/fast_ping.json
tickPeriodically();
}
void Ping::tick() {
// This part will be run at every tick. We are ticking periodically in this example.
// Print the desired message to the console
LOG_INFO(get_message().c_str());
}
} // namespace isaac
完整的应用程序
- 下面显示的应用程序功能更强大
- 具有包含多个节点的图形,具有多个组件的节点,节点之间的边缘以及接收和传输消息的小程序。
- 首先查看JSON文件以查看边缘的定义方式。
- 请注意,此文件比上面的ping示例长,但它遵循相同的语法。
{
"name": "proportional_control_cpp",
"modules": [
"//apps/tutorials/proportional_control_cpp:proportional_control_cpp_codelet",
"navigation",
"segway",
"sensors:joystick",
"viewers"
],
"config": {
"cpp_controller": {
"isaac.ProportionalControlCpp": {
"tick_period": "10ms"
}
},
"segway_rmp": {
"isaac.SegwayRmpDriver": {
"ip": "192.168.0.40",
"tick_period": "20ms",
"speed_limit_angular": 1.0,
"speed_limit_linear": 1.0,
"flip_orientation": true
},
"isaac.alice.Failsafe": {
"name": "segway"
}
},
"diffbase_joystick": {
"isaac.alice.FailsafeHeartbeat": {
"interval": 0.25,
"failsafe_name": "segway",
"heartbeat_name": "deadman_switch"
},
"isaac.navigation.RobotRemoteControl": {
"tick_period": "10ms"
}
},
"odometry": {
"isaac.navigation.DifferentialBaseOdometry": {
"tick_period": "100Hz"
}
},
"websight": {
"WebsightServer": {
"webroot": "packages/sight/webroot",
"assetroot": "/home/nvidia/isaac-lfs/sight/assets",
"port": 3000,
"ui_config": {
"windows": {
"Proportional Control C++": {
"renderer": "plot",
"channels": [
{
"name": "proportional_control_cpp/cpp_controller/isaac.ProportionalControlCpp/reference (m)"
},
{
"name": "proportional_control_cpp/cpp_controller/isaac.ProportionalControlCpp/position (m)"
}
]
}
}
}
}
}
},
"graph": {
"nodes": [
{
"name": "cpp_controller",
"components": [
{
"name": "message_ledger",
"type": "isaac::alice::MessageLedger"
},
{
"name": "isaac.ProportionalControlCpp",
"type": "isaac::ProportionalControlCpp"
}
]
},
{
"name": "segway_rmp",
"components": [
{
"name": "message_ledger",
"type": "isaac::alice::MessageLedger"
},
{
"name": "isaac.SegwayRmpDriver",
"type": "isaac::SegwayRmpDriver"
},
{
"name": "isaac.alice.Failsafe",
"type": "isaac::alice::Failsafe"
}
]
},
{
"name": "odometry",
"components": [
{
"name": "message_ledger",
"type": "isaac::alice::MessageLedger"
},
{
"name": "isaac.navigation.DifferentialBaseOdometry",
"type": "isaac::navigation::DifferentialBaseOdometry"
}
]
},
{
"name": "joystick",
"components": [
{
"name": "message_ledger",
"type": "isaac::alice::MessageLedger"
},
{
"name": "isaac.Joystick",
"type": "isaac::Joystick"
}
]
},
{
"name": "diffbase_joystick",
"components": [
{
"name": "message_ledger",
"type": "isaac::alice::MessageLedger"
},
{
"name": "isaac.navigation.RobotRemoteControl",
"type": "isaac::navigation::RobotRemoteControl"
},
{
"name": "isaac.alice.FailsafeHeartbeat",
"type": "isaac::alice::FailsafeHeartbeat"
}
]
}
],
"edges": [
{
"source": "segway_rmp/isaac.SegwayRmpDriver/segway_state",
"target": "odometry/isaac.navigation.DifferentialBaseOdometry/state"
},
{
"source": "odometry/isaac.navigation.DifferentialBaseOdometry/odometry",
"target": "cpp_controller/isaac.ProportionalControlCpp/odometry"
},
{
"source": "cpp_controller/isaac.ProportionalControlCpp/cmd",
"target": "diffbase_joystick/isaac.navigation.RobotRemoteControl/ctrl"
},
{
"source": "joystick/isaac.Joystick/js_state",
"target": "diffbase_joystick/isaac.navigation.RobotRemoteControl/js_state"
},
{
"source": "diffbase_joystick/isaac.navigation.RobotRemoteControl/segway_cmd",
"target": "segway_rmp/isaac.SegwayRmpDriver/segway_cmd"
}
]
}
}
- 文件isaac_app与ping示例非常相似。
- 但是,添加了此应用程序所需的“segway”等模块。
load("//engine/build:isaac.bzl", "isaac_app", "isaac_cc_module")
isaac_cc_module(
name = "proportional_control_cpp_codelet",
srcs = ["ProportionalControlCpp.cpp"],
hdrs = ["ProportionalControlCpp.hpp"],
visibility = ["//visibility:public"],
deps = [
"//engine/alice",
"//engine/gems/state:io",
"//messages",
"//messages/state:differential_base",
],
)
isaac_app(
name = "proportional_control_cpp",
app_json_file = "proportional_control_cpp.app.json",
modules = [
"//apps/tutorials/proportional_control_cpp:proportional_control_cpp_codelet",
"navigation",
"segway",
"sensors:joystick",
"viewers",
],
)
- 下面的ProportionalControlCpp codelet可以通过ISAAC_PROTO_RX和ISAAC_PROTO_TX宏以及JSON文件中的相关边缘与其他组件进行通信。
- ProportionalControlCpp.hpp源码
// This is the header file located at
// apps/tutorials/proportional_control_cpp/ProportionalControlCpp.hpp
#pragma once
#include "engine/alice/alice.hpp"
#include "messages/messages.hpp"
namespace isaac {
// A C++ codelet for proportional control
//
// We receive odometry information, from which we extract the x position. Then, using refence
// and gain parameters that are provided by the user, we compute and publish a linear speed
// command using `control = gain * (reference - position)`
class ProportionalControlCpp : public alice::Codelet {
public:
// Has whatever needs to be run in the beginning of the program
void start() override;
// Has whatever needs to be run repeatedly
void tick() override;
// List of messages this codelet recevies
ISAAC_PROTO_RX(Odometry2Proto, odometry);
// List of messages this codelet transmits
ISAAC_PROTO_TX(StateProto, cmd);
// Gain for the proportional controller
ISAAC_PARAM(double, gain, 1.0);
// Reference for the controller
ISAAC_PARAM(double, desired_position_meters, 1.0);
};
} // namespace isaac
ISAAC_ALICE_REGISTER_CODELET(isaac::ProportionalControlCpp)
- ProportionalControlCpp.cpp源码
// This is the C++ file located at
// apps/tutorials/proportional_control_cpp/ProportionalControlCpp.cpp
#include "ProportionalControlCpp.hpp"
#include "engine/gems/state/io.hpp"
#include "messages/math.hpp"
#include "messages/state/differential_base.hpp"
namespace isaac {
void ProportionalControlCpp::start() {
// This part will be run once in the beginning of the program
// Print some information
LOG_INFO("Please head to the Sight website at <IP>:<PORT> to see how I am doing.");
LOG_INFO("<IP> is the Internet Protocol address where the app is running,");
LOG_INFO("and <PORT> is set in the config file, typically to '3000'.");
LOG_INFO("By default, local link is 'localhost:3000'.");
// We can tick periodically, on every message, or blocking. See documentation for details.
tickPeriodically();
}
void ProportionalControlCpp::tick() {
// This part will be run at every tick. We are ticking periodically in this example.
// Nothing to do if we haven't received odometry data yet
if (!rx_odometry().available()) {
return;
}
// Read parameters that can be set through Sight webpage
const double reference = get_desired_position_meters();
const double gain = get_gain();
// Read odometry message received
const auto& odom_reader = rx_odometry().getProto();
const Pose2d odometry_T_robot = FromProto(odom_reader.getOdomTRobot());
const double position = odometry_T_robot.translation.x();
// Compute the control action
const double control = gain * (reference - position);
// Show some data in Sight
show("reference (m)", reference);
show("position (m)", position);
show("control", control);
show("gain", gain);
// Publish control command
navigation::DifferentialBaseControl command;
command.linear_speed() = control;
command.angular_speed() = 0.0; // This simple example sets zero angular speed
ToProto(command, tx_cmd().initProto());
tx_cmd().publish();
}
} // namespace isaac
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号