iCub-main
TouchSensor.h
Go to the documentation of this file.
1 // -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2 
3 /*
4  * Copyright (C) 2009 RobotCub Consortium
5  * Author: Alessandro Scalzo alessandro.scalzo@iit.it
6  * CopyPolicy: Released under the terms of the GNU GPL v2.0.
7  *
8  */
9 
10 #include <gsl/gsl_math.h>
11 #include <memory.h>
12 
13 #include <stdio.h>
14 
15 #ifndef __ALE_TOUCHSENSOR_H__
16 #define __ALE_TOUCHSENSOR_H__
17 
18 #define MAX_TAXELS 192
19 
21 {
22 protected:
23 
25 
27  {
28  for (int n = 0; n < MAX_TAXELS; ++n)
29  {
30  connected[n] = true;
31  }
32  }
33 
34 public:
35 
36  void setColor(unsigned char r, unsigned char g, unsigned char b)
37  {
38  R_MAX = r;
39  G_MAX = g;
40  B_MAX = b;
41  }
42 
43  void setCalibrationFlag (bool use_calibrated_skin)
44  {
45  calibrated_skin=use_calibrated_skin;
46  }
47 
48  void resize(int width,int height,int margin)
49  {
50  if (3*margin>=width || 3*margin>=height) margin=0;
51 
52  double scaleX=double(width -2*margin)/(dXmax-dXmin);
53  double scaleY=double(height-2*margin)/(dYmax-dYmin);
54  double scale=scaleX<scaleY?scaleX:scaleY;
55 
56  m_Radius=m_RadiusOrig*scale;
57 
59 
60  double dXmid=0.5*(dXmin+dXmax);
61  double dYmid=0.5*(dYmin+dYmax);
62 
63  int w2=width /2;
64  int h2=height/2;
65 
66  for (int i=0; i<nTaxels; ++i)
67  {
68  x[i]=w2+int(scale*(dX[i]-dXmid));
69  y[i]=h2+int(scale*(dY[i]-dYmid));
70  }
71 
72  for (int i=0; i<nVerts; ++i)
73  {
74  xv[i]=w2+int(scale*(dXv[i]-dXmid));
75  yv[i]=h2+int(scale*(dYv[i]-dYmid));
76  }
77 
78  double sigma=0.5*5.55*scale;
79  int maxRange=int(2.5*sigma);
80 
81  if (maxRange!=m_maxRange)
82  {
83  m_maxRange=maxRange;
84 
85  delete [] Exponential;
86  Exponential=new double[maxRange];
87 
88  double k=-0.5/(sigma*sigma);
89  for (int x=0; x<maxRange; ++x)
90  {
91  Exponential[x]=exp(k*double(x*x));
92  }
93  }
94 
95  xMin=w2+int(scale*(dXc-dXmid-15.0))-maxRange;
96  xMax=w2+int(scale*(dXc-dXmid+15.0))+maxRange;
97  yMin=h2+int(scale*(dYc-dYmid-15.0))-maxRange;
98  yMax=h2+int(scale*(dYc-dYmid+15.0))+maxRange;
99 
100  if (xMin<0) xMin=0;
101  if (xMax>width) xMax=width;
102  if (yMin<0) yMin=0;
103  if (yMax>height) yMax=height;
104 
105  m_Width=width;
106  m_Height=height;
107  }
108 
109  virtual ~TouchSensor()
110  {
111  if (Exponential)
112  {
113  delete [] Exponential;
114  Exponential=0;
115  }
116  }
117 
118  int Abs(int x)
119  {
120  return x>=0?x:-x;
121  }
122 
123  int get_nTaxels ()
124  {
125  return nTaxels;
126  }
127 
128  void eval_light(unsigned char *image)
129  {
130  int act;
131  int dx,dy;
132  int Y0,Y1;
133  int dya,dyb,dxa,dxb;
134 
135  switch (ilayoutNum)
136  {
137  case 0:
138  for (int i=0; i<nTaxels; ++i) remapped_activation[i]=activation[i];
139  break;
140  case 1:
141  for (int i=0; i<nTaxels; ++i) remapped_activation[nTaxels-1-i]=activation[i];
142  break;
143  default:
144  for (int i=0; i<nTaxels; ++i) remapped_activation[i]=activation[i];
145  printf("WARN: unkwnown layout number.\n");
146  break;
147  }
148 
149  int maxRange2=m_maxRangeLight*m_maxRangeLight;
150 
151  for (int i=0; i<nTaxels; ++i) if (connected[i] && remapped_activation[i]>0.0)
152  {
153  act=int(dGain*remapped_activation[i]);
154  Y0=(m_Height-y[i]-1)*m_Width+x[i];
155 
156  dya=(y[i]>=m_maxRangeLight)?-m_maxRangeLight:-y[i];
158 
159  dxa=(x[i]>=m_maxRangeLight)?-m_maxRangeLight:-x[i];
161 
162  for (dy=dya; dy<=dyb; ++dy)
163  {
164  Y1=Y0-dy*m_Width;
165 
166  for (dx=dxa; dx<=dxb; ++dx)
167  {
168  if (dx*dx+dy*dy<=maxRange2)
169  {
170  image[(dx+Y1)*3]=act<255?act:255;
171  }
172  }
173  }
174  }
175  }
176 
177  void eval(unsigned char *image)
178  {
179  int act;
180  int dx,dy;
181  int Y0,Y1;
182  int index;
183  double k0,k1;
184  int dya,dyb,dxa,dxb;
185 
186  switch (ilayoutNum)
187  {
188  case 0:
189  for (int i=0; i<nTaxels; ++i) remapped_activation[i]=activation[i];
190  break;
191  case 1:
192  for (int i=0; i<nTaxels; ++i) remapped_activation[nTaxels-1-i]=activation[i];
193  break;
194  default:
195  for (int i=0; i<nTaxels; ++i) remapped_activation[i]=activation[i];
196  printf("WARN: unkwnown layout number.\n");
197  break;
198  }
199 
200  for (int i=0; i<nTaxels; ++i) if (connected[i] && remapped_activation[i]>0.0)
201  {
203  Y0=(m_Height-y[i]-1)*m_Width+x[i];
204 
205  dya=(y[i]>=m_maxRange)?-m_maxRange:-y[i];
206  dyb=(y[i]+m_maxRange<m_Height)?m_maxRange:m_Height-y[i]-1;
207 
208  dxa=(x[i]>=m_maxRange)?-m_maxRange:-x[i];
209  dxb=(x[i]+m_maxRange<m_Width)?m_maxRange:m_Width-x[i]-1;
210 
211  for (dy=dya; dy<=dyb; ++dy)
212  {
213  k1=k0*Exponential[Abs(dy)];
214  Y1=Y0-dy*m_Width;
215 
216  for (dx=dxa; dx<=dxb; ++dx)
217  {
218  index=(dx+Y1)*3;
219 
220  if (image[index]<R_MAX || image[index+1]<G_MAX || image[index+2]<B_MAX)
221  {
222  act=int(k1*Exponential[Abs(dx)]);
223 
224  int actR=image[index ]+(act*R_MAX)/255;
225  int actG=image[index+1]+(act*G_MAX)/255;
226  int actB=image[index+2]+(act*B_MAX)/255;
227 
228  image[index ]=actR<R_MAX?actR:R_MAX;
229  image[index+1]=actG<G_MAX?actG:G_MAX;
230  image[index+2]=actB<B_MAX?actB:B_MAX;
231  }
232  }
233  }
234  }
235  }
236 
237  void setActivationFirst7(unsigned char* data)
238  {
239  for (int i=0; i<7; ++i)
240  {
241  activation[i]=data[i+1]<=244?double(244-data[i+1]):0.0;
242  }
243  }
244  void setActivationLast5(unsigned char* data)
245  {
246  for (int i=1; i<=5; ++i)
247  {
248  activation[i+6]=data[i]<=244?double(244-data[i]):0.0;
249  }
250  }
251 
252  void setActivationFromPortData(double val, int id)
253  {
254  if (calibrated_skin)
255  {
256  if (val>244.0)
257  {
258  activation[id]=244.0;
259  }
260  else if (val<0.0)
261  {
262  activation[id]=0.0;
263  }
264  else
265  {
266  activation[id]=val;
267  }
268  }
269  else
270  {
271  activation[id]=val<=244?double(244-val):0.0;
272  }
273  }
274 
275  virtual void draw(unsigned char *image)
276  {
277  for (int i=0; i<nVerts; ++i)
278  {
279  drawLine(image,xv[i],yv[i],xv[(i+1)%nVerts],yv[(i+1)%nVerts]);
280  }
281 
282  for (int i=0; i<nTaxels; ++i)
283  {
284  drawCircle(image,x[i],y[i],m_Radius);
285  }
286  }
287 
288 protected:
289  void dither(int x,int y,unsigned char *image)
290  {
291  static const unsigned char R1=0x80,G1=0x50,B1=0x00;
292  static const unsigned char R2=3*R1/4,G2=3*G1/4,B2=3*B1/4;
293  static const unsigned char R4=3*R2/4,G4=3*G2/4,B4=3*B2/4;
294 
295  //y=m_Width-y-1;
296  //int bytePos=(x+(y-1)*m_Width)*3;
297  int bytePos=(x+(m_Height-y-2)*m_Width)*3;
298 
299  if (image[bytePos-3]<R4) image[bytePos-3]=R4;
300  if (image[bytePos-2]<G4) image[bytePos-2]=G4;
301  //if (image[bytePos-1]<B4) image[bytePos-1]=B4;
302 
303  if (image[bytePos ]<R2) image[bytePos ]=R2;
304  if (image[bytePos+1]<G2) image[bytePos+1]=G2;
305  //if (image[bytePos+2]<B2) image[bytePos+2]=B2;
306 
307  if (image[bytePos+3]<R4) image[bytePos+3]=R4;
308  if (image[bytePos+4]<G4) image[bytePos+4]=G4;
309  //if (image[bytePos+5]<B4) image[bytePos+5]=B4;
310 
311  bytePos+=m_Width*3;
312 
313  if (image[bytePos-3]<R2) image[bytePos-3]=R2;
314  if (image[bytePos-2]<G2) image[bytePos-2]=G2;
315  //if (image[bytePos-1]<B2) image[bytePos-1]=B2;
316 
317  if (image[bytePos ]<R1) image[bytePos ]=R1;
318  if (image[bytePos+1]<G1) image[bytePos+1]=G1;
319  //if (image[bytePos+2]<B1) image[bytePos+2]=B1;
320 
321  if (image[bytePos+3]<R2) image[bytePos+3]=R2;
322  if (image[bytePos+4]<G2) image[bytePos+4]=G2;
323  //if (image[bytePos+5]<B2) image[bytePos+5]=B2;
324 
325  bytePos+=m_Width*3;
326 
327  if (image[bytePos-3]<R4) image[bytePos-3]=R4;
328  if (image[bytePos-2]<G4) image[bytePos-2]=G4;
329  //if (image[bytePos-1]<B4) image[bytePos-1]=B4;
330 
331  if (image[bytePos ]<R2) image[bytePos ]=R2;
332  if (image[bytePos+1]<G2) image[bytePos+1]=G2;
333  //if (image[bytePos+2]<B2) image[bytePos+2]=B2;
334 
335  if (image[bytePos+3]<R4) image[bytePos+3]=R4;
336  if (image[bytePos+4]<G4) image[bytePos+4]=G4;
337  //if (image[bytePos+5]<B4) image[bytePos+5]=B4;
338  }
339 
340  void drawLine(unsigned char *image,int x0,int y0,int x1,int y1)
341  {
342  if (x1==x0 && y1==y0) return;
343  double Vx=double(x1-x0);
344  double Vy=double(y1-y0);
345  double dt=1.0/sqrt(Vx*Vx+Vy*Vy);
346 
347  for (double t=0.0; t<=1.0; t+=dt)
348  {
349  dither(x0+int(t*Vx),y0+int(t*Vy),image);
350  }
351  }
352 
353  void drawCircle(unsigned char *image,int cx,int cy,double radius)
354  {
355  double dt=1.0/(2*M_PI*radius);
356 
357  int dx,dy;
358 
359  double cs,sn;
360 
361  for (double t=0.0; t<=M_PI_4; t+=dt)
362  {
363  cs=cos(t);
364  sn=sin(t);
365 
366  dx=int(radius*cs);
367  dy=int(radius*sn);
368 
369  dither(cx+dx,cy+dy,image);
370  dither(cx+dx,cy-dy,image);
371  dither(cx-dx,cy-dy,image);
372  dither(cx-dx,cy+dy,image);
373 
374  dither(cx+dy,cy+dx,image);
375  dither(cx+dy,cy-dx,image);
376  dither(cx-dy,cy-dx,image);
377  dither(cx-dy,cy+dx,image);
378  }
379  }
380 
381  // original
383  static double dXmin,dXmax,dYmin,dYmax;
384  double dXv[8],dYv[8];
385  double dXc,dYc;
386  double dGain;
389 
394 
395  unsigned char R_MAX, G_MAX, B_MAX;
396 
398  static int m_maxRange;
399  static double *Exponential;
400 
401  // scaled
403  int xv[8],yv[8];
404 
405  int nVerts;
406  int nTaxels;
407 
409 
411 
412  public:
413  int min_tax;
414  int max_tax;
415 };
416 
417 #endif
@ data
#define MAX_TAXELS
Definition: TouchSensor.h:18
#define M_PI
Definition: XSensMTx.cpp:24
double dX[MAX_TAXELS]
Definition: TouchSensor.h:382
double dYc
Definition: TouchSensor.h:385
int Abs(int x)
Definition: TouchSensor.h:118
bool connected[MAX_TAXELS]
Definition: TouchSensor.h:393
unsigned char R_MAX
Definition: TouchSensor.h:395
bool calibrated_skin
Definition: TouchSensor.h:24
double m_Radius
Definition: TouchSensor.h:390
int x[MAX_TAXELS]
Definition: TouchSensor.h:402
virtual ~TouchSensor()
Definition: TouchSensor.h:109
double activation[MAX_TAXELS]
Definition: TouchSensor.h:391
double m_RadiusOrig
Definition: TouchSensor.h:390
static double dXmin
Definition: TouchSensor.h:383
double remapped_activation[MAX_TAXELS]
Definition: TouchSensor.h:392
void setActivationFromPortData(double val, int id)
Definition: TouchSensor.h:252
void eval(unsigned char *image)
Definition: TouchSensor.h:177
void resize(int width, int height, int margin)
Definition: TouchSensor.h:48
double dXc
Definition: TouchSensor.h:385
void setCalibrationFlag(bool use_calibrated_skin)
Definition: TouchSensor.h:43
static double * Exponential
Definition: TouchSensor.h:399
static double dYmax
Definition: TouchSensor.h:383
double dXv[8]
Definition: TouchSensor.h:384
int get_nTaxels()
Definition: TouchSensor.h:123
void setActivationFirst7(unsigned char *data)
Definition: TouchSensor.h:237
double dY[MAX_TAXELS]
Definition: TouchSensor.h:382
void drawLine(unsigned char *image, int x0, int y0, int x1, int y1)
Definition: TouchSensor.h:340
void setActivationLast5(unsigned char *data)
Definition: TouchSensor.h:244
virtual void draw(unsigned char *image)
Definition: TouchSensor.h:275
static double dXmax
Definition: TouchSensor.h:383
void dither(int x, int y, unsigned char *image)
Definition: TouchSensor.h:289
double dYv[8]
Definition: TouchSensor.h:384
double dGain
Definition: TouchSensor.h:386
int m_maxRangeLight
Definition: TouchSensor.h:397
int y[MAX_TAXELS]
Definition: TouchSensor.h:402
void drawCircle(unsigned char *image, int cx, int cy, double radius)
Definition: TouchSensor.h:353
static int m_maxRange
Definition: TouchSensor.h:398
unsigned char G_MAX
Definition: TouchSensor.h:395
static double dYmin
Definition: TouchSensor.h:383
unsigned char B_MAX
Definition: TouchSensor.h:395
void setColor(unsigned char r, unsigned char g, unsigned char b)
Definition: TouchSensor.h:36
void eval_light(unsigned char *image)
Definition: TouchSensor.h:128
exp(-x3 *T)]
int n