【问题标题】:Lego Mindstorm NXT, Cocoa, and HiTechnic SensorsLego Mindstorm NXT、Cocoa 和 HiTechnic 传感器
【发布时间】:2009-12-28 04:35:36
【问题描述】:

我从this project 获取了现有代码,到目前为止我对它非常满意。

但是,我现在需要使用一些我从 hitechnic 购买的第三方传感器,例如加速度计、陀螺仪和 3D 指南针 - 仅举几例.

我现在不知道从哪里开始,但我需要做的是添加到我现有的代码库(基于 this),并将我的框架有效地粘合到新硬件上。

谁能指出我正确的方向?我找不到设备制造商提供的任何 API,(但我已通过电子邮件向他们询问 - 尚未回复)。

我也开始在this 页面上记录我的发现。

【问题讨论】:

    标签: objective-c cocoa frameworks robot lego


    【解决方案1】:

    好的,我看过了。陀螺仪等模拟传感器非常容易......

    我几乎只是重复使用了另一个模拟传感器 - 光传感器...

    - (void)setupGyroscopicSensor:(UInt8)port {
        [self setInputMode:port
                      type:kNXTGyroscope
                      mode:kNXTRawMode];
    }
    

    对于轮询,我使用了通用轮询方法...

    - (void)pollSensor:(UInt8)port interval:(NSTimeInterval)seconds;
    

    ...来自 LegoNXTRemote 代码。

    数字版本并不那么容易 - 特别是对于软件/硬件经验为零的人来说。这是工作的超声波传感器代码、设置和轮询。最后我只写这些方法的原型和一个 git clone 给对完整代码感兴趣的人。

    - (void)setupUltrasoundSensor:(UInt8)port continuous:(BOOL)continuous;
    - (void)getUltrasoundByte:(UInt8)port byte:(UInt8)byte;
    - (void)pollUltrasoundSensor:(UInt8)port interval:(NSTimeInterval)seconds;
    

    请注意它如何拥有自己的专用轮询方法。所以,现在的问题是如何为加速度计写一个。

    您在购买传感器时获得的信息是一个将地址映射到内容的表格:

    42H (byte) -> X-axis upper 8 bits
    43H (byte) -> X-axis upper 8 bits
    44H (byte) -> X-axis upper 8 bits
    45H (byte) -> X-axis lower 8 bits
    46H (byte) -> X-axis lower 8 bits
    47H (byte) -> X-axis lower 8 bits
    

    ...查看超声波传感器,我可以看到对0x42 的引用——我猜这是地址所在的位置,但我现在只能了。

    如果我在这方面取得任何进展,我会通知您。


    好的,这就是加速度计的位置。

    我首先向设备发送以下消息...

    0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42
    

    这分别意味着什么(我很可能是错的)是......

    kNXTRawMode
    kNXTGetInputValues
    kNXTRet     //. Meaning we expect a return value
    kNXTLSWrite //. As opposed to read
    port        //. Port 0x03 --> Port 4
    txLength
    rxLength
    //. message...
    0x02 //. Set the I2C slave address
    0x42 //. Set the register we're interested in
    

    接下来我们发送一个读取请求...

    0x03, 0x00, 0x00, 0x0e, 0x03
    

    我们得到了回应......

    0x03, 0x00, 0x02, 0x0f, 0xe0
    

    ...以错误结束。

    这是一段日志...

               libNXT[0x02]: Attempting to connect to NXT...
               libNXT[0x02]: Open sequence initiating...
               libNXT[0x02]: Channel Opening Completed
               libNXT[0x08]: >>> :0x06, 0x00, 0x80, 0x03, 0x0b, 0x02, 0xf4, 0x01, 
               libNXT[0x08]: >>> :0x02, 0x00, 0x00, 0x0b, 
               libNXT[0x08]: <<< :0x05, 0x00, 0x02, 0x0b, 0x00, 0x82, 0x1e, 
               libNXT[0x08]: @selector does NOT respond to NXTOperationError:operation:status:
               libNXT[0x08]: @selector responds to NXTBatteryLevel:batteryLevel:
     startPollingSensor: setup sensor
     startPollingSensor: start polling
               libNXT[0x02]: Polling Port 3
               libNXT[0x08]: >>> :0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42, 
               libNXT[0x08]: >>> :0x03, 0x00, 0x00, 0x0e, 0x03, 
               libNXT[0x08]: <<< :0x03, 0x00, 0x02, 0x0f, 0xe0, 
               libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
     nxt error: operation=0xf status=0xe0
               libNXT[0x08]: <<< :0x04, 0x00, 0x02, 0x0e, 0xe0, 0x00, 
               libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
     nxt error: operation=0xe status=0xe0
               libNXT[0x08]: @selector does NOT respond to NXTOperationError:operation:status:
               libNXT[0x02]: Polling Port 3
               libNXT[0x08]: >>> :0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42, 
               libNXT[0x08]: >>> :0x03, 0x00, 0x00, 0x0e, 0x03, 
               libNXT[0x08]: <<< :0x03, 0x00, 0x02, 0x0f, 0xe0, 
               libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
     nxt error: operation=0xf status=0xe0
               libNXT[0x08]: <<< :0x04, 0x00, 0x02, 0x0e, 0xe0, 0x00, 
               libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
     nxt error: operation=0xe status=0xe0
               libNXT[0x08]: @selector does NOT respond to NXTOperationError:operation:status:
               libNXT[0x02]: Polling Port 3
               libNXT[0x08]: >>> :0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42, 
               libNXT[0x08]: >>> :0x03, 0x00, 0x00, 0x0e, 0x03, 
               libNXT[0x08]: <<< :0x03, 0x00, 0x02, 0x0f, 0xe0, 
               libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
     nxt error: operation=0xf status=0xe0
               libNXT[0x08]: <<< :0x04, 0x00, 0x02, 0x0e, 0xe0, 0x00, 
               libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
     nxt error: operation=0xe status=0xe0
               libNXT[0x08]: @selector does NOT respond to NXTOperationError:operation:status:
    Error while running hook_stop:
               libNXT[0x08]: >>> :0x03, 0x00, 0x00, 0x0e, 0x03,
               libNXT[0x08]: <<< :0x03, 0x00, 0x02, 0x0f, 0xe0,
               libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
     nxt error: operation=0xf status=0xe0
               libNXT[0x08]: <<< :0x04, 0x00, 0x02, 0x0e, 0xe0, 0x00,
               libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
     nxt error: operation=0xe status=0xe0
    

    这都是基于here的示例代码,如下...

    SetSensorLowspeed(IN_1);
    int count;
    
    int xval;
    int yval;
    int zval;
    
    byte inI2Ccmd[];
    byte outbuf[];
    while (TRUE) {
        ArrayInit(inI2Ccmd, 0, 2); // set the buffer to hold 10 values (initially all are zero)
        inI2Ccmd[0] = 0x02; // set values in the array
        inI2Ccmd[1] = 0x42;
        count=8;                                  //read count set to 8 bytes
        I2CBytes(IN_1, inI2Ccmd, count, outbuf);  //read the acceleration sensor on port 1
        xval=outbuf[0];                           //load x axis upper 8 bits
        yval=outbuf[1];                           //load Y axis upper 8 bits
        zval=outbuf[2];                           //load z axis upper 8 bits
        if (xval > 127) xval-=256;                //convert x to 10 bit value
        xval=xval*4 + outbuf[3];
        if (yval > 127) yval-=256;                //convert y to 10 bit value
        yval=yval*4 + outbuf[4];
        if (zval > 127) zval-=256;                //convert z to 10 bit value
        zval=zval*4 + outbuf[5];
        ...
    
    }
    

    太棒了!看起来它现在可以工作了 - 我只需要调整输出来提取实际的 X、Y 和 Z 读数。

    如果它确实有效,我会告诉你们所有人,但在我证明它之前,我会保留这张票。


    好的,看起来它现在可以工作了,但是传感器中的错误已经足够多,我还没有证明我真的解决了这个问题。这是sn-p的代码:

    SInt8 *outbuf = malloc(48);
    [data getBytes:outbuf length:6];
    SInt16 x = outbuf[0]; x <<= 2; x += outbuf[3];
    SInt16 y = outbuf[1]; y <<= 2; y += outbuf[4];
    SInt16 z = outbuf[2]; z <<= 2; z += outbuf[5];
    free(outbuf);
    [self setSensorTextField:port
                       value:[NSString stringWithFormat:@"<%d, %d, %d>",
                              x, y, z]];
    

    如果有人对此感兴趣,我邀请您下载源代码并尝试一下 - 我还没有科学地证明这实际上是正确的,尽管乍一看它看起来还不错。


    好的,我已经进行了一些测试 - 看起来不错。根据设备随附的说明,我已将值转换为 G - 说明 1 G ~ 200 个单位(我希望它们的性能比 ~200 好一点,一些错误迹象会很好)。

    //. Acceleration in G's
    SInt8 *outbuf = malloc(48);
    [data getBytes:outbuf length:6];
    SInt16 x = outbuf[0]; x <<= 2; x += outbuf[3]; float gX = x/200.f;
    SInt16 y = outbuf[1]; y <<= 2; y += outbuf[4]; float gY = y/200.f;
    SInt16 z = outbuf[2]; z <<= 2; z += outbuf[5]; float gZ = z/200.f;
    free(outbuf);
    [self setSensorTextField:port
                       value:[NSString stringWithFormat:@"%0.2f, %0.2f, %0.2f",
                              gX, gY, gZ]];
    

    如果您根据供应商页面定位设备,您可以看到每次访问的加速度读数约为 1.02f。

    我想我现在可以关闭它并着手清理框架。


    代码可以在:

    git clone git://git.autonomy.net.au/nimachine Nimachine
    

    【讨论】:

      【解决方案2】:

      我今天收到了 HiTechnic 的回复,在他们的允许下,我将他们的回复发给大家。

      Hi Nima,
      
      There are two types of sensors, digital and analog.  The Analog sensors you
      can basically read like you would the LEGO light sensor.  If you have that
      working then you can read the HiTechnic analog sensors.  These include the
      EOPD, Gyro as well as the Touch Multiplexer.
      
      For the TMUX there is [sample NXC code][1] on the product info page.
      You should be able to use that as a basis if you want to support this device.
      
      The other sensors are digital I2C sensors.  Most of these sensors have I2C
      register information on their respective product information page and/or it
      was included on a sheet that came with the sensor.  First of all, to make
      these sensors work with your framework you need to have I2C communications
      working.  After that it will be a matter of creating your own API that uses
      the I2C interface with the sensors.  I recommend that you download and look
      at Xander Soldaat's RobotC driver suite for the HiTechnic sensors.  You will
      find this near the bottom of the HiTechnic downloads page.
      
      Regards,
      Gus
      HiTechnic Support
      

      参考资料:

      【讨论】:

      • 虽然这不能回答我的问题,但这是一个好的开始 - 一旦我有时间跟进它并获得一些结果,我会在这里发布并更新每个人。跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-19
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多