艾萨克机器人引擎简介

2020-03-18  本文已影响0人  YottaYuan

艾萨克机器人引擎简介

基本

本节介绍Isaac机器人引擎的用法。它介绍了相关术语并解释了Isaac应用程序的结构。

Isaac应用程序由JavaScript对象表示法(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应用程序由四个部分定义:

定义了应用程序之后,接下来需要创建一个makefile。以下是BUILD与ping应用程序关联的 文件。

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",
    ],
)

小码

小码是使用Isaac构建的机器人应用程序的基本构建块。Isaac SDK包含可以在您的应用程序中使用的各种代码。如下例所示,派生您的小码。

为了更好地理解小代码,请参阅了解小代码部分。

以下Ping.hpp和Ping.cpp清单在以下位置显示了示例代码的来源 apps/tutorials/ping

// 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);
// 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小码可通过ISAAC_PROTO_RXISAAC_PROTO_TX宏与edgesJSON文件中的其他组件进行通信 。

// 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);
// 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
上一篇 下一篇

猜你喜欢

热点阅读