update dexhand

This commit is contained in:
linbo 2025-10-21 10:32:18 +08:00
parent 9284d52c46
commit 4da55aa445
7 changed files with 186 additions and 124 deletions

View File

@ -23,6 +23,9 @@ namespace cmvr::service {
grpc::Status GetSensorDataStream(grpc::ServerContext* context, grpc::ServerReaderWriter<cmvr::api::GetSensorDataStreamCommand_Feedback, cmvr::api::GetSensorDataStreamCommand_Request>* stream) override; grpc::Status GetSensorDataStream(grpc::ServerContext* context, grpc::ServerReaderWriter<cmvr::api::GetSensorDataStreamCommand_Feedback, cmvr::api::GetSensorDataStreamCommand_Request>* stream) override;
private: private:
device::DeviceManager& dmgr_; device::DeviceManager& dmgr_;
// 静态成员声明(关键!必须在类内声明)
static const std::unordered_map<std::string, int> kIdToIndex; // 字符串id→索引
static const std::vector<std::string> kIndexToId; // 索引→字符串id
}; };
} }

View File

@ -5,7 +5,7 @@
#pragma once #pragma once
#include "device_manager/device_manager.h" #include "device_manager/device_manager.h"
#include "cmvr/api/humanoid_robot.grpc.pb.h" #include "cmvr/api/humanoid_robot_service.grpc.pb.h"
namespace cmvr { namespace cmvr {
namespace service { namespace service {

View File

@ -4,146 +4,169 @@ import "cmvr/api/common.proto";
package cmvr.api; package cmvr.api;
//
message FreedomValue { message FreedomValue {
int32 id = 1; // id 0-6 string id = 1; // id
float value = 2; // 0-1 // little_finger
// ring_finger
// middle_finger
// index_finger
// thumb_bend
// thumb_rotate
float value = 2; // 0-1
} }
//
message FreedomState { message FreedomState {
int32 dof_id = 1; // ID string dof_id = 1; // idFreedomValue.id一致
int32 angle = 2; // // little_finger
int32 speed = 3; // // ring_finger
int32 force = 4; // // middle_finger
int32 position = 5; // // index_finger
int32 current = 6; // // thumb_bend
int32 temperature = 7; // // thumb_rotate
int32 error = 8; // int32 angle = 2; //
repeated string error_message = 9; // int32 speed = 3; //
int32 force = 4; //
int32 position = 5; //
int32 current = 6; //
int32 temperature = 7; //
int32 error = 8; // 00
repeated string error_message = 9; //
} }
//
// //
message SensorData { message SensorData {
// //
enum FingerType { enum FingerType {
PINKY = 0; // PINKY = 0; //
RING = 1; // RING = 1; //
MIDDLE_FINGER = 2; // PartType.MIDDLE冲突 MIDDLE_FINGER = 2; // PartType冲突
INDEX = 3; // INDEX = 3; //
THUMB = 4; // THUMB = 4; //
PALM = 5; // PALM = 5; //
} }
// THUMB_MIDDLE以避免冲突 //
enum PartType { enum PartType {
TIP = 0; // TIP = 0; //
FINGER = 1; // FINGER = 1; //
PAD = 2; // PAD = 2; //
THUMB_MIDDLE = 3; // THUMB_MIDDLE = 3; //
PALM_PAD = 4; // PalmTactileData PALM_PAD = 4; //
} }
FingerType finger_type = 4; // 使PALM FingerType finger_type = 4; //
PartType part_type = 5; // PartType part_type = 5; //
string sensor_name = 6; // "小拇指指端" string sensor_name = 6; // "little_finger_tip"便
//
message RowData { message RowData {
repeated int32 values = 1 [packed = true]; // repeated int32 values = 1 [packed = true]; //
} }
repeated RowData data = 1; // RowData repeated RowData data = 1; //
int32 rows = 2; // int32 rows = 2; //
int32 cols = 3; // int32 cols = 3; //
} }
//
message DexHandState { message DexHandState {
bool is_initialized = 1; // bool is_initialized = 1; // truefalse
repeated FreedomState hands = 2; // repeated FreedomState hands = 2; // FreedomValue.id一一对应
} }
//
message GetDexHandStateCommand { message GetDexHandStateCommand {
message Request { message Request {
CommandHeader.Request header = 1; CommandHeader.Request header = 1; // ID等
} }
message Feedback { message Feedback {
CommandHeader.Feedback header = 1; CommandHeader.Feedback header = 1; //
DexHandState state = 2; DexHandState state = 2; //
} }
} }
//
message SetDexHandPositionsCommand { message SetDexHandPositionsCommand {
message Request { message Request {
CommandHeader.Request header = 1; CommandHeader.Request header = 1; //
repeated FreedomValue values = 2; repeated FreedomValue values = 2; //
} }
message Feedback { message Feedback {
CommandHeader.Feedback header = 1; CommandHeader.Feedback header = 1; //
} }
} }
//
message SetDexHandAnglesCommand { message SetDexHandAnglesCommand {
message Request { message Request {
CommandHeader.Request header = 1; CommandHeader.Request header = 1; //
repeated FreedomValue values = 2; repeated FreedomValue values = 2; //
} }
message Feedback { message Feedback {
CommandHeader.Feedback header = 1; CommandHeader.Feedback header = 1; //
} }
} }
//
message SetDexHandForceCommand { message SetDexHandForceCommand {
message Request { message Request {
CommandHeader.Request header = 1; CommandHeader.Request header = 1; //
repeated FreedomValue values = 2; repeated FreedomValue values = 2; //
} }
message Feedback { message Feedback {
CommandHeader.Feedback header = 1; CommandHeader.Feedback header = 1; //
} }
} }
//
message SetDexHandSpeedCommand { message SetDexHandSpeedCommand {
message Request { message Request {
CommandHeader.Request header = 1; CommandHeader.Request header = 1; //
repeated FreedomValue values = 2; repeated FreedomValue values = 2; //
} }
message Feedback { message Feedback {
CommandHeader.Feedback header = 1; CommandHeader.Feedback header = 1; //
} }
} }
//
message SetDexHandPresetActCommand { message SetDexHandPresetActCommand {
message Request { message Request {
CommandHeader.Request header = 1; CommandHeader.Request header = 1; //
int32 presetActId = 2; int32 presetActId = 2; // ID01
} }
message Feedback { message Feedback {
CommandHeader.Feedback header = 1; CommandHeader.Feedback header = 1; //
} }
} }
//
message GetSensorDataCommand { message GetSensorDataCommand {
message Request { message Request {
CommandHeader.Request header = 1; CommandHeader.Request header = 1; //
} }
message Feedback { message Feedback {
CommandHeader.Feedback header = 1; CommandHeader.Feedback header = 1; //
repeated SensorData sensor = 2;// repeated SensorData sensor = 2; //
} }
} }
//
message GetSensorDataStreamCommand { message GetSensorDataStreamCommand {
message Request { message Request {
CommandHeader.Request header = 1; CommandHeader.Request header = 1; //
} }
message Feedback { message Feedback {
CommandHeader.Feedback header = 1; CommandHeader.Feedback header = 1; //
repeated SensorData sensor = 2;// repeated SensorData sensor = 2; //
} }
} }

View File

@ -75,7 +75,7 @@ message SpeedJ{
message Request{ message Request{
CommandHeader.Request header = 1; CommandHeader.Request header = 1;
string joint_name = 2; string joint_name = 2;
double vel = 3; double vel = 3; // (rad/s)
double acc = 4; double acc = 4;
RobotJointIndexDirection dir = 5; RobotJointIndexDirection dir = 5;
} }

View File

@ -185,7 +185,7 @@ void HumanoidRobot<DOF>::init() {
for (auto &task: tasks) task.get(); for (auto &task: tasks) task.get();
rsm_.store(ROBOT_ESTOP); rsm_.store(ROBOT_ESTOP);
LOG(INFO) << "All enabled motors initialized successfully."; LOG(INFO) << "[HumanoidRobot](init):All enabled motors initialized successfully.";
} }
template<int DOF> template<int DOF>

View File

@ -3,6 +3,8 @@
// //
#include "service/grpc_dexhand_service.h" #include "service/grpc_dexhand_service.h"
#include <unordered_map>
#include <vector>
using namespace std; using namespace std;
using namespace cmvr::service; using namespace cmvr::service;
using namespace cmvr::device; using namespace cmvr::device;
@ -12,6 +14,26 @@ using namespace cmvr::device;
#define DEXHAND_MAX_FORCE 3000 #define DEXHAND_MAX_FORCE 3000
#define DEXHAND_MAX_SPEED 1000 #define DEXHAND_MAX_SPEED 1000
// 1. 新增静态映射表(类内复用,避免重复定义)
const unordered_map<string, int> gRPCDexHandServiceImpl::kIdToIndex = {
{"little_finger", 0}, // 小拇指 → 索引0
{"ring_finger", 1}, // 无名指 → 索引1
{"middle_finger", 2}, // 中指 → 索引2
{"index_finger", 3}, // 食指 → 索引3
{"thumb_bend", 4}, // 大拇指弯曲 → 索引4
{"thumb_rotate", 5} // 大拇指旋转 → 索引5
};
// 2. 新增索引到字符串的映射用于GetStatus返回string类型dof_id
const vector<string> gRPCDexHandServiceImpl::kIndexToId = {
"little_finger",
"ring_finger",
"middle_finger",
"index_finger",
"thumb_bend",
"thumb_rotate"
};
gRPCDexHandServiceImpl::gRPCDexHandServiceImpl(): dmgr_(DeviceManager::getInstance()) {} gRPCDexHandServiceImpl::gRPCDexHandServiceImpl(): dmgr_(DeviceManager::getInstance()) {}
grpc::Status gRPCDexHandServiceImpl::GetStatus(grpc::ServerContext* context, grpc::Status gRPCDexHandServiceImpl::GetStatus(grpc::ServerContext* context,
@ -23,9 +45,11 @@ grpc::Status gRPCDexHandServiceImpl::GetStatus(grpc::ServerContext* context,
DexHandState state; DexHandState state;
dev->getState(state); dev->getState(state);
response->mutable_state()->set_is_initialized(state.is_initialized); response->mutable_state()->set_is_initialized(state.is_initialized);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
auto hand = response->mutable_state()->add_hands(); auto hand = response->mutable_state()->add_hands();
hand->set_dof_id(i); // 关键修改用索引映射表获取string类型dof_id替代原int类型i
hand->set_dof_id(kIndexToId[i]);
hand->set_angle(state.hands[i].angle); hand->set_angle(state.hands[i].angle);
hand->set_current(state.hands[i].current); hand->set_current(state.hands[i].current);
hand->set_force(state.hands[i].force); hand->set_force(state.hands[i].force);
@ -37,6 +61,7 @@ grpc::Status gRPCDexHandServiceImpl::GetStatus(grpc::ServerContext* context,
hand->add_error_message(errormessage); hand->add_error_message(errormessage);
} }
} }
response->mutable_header()->set_success(true); response->mutable_header()->set_success(true);
setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); setCurrentTimestamp(response->mutable_header()->mutable_timestamp());
return grpc::Status::OK; return grpc::Status::OK;
@ -48,6 +73,7 @@ grpc::Status gRPCDexHandServiceImpl::GetStatus(grpc::ServerContext* context,
return grpc::Status::OK; return grpc::Status::OK;
} }
} }
grpc::Status gRPCDexHandServiceImpl::SetDexHandPos(grpc::ServerContext* context grpc::Status gRPCDexHandServiceImpl::SetDexHandPos(grpc::ServerContext* context
, const cmvr::api::SetDexHandPositionsCommand_Request* request , const cmvr::api::SetDexHandPositionsCommand_Request* request
, cmvr::api::SetDexHandPositionsCommand_Feedback* response){ , cmvr::api::SetDexHandPositionsCommand_Feedback* response){
@ -57,12 +83,21 @@ grpc::Status gRPCDexHandServiceImpl::SetDexHandPos(grpc::ServerContext* context
const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id); const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id);
auto freedoms = request->values(); auto freedoms = request->values();
//默认-1不修改状态 // 默认-1不修改状态6个自由度
std::vector<int> finger_joint_targets(6,-1); std::vector<int> finger_joint_targets(6, -1);
for (auto& freedom : freedoms) { for (auto& freedom : freedoms) {
//遍历拿到需要配置的自由度,传入的是百分比0-1 const string& freedom_id = freedom.id();
finger_joint_targets[freedom.id()] = freedom.value() * DEXHAND_MAX_POSITION; // 查找字符串id对应的索引
auto it = kIdToIndex.find(freedom_id);
if (it == kIdToIndex.end()) {
throw invalid_argument("Invalid freedom id: " + freedom_id);
}
// 计算目标位置(百分比转实际值)
int index = it->second;
finger_joint_targets[index] = freedom.value() * DEXHAND_MAX_POSITION;
} }
dev->setPositions(finger_joint_targets); dev->setPositions(finger_joint_targets);
response->mutable_header()->set_success(true); response->mutable_header()->set_success(true);
setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); setCurrentTimestamp(response->mutable_header()->mutable_timestamp());
@ -85,18 +120,19 @@ grpc::Status gRPCDexHandServiceImpl::SetDexHandAngle(grpc::ServerContext* contex
const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id); const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id);
auto freedoms = request->values(); auto freedoms = request->values();
//默认-1不修改状态 // 默认-1不修改状态6个自由度与映射表数量一致
std::vector<int> finger_joint_targets(6,-1); std::vector<int> finger_joint_targets(6, -1);
for (auto& freedom : freedoms) { for (auto& freedom : freedoms) {
//遍历拿到需要配置的自由度,传入的是百分比0-1 const std::string& freedom_id = freedom.id();
finger_joint_targets[freedom.id()] = freedom.value() * DEXHAND_MAX_ANGLE; auto it = kIdToIndex.find(freedom_id);
if (it == kIdToIndex.end()) {
throw std::invalid_argument("Invalid freedom id: " + freedom_id);
}
int index = it->second;
finger_joint_targets[index] = freedom.value() * DEXHAND_MAX_ANGLE;
} }
// std::cout << "steAngle: ";
// for (auto& angle : finger_joint_targets)
// {
// std::cout << " " << angle;
// }
// std::cout << std::endl;
dev->setAngles(finger_joint_targets); dev->setAngles(finger_joint_targets);
response->mutable_header()->set_success(true); response->mutable_header()->set_success(true);
setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); setCurrentTimestamp(response->mutable_header()->mutable_timestamp());
@ -119,12 +155,21 @@ grpc::Status gRPCDexHandServiceImpl::SetDexHandForce(grpc::ServerContext* contex
const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id); const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id);
auto freedoms = request->values(); auto freedoms = request->values();
//默认-1不修改状态 // 默认-1不修改状态6个自由度
std::vector<int> finger_joint_targets(6,-1); std::vector<int> finger_joint_targets(6, -1);
for (auto& freedom : freedoms) { for (auto& freedom : freedoms) {
//遍历拿到需要配置的自由度,传入的是百分比0-1 const string& freedom_id = freedom.id();
finger_joint_targets[freedom.id()] = freedom.value() * DEXHAND_MAX_FORCE; // 查找字符串id对应的索引
auto it = kIdToIndex.find(freedom_id);
if (it == kIdToIndex.end()) {
throw invalid_argument("Invalid freedom id: " + freedom_id);
}
// 计算目标力值(百分比转实际值)
int index = it->second;
finger_joint_targets[index] = freedom.value() * DEXHAND_MAX_FORCE;
} }
dev->setForce(finger_joint_targets); dev->setForce(finger_joint_targets);
response->mutable_header()->set_success(true); response->mutable_header()->set_success(true);
setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); setCurrentTimestamp(response->mutable_header()->mutable_timestamp());
@ -147,12 +192,21 @@ grpc::Status gRPCDexHandServiceImpl::SetDexHandSpeed(grpc::ServerContext* contex
const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id); const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id);
auto freedoms = request->values(); auto freedoms = request->values();
//默认-1不修改状态 // 默认-1不修改状态6个自由度
std::vector<int> finger_joint_targets(6,-1); std::vector<int> finger_joint_targets(6, -1);
for (auto& freedom : freedoms) { for (auto& freedom : freedoms) {
//遍历拿到需要配置的自由度,传入的是百分比0-1 const string& freedom_id = freedom.id();
finger_joint_targets[freedom.id()] = freedom.value() * DEXHAND_MAX_SPEED; // 查找字符串id对应的索引
auto it = kIdToIndex.find(freedom_id);
if (it == kIdToIndex.end()) {
throw invalid_argument("Invalid freedom id: " + freedom_id);
}
// 计算目标速度(百分比转实际值)
int index = it->second;
finger_joint_targets[index] = freedom.value() * DEXHAND_MAX_SPEED;
} }
dev->setVelocities(finger_joint_targets); dev->setVelocities(finger_joint_targets);
response->mutable_header()->set_success(true); response->mutable_header()->set_success(true);
setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); setCurrentTimestamp(response->mutable_header()->mutable_timestamp());
@ -195,22 +249,18 @@ grpc::Status gRPCDexHandServiceImpl::GetSensorData(grpc::ServerContext* context
string dev_id = request->header().device_id(); string dev_id = request->header().device_id();
LOG(INFO) << "[gRPCDexHandServiceImpl] (GetSensorData): id=" << dev_id; LOG(INFO) << "[gRPCDexHandServiceImpl] (GetSensorData): id=" << dev_id;
const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id); const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id);
//从串口获取传感器数据并返回
auto sensors = dev->getSensorData(); auto sensors = dev->getSensorData();
// 辅助函数将FingerTactileData或PalmTactileData转换为Proto的SensorData
auto fillSensorData = [](const auto& tactileData, auto fillSensorData = [](const auto& tactileData,
cmvr::api::SensorData::FingerType fingerType, cmvr::api::SensorData::FingerType fingerType,
cmvr::api::SensorData::PartType partType, cmvr::api::SensorData::PartType partType,
cmvr::api::SensorData* sensorData) { cmvr::api::SensorData* sensorData) {
// 设置行列数
sensorData->set_rows(tactileData.rows); sensorData->set_rows(tactileData.rows);
sensorData->set_cols(tactileData.cols); sensorData->set_cols(tactileData.cols);
// 设置传感器类型
sensorData->set_finger_type(fingerType); sensorData->set_finger_type(fingerType);
sensorData->set_part_type(partType); sensorData->set_part_type(partType);
sensorData->set_sensor_name(tactileData.name); // 使用原结构体中的name字段 sensorData->set_sensor_name(tactileData.name);
// 填充数据
for (const auto& row : tactileData.data) { for (const auto& row : tactileData.data) {
cmvr::api::SensorData_RowData* rowData = sensorData->add_data(); cmvr::api::SensorData_RowData* rowData = sensorData->add_data();
for (TactilePoint value : row) { for (TactilePoint value : row) {
@ -219,36 +269,24 @@ grpc::Status gRPCDexHandServiceImpl::GetSensorData(grpc::ServerContext* context
} }
}; };
// 1. 填充小拇指数据
fillSensorData(sensors.pinky.tip, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::TIP, response->add_sensor()); fillSensorData(sensors.pinky.tip, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::TIP, response->add_sensor());
fillSensorData(sensors.pinky.finger, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::FINGER, response->add_sensor()); fillSensorData(sensors.pinky.finger, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::FINGER, response->add_sensor());
fillSensorData(sensors.pinky.pad, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::PAD, response->add_sensor()); fillSensorData(sensors.pinky.pad, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::PAD, response->add_sensor());
// 2. 填充无名指数据
fillSensorData(sensors.ring.tip, cmvr::api::SensorData::RING, cmvr::api::SensorData::TIP, response->add_sensor()); fillSensorData(sensors.ring.tip, cmvr::api::SensorData::RING, cmvr::api::SensorData::TIP, response->add_sensor());
fillSensorData(sensors.ring.finger, cmvr::api::SensorData::RING, cmvr::api::SensorData::FINGER, response->add_sensor()); fillSensorData(sensors.ring.finger, cmvr::api::SensorData::RING, cmvr::api::SensorData::FINGER, response->add_sensor());
fillSensorData(sensors.ring.pad, cmvr::api::SensorData::RING, cmvr::api::SensorData::PAD, response->add_sensor()); fillSensorData(sensors.ring.pad, cmvr::api::SensorData::RING, cmvr::api::SensorData::PAD, response->add_sensor());
// 3. 填充中指数据修改为MIDDLE_FINGER
fillSensorData(sensors.middle.tip, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::TIP, response->add_sensor()); fillSensorData(sensors.middle.tip, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::TIP, response->add_sensor());
fillSensorData(sensors.middle.finger, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::FINGER, response->add_sensor()); fillSensorData(sensors.middle.finger, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::FINGER, response->add_sensor());
fillSensorData(sensors.middle.pad, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::PAD, response->add_sensor()); fillSensorData(sensors.middle.pad, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::PAD, response->add_sensor());
// 4. 填充食指数据
fillSensorData(sensors.index.tip, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::TIP, response->add_sensor()); fillSensorData(sensors.index.tip, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::TIP, response->add_sensor());
fillSensorData(sensors.index.finger, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::FINGER, response->add_sensor()); fillSensorData(sensors.index.finger, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::FINGER, response->add_sensor());
fillSensorData(sensors.index.pad, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::PAD, response->add_sensor()); fillSensorData(sensors.index.pad, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::PAD, response->add_sensor());
// 5. 填充大拇指数据修改为THUMB_MIDDLE
fillSensorData(sensors.thumb.tip, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::TIP, response->add_sensor()); fillSensorData(sensors.thumb.tip, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::TIP, response->add_sensor());
fillSensorData(sensors.thumb.finger, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::FINGER, response->add_sensor()); fillSensorData(sensors.thumb.finger, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::FINGER, response->add_sensor());
fillSensorData(sensors.thumb.middle, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::THUMB_MIDDLE, response->add_sensor()); fillSensorData(sensors.thumb.middle, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::THUMB_MIDDLE, response->add_sensor());
fillSensorData(sensors.thumb.pad, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::PAD, response->add_sensor()); fillSensorData(sensors.thumb.pad, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::PAD, response->add_sensor());
// 6. 填充掌心数据使用PALM_PAD
fillSensorData(sensors.palm, cmvr::api::SensorData::PALM, cmvr::api::SensorData::PALM_PAD, response->add_sensor()); fillSensorData(sensors.palm, cmvr::api::SensorData::PALM, cmvr::api::SensorData::PALM_PAD, response->add_sensor());
response->mutable_header()->set_success(true); response->mutable_header()->set_success(true);
setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); setCurrentTimestamp(response->mutable_header()->mutable_timestamp());
return grpc::Status::OK; return grpc::Status::OK;
@ -270,25 +308,22 @@ grpc::Status gRPCDexHandServiceImpl::GetSensorDataStream(grpc::ServerContext* co
string dev_id = request.header().device_id(); string dev_id = request.header().device_id();
LOG(INFO) << "[gRPCDexHandServiceImpl] (GetSensorDataStream): start,id=" << dev_id; LOG(INFO) << "[gRPCDexHandServiceImpl] (GetSensorDataStream): start,id=" << dev_id;
const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id); const auto dev = dmgr_.getDevice<AbstractDexHand>(dev_id);
while (true) while (true)
{ {
api::GetSensorDataStreamCommand_Feedback response; api::GetSensorDataStreamCommand_Feedback response;
//从串口获取传感器数据并返回
auto sensors = dev->getSensorData(); auto sensors = dev->getSensorData();
// 辅助函数将FingerTactileData或PalmTactileData转换为Proto的SensorData
auto fillSensorData = [](const auto& tactileData, auto fillSensorData = [](const auto& tactileData,
cmvr::api::SensorData::FingerType fingerType, cmvr::api::SensorData::FingerType fingerType,
cmvr::api::SensorData::PartType partType, cmvr::api::SensorData::PartType partType,
cmvr::api::SensorData* sensorData) { cmvr::api::SensorData* sensorData) {
// 设置行列数
sensorData->set_rows(tactileData.rows); sensorData->set_rows(tactileData.rows);
sensorData->set_cols(tactileData.cols); sensorData->set_cols(tactileData.cols);
// 设置传感器类型
sensorData->set_finger_type(fingerType); sensorData->set_finger_type(fingerType);
sensorData->set_part_type(partType); sensorData->set_part_type(partType);
sensorData->set_sensor_name(tactileData.name); // 使用原结构体中的name字段 sensorData->set_sensor_name(tactileData.name);
// 填充数据
for (const auto& row : tactileData.data) { for (const auto& row : tactileData.data) {
cmvr::api::SensorData_RowData* rowData = sensorData->add_data(); cmvr::api::SensorData_RowData* rowData = sensorData->add_data();
for (TactilePoint value : row) { for (TactilePoint value : row) {
@ -297,33 +332,22 @@ grpc::Status gRPCDexHandServiceImpl::GetSensorDataStream(grpc::ServerContext* co
} }
}; };
// 1. 填充小拇指数据
fillSensorData(sensors.pinky.tip, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::TIP, response.add_sensor()); fillSensorData(sensors.pinky.tip, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::TIP, response.add_sensor());
fillSensorData(sensors.pinky.finger, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::FINGER, response.add_sensor()); fillSensorData(sensors.pinky.finger, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::FINGER, response.add_sensor());
fillSensorData(sensors.pinky.pad, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::PAD, response.add_sensor()); fillSensorData(sensors.pinky.pad, cmvr::api::SensorData::PINKY, cmvr::api::SensorData::PAD, response.add_sensor());
// 2. 填充无名指数据
fillSensorData(sensors.ring.tip, cmvr::api::SensorData::RING, cmvr::api::SensorData::TIP, response.add_sensor()); fillSensorData(sensors.ring.tip, cmvr::api::SensorData::RING, cmvr::api::SensorData::TIP, response.add_sensor());
fillSensorData(sensors.ring.finger, cmvr::api::SensorData::RING, cmvr::api::SensorData::FINGER, response.add_sensor()); fillSensorData(sensors.ring.finger, cmvr::api::SensorData::RING, cmvr::api::SensorData::FINGER, response.add_sensor());
fillSensorData(sensors.ring.pad, cmvr::api::SensorData::RING, cmvr::api::SensorData::PAD, response.add_sensor()); fillSensorData(sensors.ring.pad, cmvr::api::SensorData::RING, cmvr::api::SensorData::PAD, response.add_sensor());
// 3. 填充中指数据修改为MIDDLE_FINGER
fillSensorData(sensors.middle.tip, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::TIP, response.add_sensor()); fillSensorData(sensors.middle.tip, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::TIP, response.add_sensor());
fillSensorData(sensors.middle.finger, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::FINGER, response.add_sensor()); fillSensorData(sensors.middle.finger, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::FINGER, response.add_sensor());
fillSensorData(sensors.middle.pad, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::PAD, response.add_sensor()); fillSensorData(sensors.middle.pad, cmvr::api::SensorData::MIDDLE_FINGER, cmvr::api::SensorData::PAD, response.add_sensor());
// 4. 填充食指数据
fillSensorData(sensors.index.tip, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::TIP, response.add_sensor()); fillSensorData(sensors.index.tip, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::TIP, response.add_sensor());
fillSensorData(sensors.index.finger, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::FINGER, response.add_sensor()); fillSensorData(sensors.index.finger, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::FINGER, response.add_sensor());
fillSensorData(sensors.index.pad, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::PAD, response.add_sensor()); fillSensorData(sensors.index.pad, cmvr::api::SensorData::INDEX, cmvr::api::SensorData::PAD, response.add_sensor());
// 5. 填充大拇指数据修改为THUMB_MIDDLE
fillSensorData(sensors.thumb.tip, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::TIP, response.add_sensor()); fillSensorData(sensors.thumb.tip, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::TIP, response.add_sensor());
fillSensorData(sensors.thumb.finger, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::FINGER, response.add_sensor()); fillSensorData(sensors.thumb.finger, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::FINGER, response.add_sensor());
fillSensorData(sensors.thumb.middle, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::THUMB_MIDDLE, response.add_sensor()); fillSensorData(sensors.thumb.middle, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::THUMB_MIDDLE, response.add_sensor());
fillSensorData(sensors.thumb.pad, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::PAD, response.add_sensor()); fillSensorData(sensors.thumb.pad, cmvr::api::SensorData::THUMB, cmvr::api::SensorData::PAD, response.add_sensor());
// 6. 填充掌心数据使用PALM_PAD
fillSensorData(sensors.palm, cmvr::api::SensorData::PALM, cmvr::api::SensorData::PALM_PAD, response.add_sensor()); fillSensorData(sensors.palm, cmvr::api::SensorData::PALM, cmvr::api::SensorData::PALM_PAD, response.add_sensor());
if (!stream->Write(response)) { if (!stream->Write(response)) {
@ -338,6 +362,4 @@ grpc::Status gRPCDexHandServiceImpl::GetSensorDataStream(grpc::ServerContext* co
catch (const std::exception& e) { catch (const std::exception& e) {
return grpc::Status::OK; return grpc::Status::OK;
} }
} }

View File

@ -5,6 +5,8 @@
#include "service/grpc_humanoid_robot_service.h" #include "service/grpc_humanoid_robot_service.h"
#include <google/protobuf/util/time_util.h> #include <google/protobuf/util/time_util.h>
#include "cmvr/api/humanoid_robot_command.pb.h"
#include "robot/humanoid_robot/humanoid_robot.h" #include "robot/humanoid_robot/humanoid_robot.h"
#include "cmvr/msgs/geometry.pb.h" #include "cmvr/msgs/geometry.pb.h"
@ -23,6 +25,7 @@ grpc::Status gRPCHumanoidRobotServiceImpl::torqueOff(grpc::ServerContext *contex
grpc::Status ret = grpc::Status::OK; grpc::Status ret = grpc::Status::OK;
try { try {
LOG(INFO) << "[gRPCHumanoidRobotServiceImpl] (torqueOff): id=" << request->device_id();
auto robot = dmgr_.getDevice<AbstractRobot>(request->device_id()); auto robot = dmgr_.getDevice<AbstractRobot>(request->device_id());
robot->torqueOff(); robot->torqueOff();
response->set_success(true); response->set_success(true);
@ -43,6 +46,7 @@ grpc::Status gRPCHumanoidRobotServiceImpl::torqueOn(grpc::ServerContext *context
grpc::Status ret = grpc::Status::OK; grpc::Status ret = grpc::Status::OK;
try { try {
LOG(INFO) << "[gRPCHumanoidRobotServiceImpl] (torqueOn): id=" << request->device_id();
auto robot = dmgr_.getDevice<AbstractRobot>(request->device_id()); auto robot = dmgr_.getDevice<AbstractRobot>(request->device_id());
robot->torqueOn(); robot->torqueOn();
response->set_success(true); response->set_success(true);
@ -62,6 +66,7 @@ grpc::Status gRPCHumanoidRobotServiceImpl::moveJ(grpc::ServerContext *context,
grpc::Status ret = grpc::Status::OK; grpc::Status ret = grpc::Status::OK;
try { try {
LOG(INFO) << "[gRPCHumanoidRobotServiceImpl] (moveJ): id=" << request->header().device_id();
auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id()); auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id());
std::vector<JointPoint> cmds{}; std::vector<JointPoint> cmds{};
for (const auto& jc : request->cmds()) { for (const auto& jc : request->cmds()) {
@ -85,6 +90,7 @@ grpc::Status gRPCHumanoidRobotServiceImpl::moveL(grpc::ServerContext* context, c
grpc::Status ret = grpc::Status::OK; grpc::Status ret = grpc::Status::OK;
try { try {
LOG(INFO) << "[gRPCHumanoidRobotServiceImpl] (moveL): id=" << request->header().device_id();
auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id()); auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id());
auto ee_link = request->ee_link(); auto ee_link = request->ee_link();
msgs::Pose3d pose; msgs::Pose3d pose;
@ -115,12 +121,16 @@ grpc::Status gRPCHumanoidRobotServiceImpl::speedJ(grpc::ServerContext* context,
grpc::Status ret = grpc::Status::OK; grpc::Status ret = grpc::Status::OK;
try try
{ {
LOG(INFO) << "[gRPCHumanoidRobotServiceImpl] (speedJ): id=" << request->header().device_id();
auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id()); auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id());
auto joint_name = request->joint_name(); auto joint_name = request->joint_name();
auto dir = static_cast<device::RobotJointIndexDirection>(request->dir()); auto dir = static_cast<device::RobotJointIndexDirection>(request->dir());
auto vel = request->vel(); auto vel = request->vel();
auto acc = request->acc(); auto acc = request->acc();
robot->speedJ(joint_name,dir,vel,acc); robot->speedJ(joint_name,dir,vel,acc);
response->mutable_header()->set_success(true);
response->mutable_header()->set_error_message("");
}catch (const std::exception& e) { }catch (const std::exception& e) {
response->mutable_header()->set_success(false); response->mutable_header()->set_success(false);
response->mutable_header()->set_error_message(e.what()); response->mutable_header()->set_error_message(e.what());
@ -135,6 +145,7 @@ grpc::Status gRPCHumanoidRobotServiceImpl::speedL(grpc::ServerContext* context,
grpc::Status ret = grpc::Status::OK; grpc::Status ret = grpc::Status::OK;
try try
{ {
LOG(INFO) << "[gRPCHumanoidRobotServiceImpl] (speedL): id=" << request->header().device_id();
auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id()); auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id());
auto ee_link = request->ee_link(); auto ee_link = request->ee_link();
auto dir = static_cast<device::RobotJointIndexDirection>(request->dir()); auto dir = static_cast<device::RobotJointIndexDirection>(request->dir());
@ -144,6 +155,9 @@ grpc::Status gRPCHumanoidRobotServiceImpl::speedL(grpc::ServerContext* context,
robot->setToolFrame(ee_link); robot->setToolFrame(ee_link);
robot->speedL(cart,dir,vel,acc); robot->speedL(cart,dir,vel,acc);
response->mutable_header()->set_success(true);
response->mutable_header()->set_error_message("");
}catch (const std::exception& e) { }catch (const std::exception& e) {
response->mutable_header()->set_success(false); response->mutable_header()->set_success(false);
response->mutable_header()->set_error_message(e.what()); response->mutable_header()->set_error_message(e.what());
@ -153,12 +167,12 @@ grpc::Status gRPCHumanoidRobotServiceImpl::speedL(grpc::ServerContext* context,
return ret; return ret;
} }
grpc::Status gRPCHumanoidRobotServiceImpl::getJointState(grpc::ServerContext *context, grpc::Status gRPCHumanoidRobotServiceImpl::getJointState(grpc::ServerContext *context, const cmvr::api::JointRequest *request, cmvr::api::JointResponse *response) {
const cmvr::api::JointRequest *request, cmvr::api::JointResponse *response) {
grpc::Status ret = grpc::Status::OK; grpc::Status ret = grpc::Status::OK;
try { try {
LOG(INFO) << "[gRPCHumanoidRobotServiceImpl] (getJointState): id=" << request->header().device_id();
auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id()); auto robot = dmgr_.getDevice<AbstractRobot>(request->header().device_id());
std::vector<cmvr::device::JointState> states{}; std::vector<cmvr::device::JointState> states{};