From f47a93c21fcfb4404e123ee069b974697694c55e Mon Sep 17 00:00:00 2001 From: tankaitao <1767759995@qq.com> Date: Thu, 4 Dec 2025 15:09:46 +0800 Subject: [PATCH] update --- config/cabin_robot.xml | 78 +++---- protos/cmvr/api/biohead_command.proto | 40 +++- protos/cmvr/api/biohead_service.proto | 11 + src/devices/biohead/abstract_biohead.h | 9 +- .../biohead_esp32/include/biohead_esp32.h | 3 + .../biohead_esp32/src/biohead_esp32.cpp | 217 ++++++++++++++++++ src/service/include/grpc_head_service.h | 5 + src/service/src/grpc_head_service.cpp | 74 ++++++ 8 files changed, 393 insertions(+), 44 deletions(-) diff --git a/config/cabin_robot.xml b/config/cabin_robot.xml index 999536e0..08542302 100644 --- a/config/cabin_robot.xml +++ b/config/cabin_robot.xml @@ -32,47 +32,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + diff --git a/protos/cmvr/api/biohead_command.proto b/protos/cmvr/api/biohead_command.proto index 04bcd472..cc91e3eb 100644 --- a/protos/cmvr/api/biohead_command.proto +++ b/protos/cmvr/api/biohead_command.proto @@ -196,7 +196,7 @@ message SpeakStop { -// 表情控制 - 高兴 +// 表情控制 - 微笑 message Happy { message Request { CommandHeader.Request header = 1; // 通用命令头 @@ -220,7 +220,7 @@ message Surprise { } - +//表情控制-疲惫 message ExpressionTired { message Request { CommandHeader.Request header = 1; @@ -231,4 +231,40 @@ message ExpressionTired { } } +//表情控制-愤怒 +message ExpressionAngry { + message Request { + CommandHeader.Request header = 1; + } + + message Feedback { + CommandHeader.Feedback header = 1; + } +} + + +//表情控制-悲伤 +message ExpressionSadness { + message Request { + CommandHeader.Request header = 1; + } + + message Feedback { + CommandHeader.Feedback header = 1; + } +} + +//表情控制-打哈欠 +message ExpressionYawn { + message Request { + CommandHeader.Request header = 1; + } + + message Feedback { + CommandHeader.Feedback header = 1; + } +} + + + diff --git a/protos/cmvr/api/biohead_service.proto b/protos/cmvr/api/biohead_service.proto index 6206c5f5..f2dda323 100644 --- a/protos/cmvr/api/biohead_service.proto +++ b/protos/cmvr/api/biohead_service.proto @@ -31,6 +31,17 @@ service BioHeadService { rpc ExpressionTired(ExpressionTired.Request) returns (ExpressionTired.Feedback){}; + rpc ExpressionAngry(ExpressionAngry.Request) returns (ExpressionAngry.Feedback){}; + + rpc ExpressionSadness(ExpressionSadness.Request) returns (ExpressionSadness.Feedback){}; + + rpc ExpressionYawn(ExpressionYawn.Request) returns (ExpressionYawn.Feedback){}; + + + + + + } \ No newline at end of file diff --git a/src/devices/biohead/abstract_biohead.h b/src/devices/biohead/abstract_biohead.h index 4ebf5233..93e0eb20 100644 --- a/src/devices/biohead/abstract_biohead.h +++ b/src/devices/biohead/abstract_biohead.h @@ -68,9 +68,12 @@ namespace cmvr::device { virtual void speakstart(){}; virtual void speakstop(){}; - virtual void expressionHappy() {}; // 高兴 - virtual void expressionSurprised() {}; // 惊讶 - virtual void expressionTired() {}; // 困倦(疲惫) + virtual void expressionHappy() {}; + virtual void expressionSurprised() {}; + virtual void expressionTired() {}; + virtual void expressionAngry() {}; + virtual void expressionSadness() {}; + virtual void expressionYawn() {}; FacialExpressionState expression_state_; std::atomic emergency_stop_requested = false; diff --git a/src/devices/biohead/biohead_esp32/include/biohead_esp32.h b/src/devices/biohead/biohead_esp32/include/biohead_esp32.h index 6c96aa23..0e6937ae 100644 --- a/src/devices/biohead/biohead_esp32/include/biohead_esp32.h +++ b/src/devices/biohead/biohead_esp32/include/biohead_esp32.h @@ -32,6 +32,9 @@ namespace cmvr::device { void expressionHappy()override; void expressionSurprised()override; void expressionTired()override; + void expressionAngry() override; + void expressionSadness()override; + void expressionYawn()override; private: diff --git a/src/devices/biohead/biohead_esp32/src/biohead_esp32.cpp b/src/devices/biohead/biohead_esp32/src/biohead_esp32.cpp index c5aa39d6..91d6ecf8 100644 --- a/src/devices/biohead/biohead_esp32/src/biohead_esp32.cpp +++ b/src/devices/biohead/biohead_esp32/src/biohead_esp32.cpp @@ -610,6 +610,36 @@ void BioHeadRobot::expressionHappy() { } serial_->sendRawServoData(raw_data); + std::this_thread::sleep_for(std::chrono::seconds(3)); + + // 设备64角度(10通道) + const std::vector device_64_neutral = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; + // 设备65角度(10通道) + const std::vector device_65_neutral = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; + + std::vector raw_data_neutral; + + // 下发设备64的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_64_neutral[ch])); + raw_data_neutral.push_back(64); // 地址 + raw_data_neutral.push_back(ch); // 通道号 + raw_data_neutral.push_back(angle); // 角度 + raw_data_neutral.push_back(step_ms & 0xFF); // 低字节 + raw_data_neutral.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + // 下发设备65的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_65_neutral[ch])); + raw_data_neutral.push_back(65); // 地址 + raw_data_neutral.push_back(ch); // 通道号 + raw_data_neutral.push_back(angle); // 角度 + raw_data_neutral.push_back(step_ms & 0xFF); // 低字节 + raw_data_neutral.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + serial_->sendRawServoData(raw_data_neutral); } @@ -708,7 +738,194 @@ void BioHeadRobot::expressionTired() { } +void BioHeadRobot::expressionAngry() { + const int step_ms = 200; + // 设备64角度(10通道) + const std::vector device_64_angles = {90, 90, 90, 90, 40, 120, 125, 50, 90, 90}; + // 设备65角度(10通道) + const std::vector device_65_angles = {90, 85, 95, 100, 90, 105, 80, 110, 85, 95}; + + std::vector raw_data; + + // 下发设备64的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_64_angles[ch])); + raw_data.push_back(64); // 地址 + raw_data.push_back(ch); // 通道号 + raw_data.push_back(angle); // 角度 + raw_data.push_back(step_ms & 0xFF); // 低字节 + raw_data.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + // 下发设备65的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_65_angles[ch])); + raw_data.push_back(65); // 地址 + raw_data.push_back(ch); // 通道号 + raw_data.push_back(angle); // 角度 + raw_data.push_back(step_ms & 0xFF); // 低字节 + raw_data.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + serial_->sendRawServoData(raw_data); + std::this_thread::sleep_for(std::chrono::seconds(3)); + + // 设备64角度(10通道) + const std::vector device_64_neutral = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; + // 设备65角度(10通道) + const std::vector device_65_neutral = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; + + std::vector raw_data_neutral; + + // 下发设备64的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_64_neutral[ch])); + raw_data_neutral.push_back(64); // 地址 + raw_data_neutral.push_back(ch); // 通道号 + raw_data_neutral.push_back(angle); // 角度 + raw_data_neutral.push_back(step_ms & 0xFF); // 低字节 + raw_data_neutral.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + // 下发设备65的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_65_neutral[ch])); + raw_data_neutral.push_back(65); // 地址 + raw_data_neutral.push_back(ch); // 通道号 + raw_data_neutral.push_back(angle); // 角度 + raw_data_neutral.push_back(step_ms & 0xFF); // 低字节 + raw_data_neutral.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + serial_->sendRawServoData(raw_data_neutral); +} + +void BioHeadRobot::expressionSadness() { + const int step_ms = 200; + + // 设备64角度(10通道) + const std::vector device_64_angles = {90, 90, 90, 90, 40, 120, 125, 50, 90, 90}; + // 设备65角度(10通道) + const std::vector device_65_angles = {90, 85, 95, 100, 90, 105, 80, 110, 85, 95}; + + std::vector raw_data; + + // 下发设备64的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_64_angles[ch])); + raw_data.push_back(64); // 地址 + raw_data.push_back(ch); // 通道号 + raw_data.push_back(angle); // 角度 + raw_data.push_back(step_ms & 0xFF); // 低字节 + raw_data.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + // 下发设备65的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_65_angles[ch])); + raw_data.push_back(65); // 地址 + raw_data.push_back(ch); // 通道号 + raw_data.push_back(angle); // 角度 + raw_data.push_back(step_ms & 0xFF); // 低字节 + raw_data.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + serial_->sendRawServoData(raw_data); + std::this_thread::sleep_for(std::chrono::seconds(3)); + + // 设备64角度(10通道) + const std::vector device_64_neutral = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; + // 设备65角度(10通道) + const std::vector device_65_neutral = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; + + std::vector raw_data_neutral; + + // 下发设备64的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_64_neutral[ch])); + raw_data_neutral.push_back(64); // 地址 + raw_data_neutral.push_back(ch); // 通道号 + raw_data_neutral.push_back(angle); // 角度 + raw_data_neutral.push_back(step_ms & 0xFF); // 低字节 + raw_data_neutral.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + // 下发设备65的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_65_neutral[ch])); + raw_data_neutral.push_back(65); // 地址 + raw_data_neutral.push_back(ch); // 通道号 + raw_data_neutral.push_back(angle); // 角度 + raw_data_neutral.push_back(step_ms & 0xFF); // 低字节 + raw_data_neutral.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + serial_->sendRawServoData(raw_data_neutral); +} + +void BioHeadRobot::expressionYawn() { + const int step_ms = 200; + + // 设备64角度(10通道) + const std::vector device_64_angles = {90, 90, 90, 90, 40, 120, 125, 50, 90, 90}; + // 设备65角度(10通道) + const std::vector device_65_angles = {90, 85, 95, 100, 90, 105, 80, 110, 85, 95}; + + std::vector raw_data; + + // 下发设备64的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_64_angles[ch])); + raw_data.push_back(64); // 地址 + raw_data.push_back(ch); // 通道号 + raw_data.push_back(angle); // 角度 + raw_data.push_back(step_ms & 0xFF); // 低字节 + raw_data.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + // 下发设备65的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_65_angles[ch])); + raw_data.push_back(65); // 地址 + raw_data.push_back(ch); // 通道号 + raw_data.push_back(angle); // 角度 + raw_data.push_back(step_ms & 0xFF); // 低字节 + raw_data.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + serial_->sendRawServoData(raw_data); + std::this_thread::sleep_for(std::chrono::seconds(3)); + + // 设备64角度(10通道) + const std::vector device_64_neutral = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; + // 设备65角度(10通道) + const std::vector device_65_neutral = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; + + std::vector raw_data_neutral; + + // 下发设备64的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_64_neutral[ch])); + raw_data_neutral.push_back(64); // 地址 + raw_data_neutral.push_back(ch); // 通道号 + raw_data_neutral.push_back(angle); // 角度 + raw_data_neutral.push_back(step_ms & 0xFF); // 低字节 + raw_data_neutral.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + // 下发设备65的10个通道(0~9) + for (int ch = 0; ch < 10; ++ch) { + uint8_t angle = static_cast(std::round(device_65_neutral[ch])); + raw_data_neutral.push_back(65); // 地址 + raw_data_neutral.push_back(ch); // 通道号 + raw_data_neutral.push_back(angle); // 角度 + raw_data_neutral.push_back(step_ms & 0xFF); // 低字节 + raw_data_neutral.push_back((step_ms >> 8) & 0xFF); // 高字节 + } + + serial_->sendRawServoData(raw_data_neutral); +} diff --git a/src/service/include/grpc_head_service.h b/src/service/include/grpc_head_service.h index 4b6552e9..e3875f9a 100644 --- a/src/service/include/grpc_head_service.h +++ b/src/service/include/grpc_head_service.h @@ -36,6 +36,11 @@ namespace cmvr::service grpc::Status ExpressionTired(grpc::ServerContext* context, const cmvr::api::ExpressionTired_Request* request, cmvr::api::ExpressionTired_Feedback* response) override; + grpc::Status ExpressionAngry(grpc::ServerContext* context, const cmvr::api::ExpressionAngry_Request* request, cmvr::api::ExpressionAngry_Feedback* response) override; + + grpc::Status ExpressionSadness(grpc::ServerContext* context, const cmvr::api::ExpressionSadness_Request* request, cmvr::api::ExpressionSadness_Feedback* response) override; + + grpc::Status ExpressionYawn(grpc::ServerContext* context, const cmvr::api::ExpressionYawn_Request* request, cmvr::api::ExpressionYawn_Feedback* response) override; private: device::DeviceManager& dmgr_; }; diff --git a/src/service/src/grpc_head_service.cpp b/src/service/src/grpc_head_service.cpp index 42075e95..c5694f61 100644 --- a/src/service/src/grpc_head_service.cpp +++ b/src/service/src/grpc_head_service.cpp @@ -350,3 +350,77 @@ grpc::Status gRPCMBioHeadServiceImpl::ExpressionTired(grpc::ServerContext* conte return grpc::Status::OK; } } + + + +grpc::Status gRPCMBioHeadServiceImpl::ExpressionAngry(grpc::ServerContext* context, const cmvr::api::ExpressionAngry_Request* request, cmvr::api::ExpressionAngry_Feedback* response) +{ + try { + string dev_id = request->header().device_id(); + auto robot = dmgr_.getDevice(dev_id); + if (!robot) { + throw runtime_error("Biohead device not found"); + } + + robot->expressionAngry(); // 停止执行 + + response->mutable_header()->set_success(true); + setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); + return grpc::Status::OK; + } + catch (const exception& e) { + response->mutable_header()->set_success(false); + response->mutable_header()->set_error_message(e.what()); + setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); + return grpc::Status::OK; + } +} + + + +grpc::Status gRPCMBioHeadServiceImpl::ExpressionSadness(grpc::ServerContext* context, const cmvr::api::ExpressionSadness_Request* request, cmvr::api::ExpressionSadness_Feedback* response) +{ + try { + string dev_id = request->header().device_id(); + auto robot = dmgr_.getDevice(dev_id); + if (!robot) { + throw runtime_error("Biohead device not found"); + } + + robot->expressionAngry(); // 停止执行 + + response->mutable_header()->set_success(true); + setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); + return grpc::Status::OK; + } + catch (const exception& e) { + response->mutable_header()->set_success(false); + response->mutable_header()->set_error_message(e.what()); + setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); + return grpc::Status::OK; + } +} + + +grpc::Status gRPCMBioHeadServiceImpl::ExpressionYawn(grpc::ServerContext* context, const cmvr::api::ExpressionYawn_Request* request, cmvr::api::ExpressionYawn_Feedback* response) +{ + try { + string dev_id = request->header().device_id(); + auto robot = dmgr_.getDevice(dev_id); + if (!robot) { + throw runtime_error("Biohead device not found"); + } + + robot->expressionYawn(); // 停止执行 + + response->mutable_header()->set_success(true); + setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); + return grpc::Status::OK; + } + catch (const exception& e) { + response->mutable_header()->set_success(false); + response->mutable_header()->set_error_message(e.what()); + setCurrentTimestamp(response->mutable_header()->mutable_timestamp()); + return grpc::Status::OK; + } +}