root/juggler/branches/2.2/modules/gadgeteer/gadget/Type/Glove.cpp

Revision 19729, 10.4 kB (checked in by patrick, 2 years ago)

Copyright update.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
2  *
3  * VR Juggler is (C) Copyright 1998-2007 by Iowa State University
4  *
5  * Original Authors:
6  *   Allen Bierbaum, Christopher Just,
7  *   Patrick Hartling, Kevin Meinert,
8  *   Carolina Cruz-Neira, Albert Baker
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *
25  *************** <auto-copyright.pl END do not edit this line> ***************/
26
27 #include <gadget/gadgetConfig.h>
28
29 #include <vpr/IO/ObjectReader.h>
30 #include <vpr/IO/ObjectWriter.h>
31
32 #include <boost/concept_check.hpp>
33 #include <gmtl/Matrix.h>
34 #include <gmtl/Vec.h>
35 #include <gmtl/VecOps.h>
36 #include <gmtl/MatrixOps.h>
37 #include <gmtl/Generate.h>
38 #include <gmtl/Xforms.h>
39 #include <gmtl/EulerAngle.h>
40
41 #include <jccl/Config/ConfigElement.h>
42 #include <gadget/Type/Glove.h>
43 #include <gadget/Util/DeviceSerializationTokens.h>
44
45 namespace gadget
46 {
47
48 Glove::Glove()
49 {
50    //Initialize the transforms for the default GloveData
51    mDefaultValue.calcXforms();
52
53    //By default there are 2 gloves
54    mGlovePositions.resize(2);
55 }
56
57 bool Glove::config(jccl::ConfigElementPtr e)
58 {
59    // For now, assume just 2 gloves (left & right)
60    std::vector<std::string> positionProxyNames(2);
61    positionProxyNames[0]=e->getProperty<std::string>("left_glove_position");
62    positionProxyNames[1]=e->getProperty<std::string>("right_glove_position");
63
64    mGlovePositions.resize(positionProxyNames.size());
65    unsigned int i;
66    for(i=0;i<positionProxyNames.size();i++)
67    {
68       if(positionProxyNames[i]!="")
69       {
70          mGlovePositions[i].init(positionProxyNames[i]);
71       }
72    }
73
74    return true;
75 }
76
77 void Glove::writeObject(vpr::ObjectWriter* writer)
78 {
79    SampleBuffer_t::buffer_t& stable_buffer = mGloveSamples.stableBuffer();
80
81    writer->beginTag(Glove::getInputTypeName());
82    writer->beginAttribute(gadget::tokens::DataTypeAttrib);
83       writer->writeUint16(MSG_DATA_GLOVE);                               // Write out the data type so that we can assert if reading in wrong place
84    writer->endAttribute();
85
86    writer->beginAttribute(gadget::tokens::SampleBufferLenAttrib);
87       writer->writeUint16(stable_buffer.size());         // Write the size of the stable buffer
88    writer->endAttribute();
89
90    if ( !stable_buffer.empty() )
91    {
92       mGloveSamples.lock();
93       for ( unsigned j=0;j<stable_buffer.size();j++ )
94       {
95          writer->beginTag(gadget::tokens::BufferSampleTag);
96          writer->beginAttribute(gadget::tokens::BufferSampleLenAttrib);
97             writer->writeUint16(stable_buffer[j].size());            // Number of glove values for this entry
98          writer->endAttribute();
99
100          for ( unsigned i=0;i<stable_buffer[j].size();i++ )       // For each glove value
101          {
102             writer->beginTag(gadget::tokens::GloveValue);
103
104             // TODO: If we switch the GloveData to only work with Matrix4x4s, then change this.
105             for(unsigned component=0;component<GloveData::NUM_COMPONENTS;component++)
106             {
107                for(unsigned joint=0;joint<GloveData::NUM_JOINTS;joint++)
108                {
109                   float value=stable_buffer[j][i].mAngles[GloveData::NUM_COMPONENTS][GloveData::NUM_JOINTS];
110                   writer->writeFloat(value);
111                }
112             }
113
114             writer->beginAttribute(gadget::tokens::TimeStamp);
115                writer->writeUint64(stable_buffer[j][i].getTime().usec());           // Write Time Stamp vpr::Uint64
116             writer->endAttribute();
117             writer->endTag();
118          }
119          writer->endTag();
120       }
121       mGloveSamples.unlock();
122    }
123    else       // No data or request out of range, return default value
124    {
125       vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL) << "Warning: Glove::writeObject: Stable buffer is empty. If this is not the first write, then this is a problem.\n" << vprDEBUG_FLUSH;
126    }
127    writer->endTag();
128 }
129
130 void Glove::readObject(vpr::ObjectReader* reader)
131 {
132    vprASSERT(reader->attribExists("rim.timestamp.delta"));
133    vpr::Uint64 delta = reader->getAttrib<vpr::Uint64>("rim.timestamp.delta");
134
135    reader->beginTag(Glove::getInputTypeName());
136    reader->beginAttribute(gadget::tokens::DataTypeAttrib);
137       vpr::Uint16 temp = reader->readUint16();
138    reader->endAttribute();
139
140    // XXX: Should there be error checking for the case when vprASSERT() is
141    // compiled out?  -PH 8/21/2003
142    vprASSERT(temp==MSG_DATA_GLOVE && "[Remote Input Manager]Not Glove Data");
143    boost::ignore_unused_variable_warning(temp);
144
145    std::vector<GloveData> dataSample;
146
147    unsigned int numGloveDatas;
148    vpr::Uint64 timeStamp;
149    GloveData gloveData;
150
151    reader->beginAttribute(gadget::tokens::SampleBufferLenAttrib);
152       unsigned int numVectors = reader->readUint16();
153    reader->endAttribute();
154
155    mGloveSamples.lock();
156    for ( unsigned int i=0;i<numVectors;i++ )
157    {
158       reader->beginTag(gadget::tokens::BufferSampleTag);
159       reader->beginAttribute(gadget::tokens::BufferSampleLenAttrib);
160          numGloveDatas = reader->readUint16();
161       reader->endAttribute();
162
163       dataSample.clear();
164
165       for ( unsigned int j=0;j<numGloveDatas;j++ )
166       {
167          reader->beginTag(gadget::tokens::GloveValue);
168          for(unsigned int component=0;component<GloveData::NUM_COMPONENTS;component++)
169          {
170             for(unsigned int joint=0;joint<GloveData::NUM_JOINTS;joint++)
171             {
172                gloveData.mAngles[component][joint]=reader->readFloat();
173             }
174          }
175
176          reader->beginAttribute(gadget::tokens::TimeStamp);
177             timeStamp = reader->readUint64();
178          reader->endAttribute();
179          reader->endTag();
180
181          gloveData.setTime(vpr::Interval(timeStamp + delta,vpr::Interval::Usec));
182          gloveData.calcXforms();
183          dataSample.push_back(gloveData);
184       }
185
186       mGloveSamples.addSample(dataSample);
187       reader->endTag();
188    }
189
190    mGloveSamples.unlock();
191    swapGloveBuffers();
192    reader->endTag();
193 }
194
195 /**
196  * Returns a vector ponting "out" of the component.
197  * Can be used for selection, etc.
198  * Use getJointTransform to get the transformation matrix.
199  */
200 gmtl::Vec3f Glove::getTipVector(GloveData::GloveComponent component, int devNum)
201 {
202    gmtl::Vec3f y_axis(0.0f, 1.0f, 0.0f);
203    gmtl::Vec3f ret_val(0.0f, 0.0f, 0.0f);
204
205    ret_val = getTipTransform(component, devNum) * y_axis;   // Compute the vector direction
206    return ret_val;
207 }
208
209 /**
210  * Returns the transform matrix of the specified finger tip in world space
211  * wTt = wTb bTj jTt
212  */
213 gmtl::Matrix44f Glove::getTipTransform(GloveData::GloveComponent component,int devNum)
214 {
215    gmtl::Matrix44f worldTdij;
216
217    worldTdij=getJointTransform(component,GloveData::DIJ,devNum);
218
219    // TODO: Fix this up
220    gmtl::Matrix44f dijTtip;
221    gmtl::setTrans(dijTtip,gmtl::Vec3f(0,0.5f / PositionUnitConversion::ConvertToInches,0));
222    gmtl::postMult(worldTdij,dijTtip);
223
224    return worldTdij;
225 }
226
227 /**
228  * Returns the transform matrix of the specified joint in world space
229  * wTj = wTb bTj
230  */
231 gmtl::Matrix44f Glove::getJointTransform(GloveData::GloveComponent component, GloveData::GloveJoint joint,int devNum)
232 {
233    gmtl::Matrix44f result;           // The returned matrix.
234    gmtl::Matrix44f baseTdij;         // Transform from base to dig coord system
235
236    const GloveData data=getGloveData(devNum);
237
238    if(component==GloveData::WRIST)
239    {
240       gmtl::identity(baseTdij);      // No transform
241    }
242    else
243    {
244       baseTdij = data.getLocalTransformMatrix(component,GloveData::MPJ);
245
246       if(joint>=GloveData::PIJ)
247       {
248          gmtl::postMult(baseTdij,data.getLocalTransformMatrix(component,GloveData::PIJ));       // mpjTpij
249
250          if(joint>=GloveData::DIJ)
251          {
252             gmtl::postMult(baseTdij,data.getLocalTransformMatrix(component,GloveData::DIJ));    // pijTdij
253          }
254       }
255    }
256
257    // Compute return value: result = TIPw = wTb bTd dTt
258    if(devNum<(int)mGlovePositions.size()){
259       result=mGlovePositions[devNum]->getData();      // wTb
260    }
261    gmtl::postMult(result,baseTdij);                     // bTd
262
263    return result;
264 }
265
266 GloveData Glove::getGloveData(int devNum = 0)
267 {
268    SampleBuffer_t::buffer_t& stable_buffer = mGloveSamples.stableBuffer();
269
270    if ( (!stable_buffer.empty()) && (stable_buffer.back().size() > (unsigned)devNum) )  // If have entry && devNum in range
271    {
272       return stable_buffer.back()[devNum];
273    }
274    else        // No data or request out of range, return default value
275    {
276       if ( stable_buffer.empty() )
277       {
278          vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL) << "Warning: Digital::getGloveData: Stable buffer is empty. If this is not the first read, then this is a problem.\n" << vprDEBUG_FLUSH;
279       }
280       else
281       {
282          vprDEBUG(vprDBG_ALL, vprDBG_CONFIG_LVL) << "Warning: Digital::getGloveData: Requested devNum " << devNum << " is not in the range available.  May have configuration error\n" << vprDEBUG_FLUSH;
283       }
284       return mDefaultValue;
285    }
286 }
287
288 /**
289  * Utility function to convert a 10 size vector of DigitalData to GloveData
290  */
291 std::vector<GloveData> Glove::getGloveDataFromDigitalData(const std::vector<DigitalData> &digitalData)
292 {
293    assert(digitalData.size()>=10);
294
295    std::vector<GloveData> gloveData=std::vector<GloveData>(2);
296
297    for(unsigned int i=0;i<2;i++)
298    {
299       for(unsigned int j=0;j<GloveData::NUM_COMPONENTS-1;j++)
300       {
301          // Use funky indexing here to access the correct digitalData
302          if( digitalData[i*(GloveData::NUM_COMPONENTS-1)+j].getDigital() == 1)
303          {
304             for(unsigned int k=0;k<GloveData::NUM_JOINTS;k++)
305             {
306                gloveData[i].mAngles[j][k]=gmtl::Math::PI_OVER_2;
307             }
308          }
309          else
310          {
311             for(unsigned int k=0;k<GloveData::NUM_JOINTS;k++)
312             {
313                gloveData[i].mAngles[j][k]=0;
314             }
315          }
316       }
317    }
318
319    gloveData[0].calcXforms();
320    gloveData[1].calcXforms();
321
322    return gloveData;
323 }
324
325 } // End of gadget namespace
326
Note: See TracBrowser for help on using the browser.