iCub-main
SkinDiagnosticsReadThread.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Francesco Giovannini, iCub Facility - Istituto Italiano di Tecnologia
3  * Authors: Francesco Giovannini
4  * email: francesco.giovannini@iit.it
5  * website: www.robotcub.org
6  * Permission is granted to copy, distribute, and/or modify this program
7  * under the terms of the GNU General Public License, version 2 or any
8  * later version published by the Free Software Foundation.
9  *
10  * A copy of the license can be found at
11  * http://www.robotcub.org/icub/license/gpl.txt
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details
17  */
18 
20 #include <SkinDiagnostics.h>
21 
22 #include <iostream>
23 #include <ios>
24 #include <sstream>
25 
26 #include <yarp/os/Time.h>
27 
29 
30 using std::cerr;
31 using std::cout;
32 
33 using yarp::os::PeriodicThread;
34 
35 #define SKINMANAGER_TH_DIAGREAD_DEBUG 1
36 
37 
38 /* *********************************************************************************************************************** */
39 /* ******* Constructor ********************************************** */
40 SkinDiagnosticsReadThread::SkinDiagnosticsReadThread(const int aPeriod, const yarp::os::ResourceFinder &aRf)
41  : PeriodicThread((double)aPeriod/1000.0) {
42  period = aPeriod;
43  rf = aRf;
44 
45  dbgTag = "SkinDiagnosticsReadThread: ";
46 }
47 /* *********************************************************************************************************************** */
48 
49 
50 /* *********************************************************************************************************************** */
51 /* ******* Destructor ********************************************** */
53 /* *********************************************************************************************************************** */
54 
55 
56 /* *********************************************************************************************************************** */
57 /* ******* Initialise thread ********************************************** */
59  using std::string;
60  using yarp::os::Value;
61 
62  cout << dbgTag << "Initialising. \n";
63 
64  // Get module name
65  string moduleName = rf.check("name", Value("skiManager"), "module name (string)").asString();
66  string portNameRoot = "/" + moduleName;
67 
68  // Open ports
69  portSkinDiagnosticsErrorsIn.open((portNameRoot + "/diagnostics/skin/errors:i").c_str());
70  portSkinManagerErrorsOut.open((portNameRoot + "/diagnostics/skin/errors:o").c_str());
71 
72  cout << dbgTag << "Initialised correctly. \n";
73 
74  return true;
75 }
76 /* *********************************************************************************************************************** */
77 
78 
79 
80 /* *********************************************************************************************************************** */
81 /* ******* Run thread ********************************************** */
83  using iCub::skin::diagnostics::SkinErrorCode; // FG: Skin diagnostics error codes
84  using std::deque;
85  using std::stringstream;
86  using std::ios;
87  using yarp::sig::Vector;
88  using yarp::os::Bottle;
89 
90 
91  // Read sensor data from port
92  Vector *data = portSkinDiagnosticsErrorsIn.read(false);
93  if ((data) && (data->size() == 4)) {
94 #if SKINMANAGER_TH_DIAGREAD_DEBUG
95  // Print out FT sensor data
96  cout << dbgTag << "Skin diagnostics data: ";
97  for (size_t i = 0; i < data->size(); ++i) {
98  cout << (*data)[i] << " ";
99  }
100  cout << "\n";
101 #endif
102 
103  // Prepare output string
104  Bottle &out = portSkinManagerErrorsOut.prepare();
105  out.clear();
106 
107  // Extract skin errors
108  deque<bool> errorTaxels; // FG: Set to true if the taxel returned an error
109  int errorCode = (int) (*data)[3];
110  if (!(errorCode & SkinErrorCode::StatusOK)) {
111  // An error occurred
112  // Handle stuck taxel data
113  if (errorCode & 0xFFF0) {
114  errorTaxels.resize(12, false);
115  int errorMask = SkinErrorCode::TaxelStuck00;
116  for (int tax = 0; tax < 12; ++tax) {
117  errorTaxels[tax] = ((errorCode & errorMask) != 0); // FG: Explicit (and safe) bool to int conversion
118  errorMask = errorMask << 1; // Increment error mask
119  }
120  }
121 
122  if (errorTaxels.size() > 0) {
123  // Errors occurred
124  stringstream ss;
125  ss << "ERROR: Net ID (" << (*data)[0] << "): Board ID (" << (*data)[1]
126  << "): Sensor ID (" << (*data)[2] << "): The following taxels are stuck/faulty: \t";
127  for (size_t i = 0; i < errorTaxels.size(); ++i) {
128  if (errorTaxels[i]) {
129  ss << i << " ";
130  }
131  }
132 
133  out.addString(ss.str().c_str());
134  }
135 
136  // Handle other data
137  stringstream ss;
138  if (errorCode & SkinErrorCode::ErrorReading12C) {
139  ss << "ERROR: Net ID (" << (*data)[0] << "): Board ID (" << (*data)[1]
140  << "): Sensor ID (" << (*data)[2] << "): Cannot read from this sensor.";
141  } else if (errorCode & SkinErrorCode::ErrorACK4C) {
142  ss << "ERROR: Net ID (" << (*data)[0] << "): Board ID (" << (*data)[1]
143  << "): Sensor ID (" << (*data)[2] << "): This sensor does not respond to the initialisation message (0x4C).";
144  }
145  // Check stringstream size
146  ss.seekg(0, ios::end);
147  if(ss.tellg() > 0) {
148  ss.seekg(0, ios::beg);
149  out.addString(ss.str().c_str());
150  }
151  } else {
152  #ifndef NODEBUG
153  stringstream ss;
154  ss << "DEBUG: Skin is working fine.";
155  out.addString(ss.str().c_str());
156  #endif
157  }
158 
159  // Write out errors
160  if (out.size() > 0) {
161  portSkinManagerErrorsOut.write();
162  }
163  }
164 }
165 /* *********************************************************************************************************************** */
166 
167 
168 
169 /* *********************************************************************************************************************** */
170 /* ******* Release thread ********************************************** */
172  cout << dbgTag << "Releasing. \n";
173 
174  // Interrupt ports
175  portSkinDiagnosticsErrorsIn.interrupt();
176  portSkinManagerErrorsOut.interrupt();
177 
178  // Close ports
179  portSkinDiagnosticsErrorsIn.close();
180  portSkinManagerErrorsOut.close();
181 
182  cout << dbgTag << "Released. \n";
183 }
184 /* *********************************************************************************************************************** */
@ data
out
Definition: sine.m:8
Enum to provide intelligible error codes for the skin.