YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
Battery_nws_yarp.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: LGPL-2.1-or-later
4 */
5
6#include "Battery_nws_yarp.h"
7#include <sstream>
8#include <string>
10#include <yarp/os/LogStream.h>
11#include <time.h>
12#include <stdlib.h>
13
14using namespace yarp::sig;
15using namespace yarp::dev;
16using namespace yarp::os;
17
18namespace {
19YARP_LOG_COMPONENT(BATTERYWRAPPER, "yarp.devices.Battery_nws_yarp")
20}
21
27
29{
31 m_ibattery_p = nullptr;
32}
33
34bool Battery_nws_yarp::attach(PolyDriver* driver)
35{
36 if (driver==nullptr)
37 {
38 yCError(BATTERYWRAPPER, "Invalid pointer to device driver received");
39 return false;
40 }
41
42 driver->view(m_ibattery_p);
43 if (nullptr == m_ibattery_p)
44 {
45 yCError(BATTERYWRAPPER, "Unable to view IBattery interface");
46 return false;
47 }
48 m_msgsImpl = std::make_unique<IBatteryMsgsImpl>(m_ibattery_p);
49
52 return true;
53}
54
55bool Battery_nws_yarp::detach()
56{
58 {
60 }
61 m_ibattery_p = nullptr;
62 return true;
63}
64
65bool Battery_nws_yarp::read(yarp::os::ConnectionReader& connection)
66{
67 if (!connection.isValid()) { return false;}
68 if (!m_msgsImpl) { return false;}
69
70 bool b = m_msgsImpl->read(connection);
71 if (b)
72 {
73 return true;
74 }
75 else
76 {
77 yCError(BATTERYWRAPPER, "read() Command failed");
78 return false;
79 }
80}
81
83{
84 return true;
85}
86
88{
89 if (!parseParams(config)) { return false; }
90
91 m_streamingPortName = m_name + "/data:o";
92 m_rpcPortName = m_name + "/rpc:i";
93
94 if(!initialize_YARP(config))
95 {
96 yCError(BATTERYWRAPPER) << m_sensorId << "Error initializing YARP ports";
97 return false;
98 }
99
100 if (m_enable_log)
101 {
102 yCInfo(BATTERYWRAPPER, "writing to log file batteryLog.txt");
103 m_logFile = fopen("batteryLog.txt", "w");
104 }
105
106 return true;
107}
108
109bool Battery_nws_yarp::initialize_YARP(yarp::os::Searchable &params)
110{
111 if (!m_streamingPort.open(m_streamingPortName.c_str()))
112 {
113 yCError(BATTERYWRAPPER) << "Error opening port" << m_streamingPortName;
114 return false;
115 }
116 if (!m_rpcPort.open(m_rpcPortName.c_str()))
117 {
118 yCError(BATTERYWRAPPER) << "Error opening port" << m_rpcPortName;
119 return false;
120 }
121 m_rpcPort.setReader(*this);
122 return true;
123}
124
128
130{
131 if (m_ibattery_p!=nullptr)
132 {
133 m_log_buffer[0] = 0;
134
135 //acquire data from the wrapped device
137 {
138 double tmp;
139 ret_chg = m_ibattery_p->getBatteryCharge(tmp);
140 if (ret_chg) {
141 m_battery_charge = tmp;
142 }
143 }
144 {
145 double tmp;
146 ret_vlt = m_ibattery_p->getBatteryVoltage(tmp);
147 if (ret_vlt) {
148 m_battery_voltage = tmp;
149 }
150 }
151 {
152 double tmp;
153 ret_cur = m_ibattery_p->getBatteryCurrent(tmp);
154 if (ret_cur) {
155 m_battery_current = tmp;
156 }
157 }
158 {
159 double tmp;
160 ret_tmp = m_ibattery_p->getBatteryTemperature(tmp);
161 if (ret_tmp) {
162 m_battery_temperature = tmp;
163 }
164 }
165 {
167 ret_sts = m_ibattery_p->getBatteryStatus(tmp);
168 if (ret_sts) {
169 m_battery_status = tmp;
170 }
171 }
172
173 if (ret_sts)
174 {
175 m_lastStateStamp.update();
176 yarp::dev::BatteryData& b = m_streamingPort.prepare();
177 b.voltage = m_battery_voltage;
178 b.current = m_battery_current;
179 b.charge = m_battery_charge;
180 b.temperature = m_battery_temperature;
181 b.status = m_battery_status;
182 m_streamingPort.setEnvelope(m_lastStateStamp);
183 m_streamingPort.write();
184
185 // if the battery is not charging, checks its status of charge
186 if (m_battery_status > 0.4) {
187 check_battery_status(m_battery_charge);
188 }
189
190 // save data to file
191 if (m_enable_log)
192 {
194 struct tm * timeinfo;
195 time(&rawtime);
198 std::snprintf(m_log_buffer, 1024, "battery status: %+6.1fA % 6.1fV charge:% 6.1f%% time: %s", m_battery_current, m_battery_voltage, m_battery_charge, battery_timestamp);
199 fprintf(m_logFile, "%s", m_log_buffer);
200 }
201 }
202 else
203 {
204 yCError(BATTERYWRAPPER, "BatteryWrapper: %s: Sensor returned error", m_sensorId.c_str());
205 }
206 }
207}
208
210{
211 yCTrace(BATTERYWRAPPER, "BatteryWrapper::Close");
213 {
215 }
216
217 m_streamingPort.close();
218 m_rpcPort.close();
219
220 // save data to file
221 if (m_enable_log)
222 {
223 fclose(m_logFile);
224 }
225
227 detachAll();
228 return true;
229}
230
231void Battery_nws_yarp::notify_message(std::string msg)
232{
233#ifdef WIN32
234 yCWarning(BATTERYWRAPPER, "%s", msg.c_str());
235#else
236 yCWarning(BATTERYWRAPPER, "%s", msg.c_str());
237 std::string cmd = "echo " + msg + " | wall";
238 int retval;
239 retval = system(cmd.c_str());
240 yCDebug(BATTERYWRAPPER) << "system executed command" << cmd.c_str() << " with return value:" << retval;
241#endif
242}
243
244void Battery_nws_yarp::emergency_shutdown(std::string msg)
245{
246#ifdef WIN32
247 std::string cmd;
248 cmd = "shutdown /s /t 120 /c " + msg;
249 yCWarning(BATTERYWRAPPER, "%s", msg.c_str());
250 system(cmd.c_str());
251#else
252 std::string cmd;
253 int retval;
254 yCWarning(BATTERYWRAPPER, "%s", msg.c_str());
255 cmd = "echo " + msg + " | wall";
256 retval = system(cmd.c_str());
257 yCDebug(BATTERYWRAPPER) << "system executed command" << cmd.c_str() << " with return value:" << retval;
258
259 cmd = "sudo shutdown -h 2 " + msg;
260 retval = system(cmd.c_str());
261 yCDebug(BATTERYWRAPPER) << "system executed command" << cmd.c_str() << " with return value:" << retval;
262
263#ifdef ICUB_SSH_SHUTDOWN
264 cmd = "ssh icub@pc104 sudo shutdown -h 2";
265 retval = system(cmd.c_str());
266 yCDebug(BATTERYWRAPPER) << "system executed command" << cmd.c_str() << " with return value:" << retval;
267#endif
268#endif
269}
270
271void Battery_nws_yarp::check_battery_status(double battery_charge)
272{
273 static bool notify_15 = true;
274 static bool notify_12 = true;
275 static bool notify_10 = true;
276 static bool notify_0 = true;
277
278 if (battery_charge > 20)
279 {
280 notify_15 = true;
281 notify_12 = true;
282 notify_10 = true;
283 notify_0 = true;
284 }
285
286 if (battery_charge < 5)
287 {
288 if (notify_0)
289 {
291 {
292 emergency_shutdown("CRITICAL WARNING: battery charge below critical level 5%. The robot will be stopped and the system will shutdown in 2mins.");
293 if (m_quitPortName != "") { stop_robot(m_quitPortName); }
294 notify_0 = false;
295 }
296 else
297 {
298 notify_message("CRITICAL WARNING: battery charge reached critical level 5%, but the emergency shutodown is currently disabled!");
299 notify_0 = false;
300 }
301 }
302 }
303 else if (battery_charge < 10)
304 {
305 if (notify_10) { notify_message("WARNING: battery charge below 10%"); notify_10 = false; }
306 }
307 else if (battery_charge < 12)
308 {
309 if (notify_12) { notify_message("WARNING: battery charge below 12%"); notify_12 = false; }
310 }
311 else if (battery_charge < 15)
312 {
313 if (notify_15) { notify_message("WARNING: battery charge below 15%"); notify_15 = false; }
314 }
315}
316
317void Battery_nws_yarp::stop_robot(std::string quit_port)
318{
319 //typical quit_port:
320 // "/icub/quit"
321 // "/ikart/quit"
322
324 port_shutdown.open((m_streamingPortName + "/shutdown:o").c_str());
325 yarp::os::Network::connect((m_streamingPortName + "/shutdown:o").c_str(), quit_port.c_str());
326 Bottle bot;
327 bot.addString("quit");
328 port_shutdown.write(bot);
331}
332
334{
335 std::lock_guard <std::mutex> lg(m_mutex);
336 return_get_BatteryInfo response;
337 std::string info;
338
339 auto ret = m_iBat->getBatteryInfo(info);
340 if(!ret)
341 {
342 yCError(BATTERYWRAPPER) << "Could not retrieve the battery status";
343 response.result = ret;
344 return response;
345 }
346
347 response.result = ret;
348 response.info = info;
349
350 return response;
351}
352
#define DEFAULT_THREAD_PERIOD
#define DEFAULT_THREAD_PERIOD
bool ret
bool parseParams(const yarp::os::Searchable &config) override
Parse the DeviceDriver parameters.
bool open(yarp::os::Searchable &params) override
Open the DeviceDriver.
void threadRelease() override
Release method.
bool threadInit() override
Initialization method.
void run() override
Loop function.
bool close() override
Close the DeviceDriver.
IBatteryMsgsImpl(yarp::dev::IBattery *iBattery)
return_get_BatteryInfo getBatteryInfoRPC() override
yarp::dev::ReturnValue result
double charge
Battery charge percentage [%].
Definition BatteryData.h:29
double voltage
Battery Voltage [V].
Definition BatteryData.h:33
double current
Battery Current [A].
Definition BatteryData.h:37
std::int32_t status
the status of the device.
Definition BatteryData.h:45
double temperature
Battery Temperature [degC].
Definition BatteryData.h:41
bool view(T *&x)
Get an interface to the device driver.
A generic battery interface.
Definition IBattery.h:26
virtual yarp::dev::ReturnValue getBatteryTemperature(double &temperature)=0
get the battery temperature
virtual yarp::dev::ReturnValue getBatteryInfo(std::string &battery_info)=0
get the battery hardware characteristics (e.g.
virtual yarp::dev::ReturnValue getBatteryCharge(double &charge)=0
get the battery status of charge
virtual yarp::dev::ReturnValue getBatteryStatus(Battery_status &status)=0
get the battery status
virtual yarp::dev::ReturnValue getBatteryCurrent(double &current)=0
Get the instantaneous current measurement.
virtual yarp::dev::ReturnValue getBatteryVoltage(double &voltage)=0
Get the instantaneous voltage measurement.
A container for a device driver.
Definition PolyDriver.h:23
bool detachAll() final
Detach the object (you must have first called attach).
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition Bottle.cpp:170
A mini-server for performing network communication in the background.
void close() override
Stop port activity.
bool setEnvelope(PortWriter &envelope) override
Set an envelope (e.g., a timestamp) to the next message which will be sent.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
void interrupt() override
Interrupt any current reads or writes attached to the port.
void write(bool forceStrict=false)
Write the current object being returned by BufferedPort::prepare.
T & prepare()
Access the object which will be transmitted by the next call to yarp::os::BufferedPort::write.
An interface for reading from a network connection.
virtual bool isValid() const =0
static bool connect(const std::string &src, const std::string &dest, const std::string &carrier="", bool quiet=true)
Request that an output port connect to an input port.
Definition Network.cpp:682
An abstraction for a periodic thread.
bool setPeriod(double period)
Set the (new) period of the thread.
bool isRunning() const
Returns true when the thread is started, false otherwise.
bool start()
Call this to start the thread.
void stop()
Call this to stop the thread, this call blocks until the thread is terminated (and releaseThread() ca...
A mini-server for network communication.
Definition Port.h:46
void setReader(PortReader &reader) override
Set an external reader for port data.
Definition Port.cpp:511
void close() override
Stop port activity.
Definition Port.cpp:363
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
Definition Port.cpp:79
A base class for nested structures that can be searched.
Definition Searchable.h:31
void update()
Set the timestamp to the current time, and increment the sequence number (wrapping to 0 if the sequen...
Definition Stamp.cpp:124
#define yCInfo(component,...)
#define yCError(component,...)
#define yCTrace(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
For streams capable of holding different kinds of content, check what they actually have.
An interface to the operating system, including Port based communication.