restore json command interface for aubo io
This commit is contained in:
parent
ee08994f6e
commit
910e0c553d
@ -181,18 +181,6 @@ struct PayloadConfig {
|
||||
double cog_z{0.0};
|
||||
};
|
||||
|
||||
struct CabinetDigitalInputState {
|
||||
std::uint32_t count{0};
|
||||
bool value{false};
|
||||
};
|
||||
|
||||
struct CabinetDigitalOutputState {
|
||||
std::uint32_t count{0};
|
||||
bool value{false};
|
||||
std::string runstate;
|
||||
int runstate_code{0};
|
||||
};
|
||||
|
||||
struct MotionOptions {
|
||||
double velocity{0.0};
|
||||
double acceleration{0.0};
|
||||
|
||||
@ -31,6 +31,7 @@ target_link_libraries(aubo_arm
|
||||
cmvr_es::proto
|
||||
PRIVATE
|
||||
glog
|
||||
jsoncpp
|
||||
Threads::Threads
|
||||
)
|
||||
|
||||
|
||||
@ -24,16 +24,8 @@ public:
|
||||
std::string typeName() const override { return "AuboARM"; }
|
||||
bool init() override;
|
||||
bool stop() override;
|
||||
Result getCabinetDigitalInput(
|
||||
std::uint32_t index,
|
||||
CabinetDigitalInputState& state) const override;
|
||||
Result getCabinetDigitalOutput(
|
||||
std::uint32_t index,
|
||||
CabinetDigitalOutputState& state) const override;
|
||||
Result setCabinetDigitalOutput(
|
||||
std::uint32_t index,
|
||||
bool value,
|
||||
CabinetDigitalOutputState& state) override;
|
||||
bool executeJsonCommand(const std::string& request_json,
|
||||
std::string& response_json) override;
|
||||
|
||||
RobotModel getRobotModel() const override { return model_; }
|
||||
std::size_t getDof() const override { return model_.dof; }
|
||||
|
||||
@ -2,7 +2,9 @@
|
||||
#include "devices/arm/aubo_arm/include/aubo_motion_result.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
@ -10,6 +12,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "common/base/logging/logger.h"
|
||||
#include <json/json.h>
|
||||
|
||||
#if defined(CMVR_HAS_AUBO_SDK)
|
||||
#include "aubo_sdk/rpc.h"
|
||||
@ -62,6 +65,98 @@ std::string vendorBrandName(const config::VendorRobotArmBrand brand)
|
||||
}
|
||||
}
|
||||
|
||||
enum class CabinetIoOperation {
|
||||
GetDigitalInput,
|
||||
GetDigitalOutput,
|
||||
SetDigitalOutput,
|
||||
};
|
||||
|
||||
std::string lowerString(std::string value)
|
||||
{
|
||||
std::transform(
|
||||
value.begin(), value.end(), value.begin(), [](const unsigned char c) {
|
||||
return static_cast<char>(std::tolower(c));
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
bool parseJsonCommand(const std::string& request_json,
|
||||
Json::Value& root,
|
||||
std::string& error)
|
||||
{
|
||||
Json::CharReaderBuilder builder;
|
||||
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
|
||||
return reader->parse(request_json.data(),
|
||||
request_json.data() + request_json.size(),
|
||||
&root,
|
||||
&error);
|
||||
}
|
||||
|
||||
std::string compactJson(const Json::Value& value)
|
||||
{
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder[std::string("indentation")] = "";
|
||||
return Json::writeString(builder, value);
|
||||
}
|
||||
|
||||
Json::Value& jsonMember(Json::Value& root, const char* name)
|
||||
{
|
||||
return *root.demand(name, name + std::strlen(name));
|
||||
}
|
||||
|
||||
const Json::Value* findJsonMember(const Json::Value& root, const char* name)
|
||||
{
|
||||
return root.find(name, name + std::strlen(name));
|
||||
}
|
||||
|
||||
bool requiredJsonString(const Json::Value& root,
|
||||
const char* name,
|
||||
std::string& value)
|
||||
{
|
||||
const Json::Value* member = findJsonMember(root, name);
|
||||
if (!member || !member->isString() || member->asString().empty()) {
|
||||
return false;
|
||||
}
|
||||
value = member->asString();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool requiredJsonInt(const Json::Value& root, const char* name, int& value)
|
||||
{
|
||||
const Json::Value* member = findJsonMember(root, name);
|
||||
if (!member || !member->isInt()) {
|
||||
return false;
|
||||
}
|
||||
value = member->asInt();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool requiredJsonBool(const Json::Value& root, const char* name, bool& value)
|
||||
{
|
||||
const Json::Value* member = findJsonMember(root, name);
|
||||
if (!member || !member->isBool()) {
|
||||
return false;
|
||||
}
|
||||
value = member->asBool();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseCabinetIoOperation(const std::string& name,
|
||||
CabinetIoOperation& operation)
|
||||
{
|
||||
const std::string normalized = lowerString(name);
|
||||
if (normalized == "get_di") {
|
||||
operation = CabinetIoOperation::GetDigitalInput;
|
||||
} else if (normalized == "get_do") {
|
||||
operation = CabinetIoOperation::GetDigitalOutput;
|
||||
} else if (normalized == "set_do") {
|
||||
operation = CabinetIoOperation::SetDigitalOutput;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(CMVR_HAS_AUBO_SDK)
|
||||
constexpr auto kAutoEnablePollInterval = std::chrono::milliseconds(100);
|
||||
constexpr auto kAutoEnableReconnectInterval = std::chrono::milliseconds(500);
|
||||
@ -356,224 +451,172 @@ bool AuboArm::stop()
|
||||
return stopMotion().ok();
|
||||
}
|
||||
|
||||
Result AuboArm::getCabinetDigitalInput(
|
||||
const std::uint32_t index,
|
||||
CabinetDigitalInputState& state) const
|
||||
bool AuboArm::executeJsonCommand(const std::string& request_json,
|
||||
std::string& response_json)
|
||||
{
|
||||
state = {};
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
const auto ready = ensureConnected_("getCabinetDigitalInput");
|
||||
if (!ready.ok()) {
|
||||
return ready;
|
||||
Json::Value response(Json::objectValue);
|
||||
jsonMember(response, "success") = false;
|
||||
const auto fail = [&](const std::string& error_code,
|
||||
const std::string& error_message) {
|
||||
jsonMember(response, "success") = false;
|
||||
jsonMember(response, "error_code") = error_code;
|
||||
jsonMember(response, "error_message") = error_message;
|
||||
response_json = compactJson(response);
|
||||
return false;
|
||||
};
|
||||
|
||||
Json::Value root;
|
||||
std::string parse_error;
|
||||
if (!parseJsonCommand(request_json, root, parse_error)) {
|
||||
return fail("invalid_json", "invalid json: " + parse_error);
|
||||
}
|
||||
if (!root.isObject()) {
|
||||
return fail("invalid_json", "invalid json: root must be an object");
|
||||
}
|
||||
|
||||
std::string command;
|
||||
if (!requiredJsonString(root, "command", command)) {
|
||||
return fail(
|
||||
"invalid_argument",
|
||||
"field 'command' is required and must be a non-empty string");
|
||||
}
|
||||
command = lowerString(command);
|
||||
if (command != "cabinet_io") {
|
||||
return fail("unsupported_command",
|
||||
"unsupported json command: " + command);
|
||||
}
|
||||
jsonMember(response, "command") = command;
|
||||
|
||||
std::string operation_name;
|
||||
if (!requiredJsonString(root, "operation", operation_name)) {
|
||||
return fail(
|
||||
"invalid_argument",
|
||||
"field 'operation' is required and must be a non-empty string");
|
||||
}
|
||||
operation_name = lowerString(operation_name);
|
||||
CabinetIoOperation operation{};
|
||||
if (!parseCabinetIoOperation(operation_name, operation)) {
|
||||
return fail("invalid_operation",
|
||||
"unsupported cabinet_io operation: " + operation_name);
|
||||
}
|
||||
jsonMember(response, "operation") = operation_name;
|
||||
|
||||
int index = -1;
|
||||
if (!requiredJsonInt(root, "index", index) || index < 0) {
|
||||
return fail(
|
||||
"invalid_argument",
|
||||
"field 'index' is required and must be a non-negative JSON integer");
|
||||
}
|
||||
jsonMember(response, "index") = index;
|
||||
|
||||
bool output_value = false;
|
||||
if (operation == CabinetIoOperation::SetDigitalOutput &&
|
||||
!requiredJsonBool(root, "value", output_value)) {
|
||||
return fail(
|
||||
"invalid_argument",
|
||||
"field 'value' is required for set_do and must be a JSON boolean");
|
||||
}
|
||||
|
||||
#if defined(CMVR_HAS_AUBO_SDK)
|
||||
try {
|
||||
const auto robot_names = sdk_->rpc_client->getRobotNames();
|
||||
if (robot_names.empty()) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::RobotNotReady,
|
||||
"[AuboArm] getCabinetDigitalInput failed: robot name list is empty");
|
||||
}
|
||||
auto robot_interface =
|
||||
sdk_->rpc_client->getRobotInterface(robot_names.front());
|
||||
if (!robot_interface || !robot_interface->getIoControl()) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::RobotNotReady,
|
||||
"[AuboArm] getCabinetDigitalInput failed: IO interface is unavailable");
|
||||
}
|
||||
|
||||
auto io = robot_interface->getIoControl();
|
||||
const int count = io->getStandardDigitalInputNum();
|
||||
if (count < 0) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] getCabinetDigitalInput failed: invalid IO count=" +
|
||||
std::to_string(count));
|
||||
}
|
||||
state.count = static_cast<std::uint32_t>(count);
|
||||
if (index >= state.count) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::InvalidArgument,
|
||||
"[AuboArm] getCabinetDigitalInput index out of range: index=" +
|
||||
std::to_string(index) + ", count=" +
|
||||
std::to_string(state.count));
|
||||
}
|
||||
state.value = io->getStandardDigitalInput(static_cast<int>(index));
|
||||
return Result::success();
|
||||
} catch (const arcs::common_interface::AuboException& e) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] getCabinetDigitalInput failed: " +
|
||||
std::string(e.what()) + ", sdk ret=" +
|
||||
std::to_string(e.code()));
|
||||
} catch (const std::exception& e) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] getCabinetDigitalInput failed: " +
|
||||
std::string(e.what()));
|
||||
}
|
||||
#else
|
||||
return Result::failure(
|
||||
ArmErrorCode::UnsupportedCommand,
|
||||
"[AuboArm] getCabinetDigitalInput failed: Aubo SDK is unavailable");
|
||||
#endif
|
||||
}
|
||||
|
||||
Result AuboArm::getCabinetDigitalOutput(
|
||||
const std::uint32_t index,
|
||||
CabinetDigitalOutputState& state) const
|
||||
{
|
||||
state = {};
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
const auto ready = ensureConnected_("getCabinetDigitalOutput");
|
||||
const auto ready = ensureConnected_("cabinet_io");
|
||||
if (!ready.ok()) {
|
||||
return ready;
|
||||
return fail("not_connected", ready.message);
|
||||
}
|
||||
|
||||
#if defined(CMVR_HAS_AUBO_SDK)
|
||||
try {
|
||||
const auto robot_names = sdk_->rpc_client->getRobotNames();
|
||||
if (robot_names.empty()) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::RobotNotReady,
|
||||
"[AuboArm] getCabinetDigitalOutput failed: robot name list is empty");
|
||||
return fail(
|
||||
"robot_interface_unavailable",
|
||||
"[AuboArm] cabinet_io failed: robot name list is empty");
|
||||
}
|
||||
|
||||
auto robot_interface =
|
||||
sdk_->rpc_client->getRobotInterface(robot_names.front());
|
||||
if (!robot_interface || !robot_interface->getIoControl()) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::RobotNotReady,
|
||||
"[AuboArm] getCabinetDigitalOutput failed: IO interface is unavailable");
|
||||
if (!robot_interface) {
|
||||
return fail(
|
||||
"robot_interface_unavailable",
|
||||
"[AuboArm] cabinet_io failed: robot interface is null");
|
||||
}
|
||||
|
||||
auto io = robot_interface->getIoControl();
|
||||
const int count = io->getStandardDigitalOutputNum();
|
||||
if (count < 0) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] getCabinetDigitalOutput failed: invalid IO count=" +
|
||||
std::to_string(count));
|
||||
}
|
||||
state.count = static_cast<std::uint32_t>(count);
|
||||
if (index >= state.count) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::InvalidArgument,
|
||||
"[AuboArm] getCabinetDigitalOutput index out of range: index=" +
|
||||
std::to_string(index) + ", count=" +
|
||||
std::to_string(state.count));
|
||||
if (!io) {
|
||||
return fail(
|
||||
"io_interface_unavailable",
|
||||
"[AuboArm] cabinet_io failed: IO interface is null");
|
||||
}
|
||||
|
||||
const bool is_input =
|
||||
operation == CabinetIoOperation::GetDigitalInput;
|
||||
const int count = is_input ? io->getStandardDigitalInputNum()
|
||||
: io->getStandardDigitalOutputNum();
|
||||
jsonMember(response, "count") = count;
|
||||
if (count < 0) {
|
||||
return fail(
|
||||
"invalid_io_count",
|
||||
"[AuboArm] cabinet_io failed: invalid IO count=" +
|
||||
std::to_string(count));
|
||||
}
|
||||
if (index >= count) {
|
||||
return fail(
|
||||
"index_out_of_range",
|
||||
"[AuboArm] cabinet_io index out of range: index=" +
|
||||
std::to_string(index) + ", count=" +
|
||||
std::to_string(count));
|
||||
}
|
||||
|
||||
if (operation == CabinetIoOperation::GetDigitalInput) {
|
||||
jsonMember(response, "value") =
|
||||
io->getStandardDigitalInput(index);
|
||||
} else {
|
||||
const auto runstate =
|
||||
io->getStandardDigitalOutputRunstate(static_cast<int>(index));
|
||||
state.runstate = arcs::common_interface::toString(runstate);
|
||||
state.runstate_code = static_cast<int>(runstate);
|
||||
state.value =
|
||||
io->getStandardDigitalOutput(static_cast<int>(index));
|
||||
return Result::success();
|
||||
} catch (const arcs::common_interface::AuboException& e) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] getCabinetDigitalOutput failed: " +
|
||||
std::string(e.what()) + ", sdk ret=" +
|
||||
std::to_string(e.code()));
|
||||
} catch (const std::exception& e) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] getCabinetDigitalOutput failed: " +
|
||||
std::string(e.what()));
|
||||
}
|
||||
#else
|
||||
return Result::failure(
|
||||
ArmErrorCode::UnsupportedCommand,
|
||||
"[AuboArm] getCabinetDigitalOutput failed: Aubo SDK is unavailable");
|
||||
#endif
|
||||
}
|
||||
io->getStandardDigitalOutputRunstate(index);
|
||||
jsonMember(response, "runstate") =
|
||||
arcs::common_interface::toString(runstate);
|
||||
jsonMember(response, "runstate_code") =
|
||||
static_cast<int>(runstate);
|
||||
|
||||
Result AuboArm::setCabinetDigitalOutput(
|
||||
const std::uint32_t index,
|
||||
const bool value,
|
||||
CabinetDigitalOutputState& state)
|
||||
{
|
||||
state = {};
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
const auto ready = ensureConnected_("setCabinetDigitalOutput");
|
||||
if (!ready.ok()) {
|
||||
return ready;
|
||||
}
|
||||
|
||||
#if defined(CMVR_HAS_AUBO_SDK)
|
||||
try {
|
||||
const auto robot_names = sdk_->rpc_client->getRobotNames();
|
||||
if (robot_names.empty()) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::RobotNotReady,
|
||||
"[AuboArm] setCabinetDigitalOutput failed: robot name list is empty");
|
||||
}
|
||||
auto robot_interface =
|
||||
sdk_->rpc_client->getRobotInterface(robot_names.front());
|
||||
if (!robot_interface || !robot_interface->getIoControl()) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::RobotNotReady,
|
||||
"[AuboArm] setCabinetDigitalOutput failed: IO interface is unavailable");
|
||||
}
|
||||
|
||||
auto io = robot_interface->getIoControl();
|
||||
const int count = io->getStandardDigitalOutputNum();
|
||||
if (count < 0) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] setCabinetDigitalOutput failed: invalid IO count=" +
|
||||
std::to_string(count));
|
||||
}
|
||||
state.count = static_cast<std::uint32_t>(count);
|
||||
if (index >= state.count) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::InvalidArgument,
|
||||
"[AuboArm] setCabinetDigitalOutput index out of range: index=" +
|
||||
std::to_string(index) + ", count=" +
|
||||
std::to_string(state.count));
|
||||
}
|
||||
|
||||
const auto runstate =
|
||||
io->getStandardDigitalOutputRunstate(static_cast<int>(index));
|
||||
state.runstate = arcs::common_interface::toString(runstate);
|
||||
state.runstate_code = static_cast<int>(runstate);
|
||||
if (operation == CabinetIoOperation::GetDigitalOutput) {
|
||||
jsonMember(response, "value") =
|
||||
io->getStandardDigitalOutput(index);
|
||||
} else {
|
||||
using arcs::common_interface::StandardOutputRunState;
|
||||
if (runstate != StandardOutputRunState::None) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandRejected,
|
||||
"[AuboArm] setCabinetDigitalOutput rejected: output is "
|
||||
"managed by controller runstate; configure this channel as "
|
||||
"None before writing");
|
||||
return fail(
|
||||
"output_managed_by_runstate",
|
||||
"[AuboArm] cabinet_io set_do rejected: output is "
|
||||
"managed by controller runstate; configure this "
|
||||
"channel as None before writing");
|
||||
}
|
||||
|
||||
const int ret =
|
||||
io->setStandardDigitalOutput(static_cast<int>(index), value);
|
||||
io->setStandardDigitalOutput(index, output_value);
|
||||
jsonMember(response, "sdk_return_code") = ret;
|
||||
if (ret != 0) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] setCabinetDigitalOutput failed: sdk ret=" +
|
||||
return fail(
|
||||
"sdk_command_failed",
|
||||
"[AuboArm] cabinet_io set_do failed: sdk ret=" +
|
||||
std::to_string(ret));
|
||||
}
|
||||
state.value = value;
|
||||
return Result::success();
|
||||
jsonMember(response, "requested_value") = output_value;
|
||||
}
|
||||
}
|
||||
|
||||
jsonMember(response, "success") = true;
|
||||
response_json = compactJson(response);
|
||||
return true;
|
||||
} catch (const arcs::common_interface::AuboException& e) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] setCabinetDigitalOutput failed: " +
|
||||
std::string(e.what()) + ", sdk ret=" +
|
||||
std::to_string(e.code()));
|
||||
jsonMember(response, "sdk_return_code") = e.code();
|
||||
return fail("sdk_exception",
|
||||
std::string("[AuboArm] cabinet_io failed: ") + e.what());
|
||||
} catch (const std::exception& e) {
|
||||
return Result::failure(
|
||||
ArmErrorCode::CommandFailed,
|
||||
"[AuboArm] setCabinetDigitalOutput failed: " +
|
||||
std::string(e.what()));
|
||||
return fail("sdk_exception",
|
||||
std::string("[AuboArm] cabinet_io failed: ") + e.what());
|
||||
}
|
||||
#else
|
||||
return Result::failure(
|
||||
ArmErrorCode::UnsupportedCommand,
|
||||
"[AuboArm] setCabinetDigitalOutput failed: Aubo SDK is unavailable");
|
||||
return fail("sdk_unavailable",
|
||||
"[AuboArm] cabinet_io failed: Aubo SDK is unavailable");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -44,33 +44,12 @@ public:
|
||||
ArmErrorCode::UnsupportedCommand,
|
||||
"ListTCPFrame is not supported by this robot arm");
|
||||
}
|
||||
virtual Result getCabinetDigitalInput(
|
||||
std::uint32_t,
|
||||
CabinetDigitalInputState& state) const
|
||||
virtual bool executeJsonCommand(const std::string&,
|
||||
std::string& response_json)
|
||||
{
|
||||
state = {};
|
||||
return Result::failure(
|
||||
ArmErrorCode::UnsupportedCommand,
|
||||
"cabinet digital input is not supported by this robot arm");
|
||||
}
|
||||
virtual Result getCabinetDigitalOutput(
|
||||
std::uint32_t,
|
||||
CabinetDigitalOutputState& state) const
|
||||
{
|
||||
state = {};
|
||||
return Result::failure(
|
||||
ArmErrorCode::UnsupportedCommand,
|
||||
"cabinet digital output is not supported by this robot arm");
|
||||
}
|
||||
virtual Result setCabinetDigitalOutput(
|
||||
std::uint32_t,
|
||||
bool,
|
||||
CabinetDigitalOutputState& state)
|
||||
{
|
||||
state = {};
|
||||
return Result::failure(
|
||||
ArmErrorCode::UnsupportedCommand,
|
||||
"cabinet digital output is not supported by this robot arm");
|
||||
response_json =
|
||||
R"({"success":false,"error_code":"unsupported_command","error_message":"JSON command unsupported"})";
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual Result torqueOn() = 0;
|
||||
|
||||
@ -59,18 +59,10 @@ public:
|
||||
grpc::Status computeForwardKinematics(grpc::ServerContext* context,
|
||||
const api::ComputeForwardKinematics_Request* request,
|
||||
api::ComputeForwardKinematics_Response* response) override;
|
||||
grpc::Status getCabinetDigitalInput(
|
||||
grpc::Status ExecuteJsonCommand(
|
||||
grpc::ServerContext* context,
|
||||
const api::CabinetDigitalInput_Request* request,
|
||||
api::CabinetDigitalInput_Response* response) override;
|
||||
grpc::Status getCabinetDigitalOutput(
|
||||
grpc::ServerContext* context,
|
||||
const api::CabinetDigitalOutput_Request* request,
|
||||
api::CabinetDigitalOutput_Response* response) override;
|
||||
grpc::Status setCabinetDigitalOutput(
|
||||
grpc::ServerContext* context,
|
||||
const api::SetCabinetDigitalOutput_Request* request,
|
||||
api::SetCabinetDigitalOutput_Response* response) override;
|
||||
const api::JsonDeviceCommand_Request* request,
|
||||
api::JsonDeviceCommand_Feedback* response) override;
|
||||
|
||||
private:
|
||||
device::DeviceManager& dmgr_;
|
||||
|
||||
@ -588,10 +588,10 @@ grpc::Status gRPCArmServiceImpl::computeForwardKinematics(grpc::ServerContext*,
|
||||
return grpc::Status(grpc::StatusCode::UNIMPLEMENTED, "computeForwardKinematics is not implemented");
|
||||
}
|
||||
|
||||
grpc::Status gRPCArmServiceImpl::getCabinetDigitalInput(
|
||||
grpc::Status gRPCArmServiceImpl::ExecuteJsonCommand(
|
||||
grpc::ServerContext*,
|
||||
const api::CabinetDigitalInput_Request* request,
|
||||
api::CabinetDigitalInput_Response* response)
|
||||
const api::JsonDeviceCommand_Request* request,
|
||||
api::JsonDeviceCommand_Feedback* response)
|
||||
{
|
||||
auto control_lease =
|
||||
ControlCommandArbiter::instance().tryAcquireControl();
|
||||
@ -606,85 +606,17 @@ grpc::Status gRPCArmServiceImpl::getCabinetDigitalInput(
|
||||
return setDeviceNotFound(response, device_id);
|
||||
}
|
||||
|
||||
device::CabinetDigitalInputState state;
|
||||
const auto result =
|
||||
arm->getCabinetDigitalInput(request->index(), state);
|
||||
response->set_count(state.count);
|
||||
response->set_value(state.value);
|
||||
if (result.ok()) {
|
||||
logRpcSuccess("getCabinetDigitalInput", device_id);
|
||||
std::string response_json;
|
||||
const bool success = arm->executeJsonCommand(
|
||||
request->request_json(), response_json);
|
||||
fillFeedback(response->mutable_header(),
|
||||
success,
|
||||
success ? "" : response_json);
|
||||
response->set_response_json(response_json);
|
||||
if (success) {
|
||||
logRpcSuccess("ExecuteJsonCommand", device_id);
|
||||
}
|
||||
return setResponseResult(response, result);
|
||||
} catch (const std::exception& e) {
|
||||
fillFeedback(response->mutable_header(), false, e.what());
|
||||
return grpc::Status(grpc::StatusCode::INTERNAL, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
grpc::Status gRPCArmServiceImpl::getCabinetDigitalOutput(
|
||||
grpc::ServerContext*,
|
||||
const api::CabinetDigitalOutput_Request* request,
|
||||
api::CabinetDigitalOutput_Response* response)
|
||||
{
|
||||
auto control_lease =
|
||||
ControlCommandArbiter::instance().tryAcquireControl();
|
||||
if (!control_lease) {
|
||||
return setControlBusy(response);
|
||||
}
|
||||
|
||||
try {
|
||||
const std::string device_id = request->header().device_id();
|
||||
auto arm = dmgr_.getDevice<device::RobotArm>(device_id);
|
||||
if (!arm) {
|
||||
return setDeviceNotFound(response, device_id);
|
||||
}
|
||||
|
||||
device::CabinetDigitalOutputState state;
|
||||
const auto result =
|
||||
arm->getCabinetDigitalOutput(request->index(), state);
|
||||
response->set_count(state.count);
|
||||
response->set_value(state.value);
|
||||
response->set_runstate(state.runstate);
|
||||
response->set_runstate_code(state.runstate_code);
|
||||
if (result.ok()) {
|
||||
logRpcSuccess("getCabinetDigitalOutput", device_id);
|
||||
}
|
||||
return setResponseResult(response, result);
|
||||
} catch (const std::exception& e) {
|
||||
fillFeedback(response->mutable_header(), false, e.what());
|
||||
return grpc::Status(grpc::StatusCode::INTERNAL, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
grpc::Status gRPCArmServiceImpl::setCabinetDigitalOutput(
|
||||
grpc::ServerContext*,
|
||||
const api::SetCabinetDigitalOutput_Request* request,
|
||||
api::SetCabinetDigitalOutput_Response* response)
|
||||
{
|
||||
auto control_lease =
|
||||
ControlCommandArbiter::instance().tryAcquireControl();
|
||||
if (!control_lease) {
|
||||
return setControlBusy(response);
|
||||
}
|
||||
|
||||
try {
|
||||
const std::string device_id = request->header().device_id();
|
||||
auto arm = dmgr_.getDevice<device::RobotArm>(device_id);
|
||||
if (!arm) {
|
||||
return setDeviceNotFound(response, device_id);
|
||||
}
|
||||
|
||||
device::CabinetDigitalOutputState state;
|
||||
const auto result = arm->setCabinetDigitalOutput(
|
||||
request->index(), request->value(), state);
|
||||
response->set_count(state.count);
|
||||
response->set_requested_value(request->value());
|
||||
response->set_runstate(state.runstate);
|
||||
response->set_runstate_code(state.runstate_code);
|
||||
if (result.ok()) {
|
||||
logRpcSuccess("setCabinetDigitalOutput", device_id);
|
||||
}
|
||||
return setResponseResult(response, result);
|
||||
return grpc::Status::OK;
|
||||
} catch (const std::exception& e) {
|
||||
fillFeedback(response->mutable_header(), false, e.what());
|
||||
return grpc::Status(grpc::StatusCode::INTERNAL, e.what());
|
||||
|
||||
@ -319,76 +319,3 @@ message ComputeForwardKinematics {
|
||||
TransformMatrix4x4 matrix = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// 读取机械臂控制柜 Standard 数字输入(DI)。
|
||||
message CabinetDigitalInput {
|
||||
// 数字输入读取请求。
|
||||
message Request {
|
||||
// 通用请求头,包含目标设备 ID 和请求时间戳。
|
||||
CommandHeader.Request header = 1;
|
||||
// DI 通道索引,从 0 开始,无单位。
|
||||
uint32 index = 2;
|
||||
}
|
||||
|
||||
// 数字输入读取结果。
|
||||
message Response {
|
||||
// 通用响应头,包含成功标志、错误信息和响应时间戳。
|
||||
CommandHeader.Feedback header = 1;
|
||||
// 控制柜可用 Standard DI 通道总数,无单位。
|
||||
uint32 count = 2;
|
||||
// 输入电平;true 为高电平,false 为低电平,无单位。
|
||||
bool value = 3;
|
||||
}
|
||||
}
|
||||
|
||||
// 读取机械臂控制柜 Standard 数字输出(DO)。
|
||||
message CabinetDigitalOutput {
|
||||
// 数字输出读取请求。
|
||||
message Request {
|
||||
// 通用请求头,包含目标设备 ID 和请求时间戳。
|
||||
CommandHeader.Request header = 1;
|
||||
// DO 通道索引,从 0 开始,无单位。
|
||||
uint32 index = 2;
|
||||
}
|
||||
|
||||
// 数字输出读取结果。
|
||||
message Response {
|
||||
// 通用响应头,包含成功标志、错误信息和响应时间戳。
|
||||
CommandHeader.Feedback header = 1;
|
||||
// 控制柜可用 Standard DO 通道总数,无单位。
|
||||
uint32 count = 2;
|
||||
// 当前输出电平;true 为高电平,false 为低电平,无单位。
|
||||
bool value = 3;
|
||||
// 控制器对该输出通道配置的运行状态名称,无单位。
|
||||
string runstate = 4;
|
||||
// 控制器输出运行状态枚举值,无单位。
|
||||
int32 runstate_code = 5;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置机械臂控制柜 Standard 数字输出(DO)。
|
||||
message SetCabinetDigitalOutput {
|
||||
// 数字输出设置请求。
|
||||
message Request {
|
||||
// 通用请求头,包含目标设备 ID 和请求时间戳。
|
||||
CommandHeader.Request header = 1;
|
||||
// DO 通道索引,从 0 开始,无单位。
|
||||
uint32 index = 2;
|
||||
// 目标输出电平;true 为高电平,false 为低电平,无单位。
|
||||
bool value = 3;
|
||||
}
|
||||
|
||||
// 数字输出设置结果。
|
||||
message Response {
|
||||
// 通用响应头,包含成功标志、错误信息和响应时间戳。
|
||||
CommandHeader.Feedback header = 1;
|
||||
// 控制柜可用 Standard DO 通道总数,无单位。
|
||||
uint32 count = 2;
|
||||
// SDK 已接受的目标输出电平,不代表已经回读确认,无单位。
|
||||
bool requested_value = 3;
|
||||
// 写入前该输出通道的控制器运行状态名称,无单位。
|
||||
string runstate = 4;
|
||||
// 写入前该输出通道的控制器运行状态枚举值,无单位。
|
||||
int32 runstate_code = 5;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,10 +39,6 @@ service ArmService {
|
||||
rpc getPoseMatrix(GetPoseMatrix.Request) returns (GetPoseMatrix.Response);
|
||||
// 根据关节角计算正运动学矩阵;输入角度 rad,输出平移元素 m。
|
||||
rpc computeForwardKinematics(ComputeForwardKinematics.Request) returns (ComputeForwardKinematics.Response);
|
||||
// 读取控制柜 Standard DI;通道索引从 0 开始,电平为布尔值。
|
||||
rpc getCabinetDigitalInput(CabinetDigitalInput.Request) returns (CabinetDigitalInput.Response);
|
||||
// 读取控制柜 Standard DO 及其控制器运行状态;通道索引从 0 开始。
|
||||
rpc getCabinetDigitalOutput(CabinetDigitalOutput.Request) returns (CabinetDigitalOutput.Response);
|
||||
// 设置控制柜 Standard DO;仅允许写入未被控制器运行状态管理的通道。
|
||||
rpc setCabinetDigitalOutput(SetCabinetDigitalOutput.Request) returns (SetCabinetDigitalOutput.Response);
|
||||
// 执行机械臂厂商扩展 JSON 命令;当前用于 AUBO 控制柜 Standard DI/DO。
|
||||
rpc ExecuteJsonCommand(JsonDeviceCommand.Request) returns (JsonDeviceCommand.Feedback);
|
||||
}
|
||||
|
||||
@ -59,14 +59,21 @@ message ConfigParam {
|
||||
}
|
||||
}
|
||||
|
||||
// 设备厂商扩展 JSON 命令;JSON 内容及字段单位由具体设备命令定义。
|
||||
message JsonDeviceCommand {
|
||||
// JSON 命令请求。
|
||||
message Request {
|
||||
// 通用请求头,包含目标设备 ID 和请求时间戳。
|
||||
CommandHeader.Request header = 1;
|
||||
// JSON 格式的设备命令字符串,无单位。
|
||||
string request_json = 2;
|
||||
}
|
||||
|
||||
// JSON 命令响应。
|
||||
message Feedback {
|
||||
// 通用响应头,包含成功标志、错误信息和响应时间戳。
|
||||
CommandHeader.Feedback header = 1;
|
||||
// JSON 格式的设备响应字符串,无单位。
|
||||
string response_json = 2;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user