diff --git a/src/viam/sdk/robot/client.cpp b/src/viam/sdk/robot/client.cpp index 25613ac88..fff691fd2 100644 --- a/src/viam/sdk/robot/client.cpp +++ b/src/viam/sdk/robot/client.cpp @@ -355,5 +355,43 @@ void RobotClient::stop_all(const std::unordered_map& extra) { } } +std::ostream& operator<<(std::ostream& os, const RobotClient::status& v) { + std::string status; + switch (v) { + case RobotClient::status::k_running: + status = "running"; + break; + case RobotClient::status::k_initializing: + status = "initializing"; + break; + case RobotClient::status::k_unspecified: + default: + status = "unspecified"; + } + os << status; + return os; +} + +RobotClient::status RobotClient::get_machine_status() const { + const robot::v1::GetMachineStatusRequest req; + robot::v1::GetMachineStatusResponse resp; + ClientContext ctx; + + const grpc::Status response = impl_->stub_->GetMachineStatus(ctx, req, &resp); + if (is_error_response(response)) { + BOOST_LOG_TRIVIAL(error) << "Error getting machine status: " << response.error_message() + << response.error_details(); + } + switch (resp.state()) { + case robot::v1::GetMachineStatusResponse_State_STATE_INITIALIZING: + return RobotClient::status::k_initializing; + case robot::v1::GetMachineStatusResponse_State_STATE_RUNNING: + return RobotClient::status::k_running; + case robot::v1::GetMachineStatusResponse_State_STATE_UNSPECIFIED: + default: + return RobotClient::status::k_unspecified; + } +} + } // namespace sdk } // namespace viam diff --git a/src/viam/sdk/robot/client.hpp b/src/viam/sdk/robot/client.hpp index fd62660af..9d63bd14b 100644 --- a/src/viam/sdk/robot/client.hpp +++ b/src/viam/sdk/robot/client.hpp @@ -34,6 +34,17 @@ namespace sdk { /// `with_channel` require a user call to `close()`. class RobotClient { public: + /// @enum status + /// @brief the current status of the robot + /// @ingroup Robot + enum class status : uint8_t { + k_initializing, + k_running, + k_unspecified, + }; + + friend std::ostream& operator<<(std::ostream& os, const status& v); + struct frame_system_config { WorldState::transform frame; ProtoStruct kinematics; @@ -132,6 +143,9 @@ class RobotClient { /// @param id The ID of the operation to cancel. void cancel_operation(std::string id); + /// @brief gets the current status of the machine + status get_machine_status() const; + private: std::vector> threads_; std::atomic should_refresh_; diff --git a/src/viam/sdk/tests/mocks/mock_robot.cpp b/src/viam/sdk/tests/mocks/mock_robot.cpp index 2aa15ef8e..cdef0fe78 100644 --- a/src/viam/sdk/tests/mocks/mock_robot.cpp +++ b/src/viam/sdk/tests/mocks/mock_robot.cpp @@ -322,6 +322,21 @@ ::grpc::Status MockRobotService::TransformPose(::grpc::ServerContext* context, return ::grpc::Status(); } +::grpc::Status MockRobotService::GetMachineStatus( + ::grpc::ServerContext* context, + const ::viam::robot::v1::GetMachineStatusRequest*, + ::viam::robot::v1::GetMachineStatusResponse* response) { + auto client_md = context->client_metadata(); + if (auto client_info = client_md.find("viam_client"); client_info == client_md.end()) { + return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, + "viam_client info not properly set in metadata"); + } + + response->set_state(::viam::robot::v1::GetMachineStatusResponse_State_STATE_RUNNING); + + return ::grpc::Status(); +} + ::grpc::Status MockRobotService::GetOperations(::grpc::ServerContext* context, const ::viam::robot::v1::GetOperationsRequest*, ::viam::robot::v1::GetOperationsResponse* response) { diff --git a/src/viam/sdk/tests/mocks/mock_robot.hpp b/src/viam/sdk/tests/mocks/mock_robot.hpp index 2ad224232..6ef384be6 100644 --- a/src/viam/sdk/tests/mocks/mock_robot.hpp +++ b/src/viam/sdk/tests/mocks/mock_robot.hpp @@ -46,6 +46,10 @@ class MockRobotService : public ResourceServer, public viam::robot::v1::RobotSer const ::viam::robot::v1::TransformPoseRequest* request, ::viam::robot::v1::TransformPoseResponse* response) override; + ::grpc::Status GetMachineStatus(::grpc::ServerContext* context, + const ::viam::robot::v1::GetMachineStatusRequest* request, + ::viam::robot::v1::GetMachineStatusResponse* response) override; + ::grpc::Status GetOperations(::grpc::ServerContext* context, const ::viam::robot::v1::GetOperationsRequest* request, ::viam::robot::v1::GetOperationsResponse* response) override; diff --git a/src/viam/sdk/tests/test_robot.cpp b/src/viam/sdk/tests/test_robot.cpp index 8a57adac3..9f1093d49 100644 --- a/src/viam/sdk/tests/test_robot.cpp +++ b/src/viam/sdk/tests/test_robot.cpp @@ -190,6 +190,15 @@ BOOST_AUTO_TEST_CASE(test_transform_pose) { }); } +BOOST_AUTO_TEST_CASE(test_get_machine_status) { + robot_client_to_mocks_pipeline( + [](std::shared_ptr client, MockRobotService& service) -> void { + auto status = client->get_machine_status(); + + BOOST_CHECK_EQUAL(status, RobotClient::status::k_running); + }); +} + BOOST_AUTO_TEST_CASE(test_stop_all) { robot_client_to_mocks_pipeline( [](std::shared_ptr client, MockRobotService& service) -> void {