FP Perception 0.1.2
Loading...
Searching...
No Matches
sentiment_driver.hpp
Go to the documentation of this file.
1#pragma once
2
6#include <rclcpp/rclcpp.hpp>
7#include <string>
8#include <vector>
9
10namespace fp_perception
11{
21{
22public:
29 {
30 }
31
38 {
40 }
41
49 void initialize(const rclcpp::Node::SharedPtr& node) override
50 {
51 // Confirm parameters for the node
52 node->declare_parameter("driver.sentiment.SentimentDriver.name", "SentimentDriver");
53
54 name_ = node->get_parameter("driver.sentiment.SentimentDriver.name").as_string();
55
56 // Initialize the base driver
57 initialize_rest_base(node, "driver.sentiment.SentimentDriver", "HUGGINGFACE_API_KEY");
58
59 // Log the parameters
60 RCLCPP_INFO(node_->get_logger(), "Assigned driver Name: %s", name_.c_str());
61
63 {
64 enable_diagnostics("rest-sentiment-" + name_, name_ + " status",
65 [this](diagnostic_updater::DiagnosticStatusWrapper& status) { produce_diagnostics(status); });
66 }
67
68 // Log that the driver has been initialized
69 RCLCPP_INFO(node_->get_logger(), "Initialized");
70 }
71
77 void deinitialize() override
78 {
81 name_.clear();
82 node_.reset();
83 }
84
93 sentiment_result analyze(const sentiment_request& request_data) override
94 {
96 request.prompt = request_data.text;
97
98 response_ = call(request);
99
100 sentiment_result result;
101 result.label = response_.response;
102 result.score = response_.confidence;
103 result.analyzed_text = request_data.text;
104 result.success = !response_.response.empty();
105 if (!result.success)
106 result.error = "No response received from sentiment analysis service";
107
108 last_result_ = result;
109 return last_result_;
110 }
116 void test() override
117 {
118 RCLCPP_INFO(node_->get_logger(), "Testing SentimentDriver with model: %s", uri_.c_str());
119
120 // Example test input
121 sentiment_request request;
122 request.text = "I love programming!";
123
124 // Wait for the service to process the request
125 RCLCPP_INFO(node_->get_logger(), "Initiated Sentiment analysis for text: %s", request.text.c_str());
126
127 const auto sentiment = analyze(request);
128
129 if (sentiment.success)
130 {
131 RCLCPP_INFO(node_->get_logger(), "Analysis results with sentiment: %s and confidence: %f",
132 sentiment.label.c_str(), sentiment.score);
133 }
134 else
135 {
136 throw fp_perception_exception(sentiment.error.empty() ? "No response received from sentiment analysis service" :
137 sentiment.error);
138 }
139
140 RCLCPP_INFO(node_->get_logger(), "Test completed.");
141 }
142
143protected:
153 nlohmann::json toJson(const fp_perception::RESTRequest& request) override
154 {
155 nlohmann::json result;
156
157 // Add options
158 for (const auto& option : request.options)
159 {
160 result[option.key] = option.value;
161 }
162
163 // Add prompt
164 result["inputs"] = request.prompt;
165
166 return result;
167 }
168
177 fp_perception::RESTResponse fromJson(const nlohmann::json& object) override
178 {
180
181 // Hugging Face returns a double-nested array: [[{label, score}, {label, score}]]
182 if (object.is_array() && !object.empty() && object[0].is_array() && !object[0].empty())
183 {
184 const auto& firstResult = object[0][0];
185 if (firstResult.contains("label") && firstResult.contains("score"))
186 {
187 res.response = firstResult["label"].get<std::string>();
188 res.confidence = firstResult["score"].get<double>();
189 }
190 }
191 else
192 throw fp_perception_exception("Unexpected sentiment JSON structure received");
193
194 return res;
195 }
196
197 void produce_diagnostics(diagnostic_updater::DiagnosticStatusWrapper& status)
198 {
199 std::string last_error;
200 {
201 std::lock_guard<std::mutex> lock(rest_status_mutex_);
202 last_error = last_rest_error_;
203 }
204
205 if (rest_request_count_.load() == 0)
206 status.summary(diagnostic_msgs::msg::DiagnosticStatus::OK, "Sentiment driver idle");
207 else if (last_rest_success_.load())
208 status.summary(diagnostic_msgs::msg::DiagnosticStatus::OK, "Last sentiment request succeeded");
209 else
210 status.summary(diagnostic_msgs::msg::DiagnosticStatus::WARN, "Last sentiment request failed");
211
212 status.add("uri", uri_);
213 status.add("request_count", rest_request_count_.load());
214 status.add("failure_count", rest_failure_count_.load());
215 status.add("last_http_code", last_rest_http_code_.load());
216 status.add("last_result_success", last_result_.success ? "true" : "false");
217 status.add("last_label", last_result_.label.empty() ? std::string("none") : last_result_.label);
218 status.add("last_score", last_result_.score);
219 status.add("last_error", last_error.empty() ? std::string("none") : last_error);
220 }
221
224};
225
226} // namespace fp_perception
std::string name_
Name of the driver.
Definition driver_base.hpp:143
rclcpp::Node::SharedPtr node_
ROS node for the driver.
Definition driver_base.hpp:138
void disable_diagnostics()
Definition driver_base.hpp:129
bool diagnostics_enabled() const
Definition driver_base.hpp:105
void enable_diagnostics(const std::string &hardware_id, const std::string &task_name, std::function< void(diagnostic_updater::DiagnosticStatusWrapper &)> task, std::chrono::milliseconds period=std::chrono::seconds(1))
Definition driver_base.hpp:110
RestBase.
Definition rest_base.hpp:23
virtual fp_perception::RESTResponse call(const fp_perception::RESTRequest &req)
Request data from the REST API.
Definition rest_base.hpp:117
std::atomic< bool > last_rest_success_
Definition rest_base.hpp:515
std::string last_rest_error_
Definition rest_base.hpp:518
std::mutex rest_status_mutex_
Definition rest_base.hpp:517
std::atomic< uint64_t > rest_request_count_
Definition rest_base.hpp:513
std::atomic< long > last_rest_http_code_
Definition rest_base.hpp:516
std::string uri_
Definition rest_base.hpp:506
std::atomic< uint64_t > rest_failure_count_
Definition rest_base.hpp:514
virtual void initialize_rest_base(const rclcpp::Node::SharedPtr &node, std::string plugin_name="RestBase", std::string api_key_name="")
Initialize the REST base class.
Definition rest_base.hpp:51
Definition sentiment_analysis_driver.hpp:10
SentimentDriver class for handling prompt_tools based sentument analysis.
Definition sentiment_driver.hpp:21
sentiment_result last_result_
Definition sentiment_driver.hpp:223
fp_perception::RESTResponse fromJson(const nlohmann::json &object) override
Convert a JSON object to a RESTResponse.
Definition sentiment_driver.hpp:177
void produce_diagnostics(diagnostic_updater::DiagnosticStatusWrapper &status)
Definition sentiment_driver.hpp:197
sentiment_result analyze(const sentiment_request &request_data) override
Set data to the driver.
Definition sentiment_driver.hpp:93
SentimentDriver()
Constructor for SentimentDriver.
Definition sentiment_driver.hpp:28
void initialize(const rclcpp::Node::SharedPtr &node) override
Initialize the driver.
Definition sentiment_driver.hpp:49
void test() override
Test method for the driver.
Definition sentiment_driver.hpp:116
void deinitialize() override
Deinitialize the driver.
Definition sentiment_driver.hpp:77
nlohmann::json toJson(const fp_perception::RESTRequest &request) override
Convert a prompt request to a JSON object.
Definition sentiment_driver.hpp:153
fp_perception::RESTResponse response_
Definition sentiment_driver.hpp:222
~SentimentDriver() override
Destructor for SentimentDriver.
Definition sentiment_driver.hpp:37
Definition audio_buffer.hpp:16
Definition structs.hpp:26
std::string prompt
Definition structs.hpp:27
std::vector< RESTOption > options
Definition structs.hpp:30
Definition structs.hpp:35
double confidence
Definition structs.hpp:41
std::string response
Definition structs.hpp:36
Base class for driver exceptions.
Definition exceptions.hpp:14
Definition structs.hpp:11
std::string text
Definition structs.hpp:12
Definition structs.hpp:20
std::string error
Definition structs.hpp:25
std::string analyzed_text
Definition structs.hpp:23
double score
Definition structs.hpp:22
std::string label
Definition structs.hpp:21
bool success
Definition structs.hpp:24