跳转至

PND CPP SDK

简介

PND cpp sdk基于C++14标准开发,可为操作PND设备(PSA、RCU、PNDEncoder)提供简单灵活的方式,包括读写PSA参数,控制PSA运动、读写RCU参数、读取PNDEncoder角度等功能。

英文名 中文名 描述
PSA 执行器 PSA系列执行器具有高通信、高扭矩密度、一体化、标准化关节组件,为细分行业提供智能化一站式方案,共同打造行业标杆案例,专为机器人应用而设计。
RCU 机器人控制单元 RCU是一款支持PSA系列执行器供电的电源模块,集EthernetUDP通讯配置及功率制动等功能于一体,支持多路标准RJ45通信接口和多种电源输出接口,可为多个执行器的不同用电需求提供可靠保障。
PNDEncoder 绝对编码器 是一款为PNDbotics机器人关节执行器提供末端位置检测的模块。它具备Ethernet或Wi-Fi通讯配置及获取绝对角度等一系列功能,可为机器人主控提供关节末端绝对位置信息。

支持平台

推荐使用Linux x64平台,其他平台尚未得到充分验证。

  • Linux
    • x64
    • arm32
    • arm64
  • MacOS
    • x64
    • arm64

例子

搜索在网设备

ol_lookup.cpp
#include <iostream>
#include <thread>

#include "lookup.hpp"

using namespace Pnd;

int main() {
  std::string str("10.10.10.255");
  pndSetLogLevel("INFO", "INFO");
  Lookup lookup(&str);
  // After construction,start the background thread lookup actuator Wait 1 seconds for the module list to populate, and
  // then print out its contents
  std::this_thread::sleep_for(std::chrono::seconds(1));
  lookup.setLookupFrequencyHz(0);  // set lookup stop

  std::shared_ptr<Group> group = lookup.getGroupFromFamily("Default");
  if (!group) {
    std::cout << "Group not found! Check that the family and name of a module "
                 "on the network"
              << std::endl
              << "matches what is given in the source file." << std::endl;
    return -1;
  }
  std::cout << std::endl << "group size: " << group->size() << std::endl;

  group = lookup.getGroupFromFamily("PNDriver");
  std::cout << std::endl << "PNDriver group size: " << group->size() << std::endl;

  auto entry_list = lookup.getEntryList();
  for (const auto &entry : *entry_list) {
    std::cout << "Name: " << entry.name_ << std::endl;
    std::cout << "Family: " << entry.family_ << std::endl;
  }
  return 0;
}

使用以下命令搜索在网设备:

$ cd examples/project/cmake
$ cmake -B build
$ cmake --build build -j7
$ cd ../../bin
$ ./01_lookup
[2024-01-17 14:21:10.091] [info] [t 6291581] Broadcast: 10.10.10.255
[2024-01-17 14:21:10.592] [info] [t 6291585] abs broadcast start.

group size: 1

PNDriver group size: 1
Name: RCU0
Family: RCU
Name: PNDriver1
Family: PNDriver
Name: IO2
Family: IO
Name: PNDencoder3
Family: PNDencoder

PSA Control

位置控制

position_pt.cpp
#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>

#include "groupCommand.hpp"
#include "groupFeedback.hpp"
#include "lookup.hpp"

using namespace Pnd;

int main() {
  std::string str("10.10.10.255");
  pndSetLogLevel("ERROR", "INFO");
  // After construction,start the background thread lookup actuator
  Lookup lookup(&str);
  // Wait 1 seconds for the module list to populate, and then print out its
  // contents
  std::this_thread::sleep_for(std::chrono::seconds(1));
  lookup.setLookupFrequencyHz(0);

  auto group = lookup.getGroupFromFamily("Default", 150);

  if (!group) {
    std::cout << "Group not found! Check that the family and name of a module "
                 "on the network"
              << std::endl
              << "matches what is given in the source file." << std::endl;
    return -1;
  }

  std::cout << "group size: " << group->size() << std::endl;
  GroupCommand group_command(group->size());

  GroupFeedback group_feedback(group->size());

  group_command.enable(std::vector<float>(group->size(), 0));
  group->sendCommand(group_command);
  std::this_thread::sleep_for(std::chrono::milliseconds(100));
  auto ret = group->getNextFeedback(group_feedback, 10);
  if (ret) {
    for (int i = 0; i < group_feedback.size(); ++i) {
      if (group_feedback[i]->enabled) {
        std::cout << "disable failed!" << std::endl;
        exit(-1);
      }
    }
  }

  group_command.resetLinearCount(std::vector<float>(group->size(), 0));
  group->sendCommand(group_command);

  group_command.enable(std::vector<float>(group->size(), 1));
  group->sendCommand(group_command);

  std::this_thread::sleep_for(std::chrono::milliseconds(100));
  ret = group->getNextFeedback(group_feedback, 10);
  if (ret) {
    for (int i = 0; i < group_feedback.size(); ++i) {
      if (!group_feedback[i]->enabled) {
        std::cout << "enable failed!" << std::endl;
        exit(-1);
      }
    }
  }

  std::vector<PosPtInfo> pos_pt_infos;
  std::vector<PosPtInfo> pre_pos_infos;
  PosPtInfo pos;
  int timeout_num = 0;
  int next_feedback_timeout = 0;

  for (int j = 0; j < 10000; ++j) {
    ret = group->getNextFeedback(group_feedback, 10);
    if (!ret) { // get next feedback failed
      next_feedback_timeout++;
      continue;
    }
    for (int i = 0; i < group_feedback.size(); ++i) {
      if (std::isnan(group_feedback[i]->position)) { // timeout
        timeout_num++;
        pos.pos = pre_pos_infos.at(i).pos;
      } else {
        pos.pos = sin(j * 0.002 * M_PI) * 3;
      }
      pos.vel_ff = 0.0;
      pos.torque_ff = 0.0;
      pos_pt_infos.push_back(pos);
    }
    pre_pos_infos = pos_pt_infos;
    group_command.setInputPositionPt(pos_pt_infos);
    group->sendCommand(group_command);
    pos_pt_infos.clear();
    std::cout << "sdk command duration:" << group_feedback.Duration() << " us" << std::endl;

    std::this_thread::sleep_for(std::chrono::milliseconds(4));
  }

  group_command.enable(std::vector<float>(group->size(), 0));
  group->sendCommand(group_command);
  std::cout << "feedback timeout:" << next_feedback_timeout << " recv timeout:" << timeout_num << std::endl;

  return 0;
}

速度控制

velocity_pt.cpp
#include <iostream>
#include <thread>

#include "groupCommand.hpp"
#include "groupFeedback.hpp"
#include "lookup.hpp"

using namespace Pnd;

int main() {
  std::string str("10.10.10.255");

  // After construction,start the background thread lookup actuator
  Lookup lookup(&str);

  // Wait 1 seconds for the module list to populate, and then print out its
  // contents
  std::this_thread::sleep_for(std::chrono::seconds(1));
  lookup.setLookupFrequencyHz(0);  // set lookup stop

  std::shared_ptr<Group> group = lookup.getGroupFromFamily("Default");
  std::cout << std::endl << "group size: " << group->size() << std::endl;
  GroupCommand group_command(group->size());

  group_command.enable(std::vector<float>(group->size(), 1));
  group->sendCommand(group_command);
  // std::this_thread::sleep_for(std::chrono::seconds(1));

  group_command.setInputVelocityPt(std::vector<float>(group->size(), 10));
  group->sendCommand(group_command);
  std::this_thread::sleep_for(std::chrono::seconds(1));

  group_command.setInputVelocityPt(std::vector<float>(group->size(), 0));
  group->sendCommand(group_command);
  std::this_thread::sleep_for(std::chrono::seconds(1));

  for (int i = 1; i < 1000; ++i) {
    group_command.setInputVelocityPt(std::vector<float>(group->size(), i / 50.0));
    group->sendCommand(group_command);
    std::this_thread::sleep_for(std::chrono::milliseconds(4));
  }
  std::this_thread::sleep_for(std::chrono::seconds(1));

  group_command.setInputVelocityPt(std::vector<float>(group->size(), 0));
  group->sendCommand(group_command);

  group_command.enable(std::vector<float>(group->size(), 0));
  group->sendCommand(group_command);

  return 0;
}

电流控制

torque_pt.cpp
#include <iostream>
#include <thread>

#include "groupCommand.hpp"
#include "groupFeedback.hpp"
#include "lookup.hpp"

using namespace Pnd;

int main() {
  std::string str("10.10.10.255");

  // After construction,start the background thread lookup actuator
  Lookup lookup(&str);

  // Wait 1 seconds for the module list to populate, and then print out its
  // contents
  std::this_thread::sleep_for(std::chrono::seconds(1));
  lookup.setLookupFrequencyHz(0);  // set lookup stop

  std::shared_ptr<Group> group = lookup.getGroupFromFamily("Default");
  std::cout << std::endl << "group size: " << group->size() << std::endl;
  GroupCommand group_command(group->size());

  group_command.enable(std::vector<float>(group->size(), 1));
  group->sendCommand(group_command);
  std::this_thread::sleep_for(std::chrono::seconds(1));

  for (int i = 1; i < 6; ++i) {
    group_command.setInputTorquePt(std::vector<float>(group->size(), i));
    group->sendCommand(group_command);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  }
  std::this_thread::sleep_for(std::chrono::seconds(1));

  group_command.setInputTorquePt(std::vector<float>(group->size(), 0));
  group->sendCommand(group_command);

  group_command.enable(std::vector<float>(group->size(), 0));
  group->sendCommand(group_command);
  std::this_thread::sleep_for(std::chrono::seconds(1));

  return 0;
}

RCU Control

rcu.cpp
#include <iostream>
#include <thread>

#include "groupCommand.hpp"
#include "groupFeedback.hpp"
#include "lookup.hpp"

using namespace Pnd;

int main() {
  std::string str("10.10.10.255");
  Lookup lookup(&str);
  // After construction,start the background thread lookup actuator
  // Wait 1 seconds for the module list to populate, and then print out its
  // contents
  std::this_thread::sleep_for(std::chrono::seconds(1));
  lookup.setLookupFrequencyHz(0);  // set lookup stop

  std::shared_ptr<Group> group = lookup.getGroupFromFamily("RCU");
  if (!group) {
    std::cout << "Group not found! Check that the family and name of a module "
                 "on the network"
              << std::endl
              << "matches what is given in the source file." << std::endl;
    return -1;
  }
  std::cout << std::endl << "rcu group size: " << group->size() << std::endl;

  auto command = std::make_shared<GroupCommand>(group->size());
  auto feedback = std::make_shared<GroupFeedback>(group->size());

  bool flag = false;

  command->RcuPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuV5VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuAV5VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuV5VAPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuV5VBPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->Rcu12VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuFan12VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->Rcu19VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  RcuBrake rcu_brake;
  rcu_brake.brake_enable = false;
  rcu_brake.brake_overvoltage = 49.1;
  rcu_brake.brake_factor = 2049;
  std::vector<RcuBrake> rcu_brake_vec;
  for (int i = 0; i < group->size(); ++i) rcu_brake_vec.push_back(rcu_brake);
  command->RcuBrakeCmd(rcu_brake_vec);
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuAdcOffset(std::vector<float>(group->size(), 42));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  std::this_thread::sleep_for(std::chrono::seconds(2));

  flag = !flag;
  command->RcuPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuV5VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuAV5VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuV5VAPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuV5VBPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->Rcu12VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuFan12VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->Rcu19VPower(std::vector<bool>(group->size(), flag));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  rcu_brake.brake_enable = true;
  rcu_brake.brake_overvoltage = 49.0;
  rcu_brake.brake_factor = 2048;
  rcu_brake_vec.clear();
  for (int i = 0; i < group->size(); ++i) rcu_brake_vec.push_back(rcu_brake);
  command->RcuBrakeCmd(rcu_brake_vec);
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  command->RcuAdcOffset(std::vector<float>(group->size(), 0));
  group->sendCommand(*command);
  std::this_thread::sleep_for(std::chrono::milliseconds(20));

  return 0;
}

PNDEncoder Control

encoder.cpp
#include <iostream>
#include <thread>

#include "groupCommand.hpp"
#include "groupFeedback.hpp"
#include "lookup.hpp"

using namespace Pnd;

int main() {
  std::string str("10.10.10.255");
  Lookup lookup(&str);
  // After construction,start the background thread lookup actuator
  // Wait 1 seconds for the module list to populate, and then print out its
  // contents
  std::this_thread::sleep_for(std::chrono::seconds(1));
  lookup.setLookupFrequencyHz(0);  // set lookup stop
  pndSetLogLevel(NULL, NULL);

  std::shared_ptr<Group> group = lookup.getGroupFromFamily("PNDencoder");
  if (!group) {
    std::cout << "Group not found! Check that the family and name of a module "
                 "on the network"
              << std::endl
              << "matches what is given in the source file." << std::endl;
    return -1;
  }
  std::cout << std::endl << "group size: " << group->size() << std::endl;

  GroupCommand group_command(group->size());
  GroupFeedback group_feedback(group->size());
  group_command.getEncoderAngle(std::vector<float>(group->size(), 1));

  auto startTime = std::chrono::high_resolution_clock::now();
  auto duration = std::chrono::seconds(100);
  while (std::chrono::high_resolution_clock::now() - startTime < duration) {
    group->sendCommand(group_command);
    auto ret = group->getNextFeedback(group_feedback, 10);
    if (ret) {
      for (int i = 0; i < group_feedback.size(); ++i) {
        std::cout << group_feedback[i]->encoder_angle << std::endl;
      }
    } else {
      std::cout << "getNextFeedback failed!" << std::endl;
      exit(-1);
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
  }

  return 0;
}

接口说明

CPP

Lookup

下方Lookup类作用是搜索所有在网设备,通过getGroupXXX函数获取一组控制设备。

lookup.hpp
#pragma once
#include <memory>

#include "aios.h"
#include "group.hpp"
#include "util.hpp"

namespace Pnd {

/**
 * @brief Maintains a registry of network-connected modules and returns Group
 * objects to the user.
 *
 * Only one Lookup object is needed per application.
 */
class Lookup final {
 public:
  /**
   * @brief Creates a Lookup object which can create Module and Group
   * references.
   * Typically, only one Lookup object should exist at a time.
   *
   * Note that this call invokes a background thread to query the network for
   * modules at regular intervals.
   */
  Lookup(std::string *addr = nullptr);

  /**
   * @brief Destructor frees all resources created by Lookup object, and stops
   * the background query thread.
   */
  ~Lookup() noexcept;

  /**
   * @brief Sets the broadcast address for the lookup.
   *
   * @param networks A string pointer to a broadcast address.
   *             eg: "192.168.100.255,192.168.101.255"
   */
  void setNetWorks(std::string networks);

  /**
   * @brief Get CtrlBox ip address.
   */
  std::string getCtrlBoxIP();

  /**
   * @brief Get a group from all known modules with the given family.
   *
   * @param family The family of each of the desired group modules.
   * @returns A shared_ptr with no reference if no group found in allotted
   * time, or reference to a newly allocated group object corresponding to
   * the given parameters otherwise.
   */
  std::shared_ptr<Group> getGroupFromFamily(const std::string &family, int32_t timeout_ms = DEFAULT_TIMEOUT);

  std::shared_ptr<Group> getGroupFromIps(const std::vector<std::string> &ips);

  /**
   * @brief Gets the rate [Hz] at which "discovery" packets are broadcast.
   *
   * Defaults to 5 Hz.
   */
  float getLookupFrequencyHz() const;

  /**
   * @brief Sets the lookup rate [Hz]
   *
   * @param frequency The rate at which "discovery" packets get broadcast on
   * the network to search for modules.
   *
   * \returns true on success, false on failure (e.g., invalid frequency)
   */
  bool setLookupFrequencyHz(float frequency);

  class EntryList final {
    struct Entry final {
      std::string name_;
      std::string family_;
      std::string serial_number_;
    };

   private:
    /**
     * \internal C-style lookup entry list object
     */
    PndLookupEntryListPtr lookup_list_;

    /**
     * \internal Entry list iterator implementation
     * (see http://anderberg.me/2016/07/04/c-custom-iterators/)
     */
    class Iterator final {
     public:
      // Iterator traits (not from std::iterator to be C++17 compliant)
      using value_type = Entry;
      using difference_type = int;
      using pointer = Entry *;
      using reference = Entry;
      using iterator_category = std::bidirectional_iterator_tag;

      Iterator() = delete;
      explicit Iterator(const EntryList &list, size_t current);

      reference operator*() const;

      Iterator &operator++();
      Iterator operator++(int);
      Iterator &operator--();
      Iterator operator--(int);

      bool operator==(const Iterator &rhs) const;
      bool operator!=(const Iterator &rhs) const;

     private:
      const EntryList &list_;
      size_t current_{0};
    };

   public:
    /**
     * \internal Creates entry list from internal C-style object.
     */
    EntryList(PndLookupEntryListPtr lookup_list) : lookup_list_(lookup_list) {}

    ~EntryList() noexcept;

    Entry operator[](size_t index) const;

    size_t size() const;

    Iterator begin() const;
    Iterator end() const;

   private:
    /**
     * Disable copy and move constructors and assignment operators
     */
    PND_DISABLE_COPY_MOVE(EntryList)
  };

  std::shared_ptr<EntryList> getEntryList();

  DeviceList *getDeviceList();

 private:
  /**
   * \internal C-style lookup object
   */
  PndLookupPtr lookup_;

  static const int32_t DEFAULT_TIMEOUT = 500;
};

}  // namespace Pnd

Group

下方Group类作用是将同一类设备(PSA、RCU、PNDEncoder)的某几个组织为一组同步控制。

group.hpp
#pragma once

#include <functional>
#include <memory>
#include <mutex>
#include <vector>

#include "aios.h"

namespace Pnd {

class GroupFeedback;
class GroupCommand;

using GroupFeedbackHandler = std::function<void(const GroupFeedback &)>;

/**
 * @brief Represents a group of physical Pnd actuator, and allows Command,
 * Feedback, and Info objects to be sent to and recieved from the actuator.
 */
class Group final {
 public:
  /**
   * Creates a group from the underlying C-style group object. This should
   * only be called to create groups from the lookup class, not from user
   * code!
   */
  Group(PndGroupPtr group, float initial_feedback_frequency = 0.0f, int32_t initial_command_lifetime = 0);

  /**
   * @brief Destructor cleans up group.
   */
  ~Group() noexcept;

  /**
   * @brief Returns the number of modules in the group
   */
  int size();

  /**
   * @brief Sets the command lifetime for the modules in this group.
   */
  bool setCommandLifetimeMs(int32_t ms);

  /**
   * @brief Send a command to the given group, requesting an acknowledgement
   * of transmission to be sent back.
   *
   * @param group_command The GroupCommand object containing information to be
   * sent to the group.
   *
   * @returns true if an acknowledgement was successfully received
   * (guaranteeing the group received this command), or a negative number for
   * an error otherwise.
   */
  bool sendCommand(const GroupCommand &group_command);

  /**
   * @brief Requests feedback from the group.
   *
   * Sends a background request to the modules in the group; if/when all
   * modules return feedback, any associated handler functions are called.
   * This returned feedback is also stored to be returned by the next call to
   * getNextFeedback (any previously returned data is discarded).
   *
   * @returns @c true if feedback was request was successfully sent, otherwise
   *  @c false on failure (i.e., connection error).
   */
  bool sendFeedbackRequest(PndFeedbackCode feedbackCode = PndFeedbackAll);

  /**
   * @brief Returns the most recently stored feedback from a sent feedback
   * request, or returns the next one received (up to the requested timeout).
   *
   * Note that a feedback request can be sent either with the
   * sendFeedbackRequest function.
   *
   * Warning: other data in the provided 'Feedback' object is erased!
   *
   * @param feedback On success, the group feedback read from the group are
   * written into this structure.
   *
   * @returns @c true if feedback was returned, otherwise @c false on failure
   * (i.e., connection error or timeout waiting for response).
   */
  bool getNextFeedback(GroupFeedback &feedback, int32_t timeout_ms = DEFAULT_TIMEOUT_MS);

  /**
   * TODO:
   * @brief Sets the frequency of the internal feedback request + callback
   * thread.
   *
   * @returns @c true if the frequency successfully was set, or @c false
   * if the parameter was outside the accepted range (less than zero or faster
   * than supported maximum).
   */
  bool setFeedbackFrequencyHz(float frequency);

  /**
   * TODO:
   */
  float getFeedbackFrequencyHz();

  /**
   * TODO:
   */
  void addFeedbackHandler(GroupFeedbackHandler handler);

  /**
   * TODO:
   */
  void clearFeedbackHandlers();

  /**
   * @brief Gets the actuator error message
   */
  PndFeedbackErrorPtr getError(int idx);

 private:
  /**
   * C-style group object
   */
  PndGroupPtr internal_;

  /**
   * The number of modules in this group.
   */
  const int number_of_modules_;

  /**
   * Protects access to the group feedback handler vector.
   */
  std::mutex handler_lock_;

  /**
   * TODO:
   */
  std::vector<GroupFeedbackHandler> handlers_;

  /**
   * TODO:
   */
  friend void callbackWrapper(PndGroupFeedbackPtr group_feedback, void *user_data);

  /**
   * TODO:
   */
  void callAttachedHandlers(PndGroupFeedbackPtr group_feedback);

 public:
  static const int32_t DEFAULT_TIMEOUT_MS = 500;
};

}  // namespace Pnd

GroupCommand

下方GroupCommand类的作用是构造一组设备的控制命令。

groupCommand.hpp
#pragma once

#include <memory>
#include <vector>

#include "aios.h"

namespace Pnd {

/**
 * @brief A list of Command objects appropriate for sending to a Group of
 * modules; the size() must match the number of modules in the group.
 */
class GroupCommand final {
 public:
  /**
   * @brief Create a group command with the specified number of modules.
   */
  GroupCommand(size_t number_of_modules);

  /**
   * @brief Destructor cleans up group command object as necessary.
   */
  ~GroupCommand() noexcept;

  /**
   * @brief Returns the number of module commands in this group command.
   */
  size_t size() const;

  /**
   * @brief Access the command for an individual module.
   */
  PndCommandPtr operator[](size_t index);

  /**
   * @brief Access the command for an individual module.
   */
  const PndCommandPtr operator[](size_t index) const;

  /**
   * @brief Clears all data in this GroupCommand object; this returns to the
   * state the GroupCommand was at time of creation.
   */
  void clear();

  /**
   * @brief Convenience function for setting position commands from vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void setPosition(const std::vector<float> &position);

  /**
   * @brief Convenience function for setting TrapezoidalMove commands from
   * vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void setTrapezoidalMove(const std::vector<float> &val);

  /**
   * @brief Convenience function for setting velocity commands from vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void setVelocity(const std::vector<float> &velocity);

  /**
   * @brief Convenience function for setting velocity ramp commands from
   * vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void setVelocityRamp(const std::vector<float> &velocity);

  /**
   * @brief Convenience function for setting current commands from vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void setCurrent(const std::vector<float> &effort);

  /**
   * @brief Convenience function for setting enable commands from vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   * enable is (nan continue, 0 disable, 1 enable),so choose float type.
   */
  void enable(const std::vector<float> &status);

  /**
   * @brief Convenience function for setting reboot commands from vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void reboot(const std::vector<bool> &flag);

  /**
   * @brief Convenience function for setting getError commands from vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void getError(const std::vector<bool> &flag);

  /**
   * @brief Convenience function for setting clearError commands from vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void clearError(const std::vector<bool> &flag);

  /**
   * @brief Convenience function for setting resetLinearCount commands from
   * vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void resetLinearCount(const std::vector<float> &linearCount);

  /**
   * @brief Convenience function for setting setMotionCtrlConfig commands
   * from vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void setMotionCtrlConfig(const std::vector<MotionControllerConfig *> &config);

  /**
   * @brief Convenience function for setting setMotorConfig commands from
   * vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void setMotorConfig(const std::vector<MotorConfig *> &config);

  /**
   * @brief Convenience function for setting setTrapTraj commands from
   * vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void setTrapTraj(const std::vector<TrapTraj *> &config);

  /**
   * @brief Convenience function for setting saveConfig commands from vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void saveConfig(const std::vector<bool> &flag);

  /**
   * @brief Convenience function for setting setNetworkSetting commands from
   * vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void setNetworkSetting(const std::vector<NetworkSetting *> &config);

  // For latency test
  void setLatencyTest(const std::vector<bool> &flag);

  /******* fw2 .0 *******/
  void setInputPositionPt(const std::vector<PosPtInfo> &param);

  void setInputVelocityPt(const std::vector<float> &param);

  void setInputTorquePt(const std::vector<float> &param);
  /******* fw2 .0 *******/

  /**
   * @brief Convenience function for setting ctrlBoxEnable commands from
   * vectors.
   *
   * Note that if the vector is not the correct link, no action is taken.
   */
  void RcuPower(const std::vector<bool> &status);
  void RcuAV5VPower(const std::vector<bool> &status);
  void RcuV5VPower(const std::vector<bool> &status);
  void RcuV5VAPower(const std::vector<bool> &status);
  void RcuV5VBPower(const std::vector<bool> &status);
  void Rcu12VPower(const std::vector<bool> &status);
  void RcuFan12VPower(const std::vector<bool> &status);
  void Rcu19VPower(const std::vector<bool> &status);

  void RcuBrakeCmd(const std::vector<RcuBrake> &param);
  void RcuAdcOffset(const std::vector<float> &param);
  void RcuFwUpgrade();

  // Encoder
  void getEncoderAngle(const std::vector<float> &param);

 public:
  /**
   * C-style group command object.
   * NOTE: this should not be used except by library functions!
   */
  PndGroupCommandPtr internal_;

  /**
   * The number of modules in this group command.
   */
  const size_t number_of_modules_;

 private:
  /**
   * The list of Command subobjects
   */
  std::vector<PndCommandPtr> commands_;
};

}  // namespace Pnd

GroupFeedback

下方GroupFeedback类作用是获取一组设备的反馈

groupFeedback.hpp
#pragma once

#include <vector>

#include "aios.h"

namespace Pnd {

/**
 * @brief A list of Feedback objects that can be received from a Group of
 * modules; the size() must match the number of modules in the group.
 */
class GroupFeedback final {
 public:
  /**
   * @brief Create a group feedback with the specified number of modules.
   */
  GroupFeedback(size_t number_of_modules);

  /**
   * TODO:
   */
  GroupFeedback(PndGroupFeedbackPtr group_feedback);

  /**
   * @brief Destructor cleans up group feedback object as necessary.
   */
  ~GroupFeedback() noexcept;

  /**
   * @brief Returns the number of module feedbacks in this group feedback.
   */
  size_t size() const;

  /**
   * @brief Access the feedback for an individual module.
   */
  const PndFeedbackPtr &operator[](size_t index) const;

  /**
   * @brief Get the duration of the command sent to recv.
   */
  const int Duration() { return pndGroupFeedbackGetDuration(internal_); };

 public:
  /**
   * C-style group feedback object.
   * NOTE: this should not be used except by library functions!
   */
  PndGroupFeedbackPtr internal_;

 private:
  /**
   * True if this object is responsible for creating and destroying the
   * underlying C pointer; false otherwise.
   */
  const bool manage_pointer_lifetime_;

  /**
   * The number of modules in this group feedback.
   */
  const size_t number_of_modules_;

  /**
   * The list of Feedback subobjects
   */
  std::vector<PndFeedbackPtr> feedbacks_;
};

}  // namespace Pnd

error code

Value Description
48 Feed forward change rate is too large
64 Over current limit

Release Notes

v1.5.11

v1.5.1

Fixed

  • fix array overreach caused by names

v1.4.4

v1.4.4-auth

v1.4.32

v1.4.3

Fixed

  • fix some bug

v1.4.3-auth3

v1.4.3-auth

Features

  • add auth

v1.4.24

v1.4.2

Fixed

  • fix mutil group control error

v1.4.15

v1.4.1

Features

  • Add get all device list api for c/c++

  • Find the io device in the broadcast

Docs

  • Add doc for aios.h

v1.4.06

v1.4.0

Features

  • Add create group form ips

  • Add rcu brake and rcu adcoffset api

  • Add rcu power api

  • Add Rcu av5v power

  • Add rcu power

v1.3.07

v1.3.0

Features

  • Add encoder related.

Docs

  • Update latency_test.

v1.2.08

v1.2.0

Features

  • Control console and file log levels.

v1.1.09

v1.1.0

Features

  • Add duration of the command sent to recv

v1.0.010

v1.1.0

  • base version


  1. Fixed

    • fix array overreach caused by names

  2. Fixed

    • fix some bug

  3. Features

    • add auth

  4. Fixed

    • fix mutil group control error

  5. Features

    • Add get all device list api for c/c++
    • Find the io device in the broadcast

    Docs

    • Add doc for aios.h

  6. Features

    • Add create group form ips
    • Add rcu brake and rcu adcoffset api
    • Add rcu power api
    • Add Rcu av5v power
    • Add rcu power

  7. Features

    • Add encoder related.

    Examples

    • Update latency_test.

  8. Features

    • Control console and file log levels.

  9. Features

    • Add duration of the command sent to recv

    • base version