VREP Regular API提供了串口操作的相关函数,可以对串口进行打开、关闭和读写:

  下面使用一款淘宝上常见的AHRS(Attitude and heading reference system,航姿参考系统)模块来驱动VREP中的虚拟模型,控制其姿态。VREP通过串口读取传感器实时发送的数据并进行解析。

  传感器通过串口发送2种数据:

  1. 解算后的姿态角和气压高度等数据
  2. 原始的传感器ADC数据(直接从传感器读取出来的测量值,没有经过解算处理)

  下面是VREP中以16进制显示的接收到的串口数据:

  根据约定的通信协议,上位机要对接收到的字符串进行解析。关键的一步是要将2个byte型(8位)变量转换为int16型(有符号整型变量,16位),因为角度、高度、温度等数据都可以有正负。

  计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。

  以0x8000为例,若用无符号数表达其值为32768,若用有符号数表达其值为-32768。 因为0x8000最高位为1是负数,其代表的值为-(0x7FFF + 1) = -(0x8000) = - 32768(负数的补码求原码和负数的原码求补码的方法一样:除符号位外,每位求反,末位加一

  • 原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。比如:

[+1] = 0000 0001

[-1] = 1000 0001

  • 正数的反码是其本身,负数的反码是在其原码的基础上,符号位不变,其余各个位取反:

[+1] = [00000001] = [00000001]

[-1] = [10000001] = [11111110]

  • 正数的补码就是其本身,负数的补码是在其原码的基础上,符号位不变,其余各位取反后+1. (即在反码的基础上+1):

[+1] = [00000001] = [00000001] = [00000001]

[-1] = [10000001] = [11111110] = [11111111]

  补码运算的规则如下。采用补码表示数,在计算机的加、减法运算中,不必判断数的正负,只要符号位参加运算就能自动得到正确的结果。

[ x + y ]  =  x  +  y

[ x - y ]补   =  x  +  [-y]

  将两个2个byte数据转换为int16型的函数如下:

function make_int16(b1, b2)
  assert ( <= b1 and b1 <= 0xff)
  assert ( <= b1 and b2 <= 0xff)
  local mask = ( << )
  local res = (b1 << ) | (b2 << )
  return (res ~ mask) - mask
end

  其中mask = (1000 0000 0000 0000)b,将其与res进行异或操作(res~mask)只改变符号位,正数符号位变为1,负数符号位变为0。然后再减去mask,得到res的有符号数。

  以0x81和0xC3为例:

  res = 0x81<<8 | 0xC3 = (1000 0001 1100 0011)b

  res~mask = (0000 0001 1100 0011)b

  ((res~mask) - mask)  =  (res~mask)+(-mask )补 = (0000 0001 1100 0011)b补 + (1000 0000 0000 0000)b补 = (1000 0001 1100 0011)b补 = -32317

  Lua 5.3开始可以使用“<<”、“~”、“|”等运算符进行移位、取反、或等按位操作,而VREP 3.4中使用的是Lua 5.1还不支持按位操作运算符,可以下载合适的bitwise operation lib,下面使用了LuaBit来完成移位等操作。

代码如下:

require 'bit'

make_int16 = function(bh ,bl)

  assert ( <= bh and bh <= 0xff)
assert ( <= bl and bl <= 0xff)
local mask = bit.blshift(, ) -- mask = 1 << 15
local res = bit.bor(bit.blshift(bh,), bl) -- res = (bh << 8) | bl
return bit.bxor(res, mask) - mask -- (res ~ mask) - mask end HelicopterHandle = simGetObjectHandle("Helicopter") --defining the serial port number
port = simGetScriptSimulationParameter(sim_handle_self,'serialPortNumber')
portNumber = "COM"..port
baudrate = -- Opens a serial port (RS-232) for communication
serial = simSerialOpen(portNumber, baudrate) while (simGetSimulationState()~=sim_simulation_advancing_abouttostop) do -- Reads how many bytes are waiting to be read on a serial port
--local number =simSerialCheck(serial) -- Reads from a previously opened serial port (RS-232).
local str = simSerialRead(serial, , true, '', ) visibleString = ''
if str ~= nil then
for i=,#str, do
visibleString = visibleString..string.format("%02X ", string.byte(str,i))
end
--simAddStatusbarMessage(visibleString) yaw = make_int16(string.byte(str,), string.byte(str,))
pitch = make_int16(string.byte(str,), string.byte(str,))
roll = make_int16(string.byte(str,), string.byte(str,)) simAddStatusbarMessage(string.format("Yaw:%.1f Pitch:%.1f Roll:%.1f", yaw*0.1,pitch*0.1,roll*0.1))
simSetObjectOrientation(HelicopterHandle, -, {math.pi/-pitch*0.1*math.pi/,-yaw*0.1*math.pi/,roll*0.1*math.pi/}) end end -- Closes a serial port (RS-232). Port is automatically closed at simulation stop
simSerialClose(serial)

参考:
Bitwise Operators

原码, 反码, 补码 详解

Online Binary-Decimal Converter

How can I convert a pair of bytes into a signed 16-bit integer using Lua?

V-rep学习笔记:串口操作的更多相关文章

  1. Javascript学习笔记二——操作DOM

    Javascript学习笔记 DOM操作: 一.GetElementById() ID在HTML是唯一的,getElementById()可以定位唯一的一个DOM节点 二.querySelector( ...

  2. MongoDB学习笔记:Python 操作MongoDB

    MongoDB学习笔记:Python 操作MongoDB   Pymongo 安装 安装pymongopip install pymongoPyMongo是驱动程序,使python程序能够使用Mong ...

  3. Javascript学习笔记三——操作DOM(二)

    Javascript学习笔记 在我的上一个博客讲了对于DOM的基本操作内容,这篇继续巩固一下对于DOM的更新,插入和删除的操作. 对于HTML解析的DOM树来说,我们肯定会时不时对其进行一些更改,在原 ...

  4. .net学习笔记---xml操作及读写

    一.XML文件操作中与.Net中对应的类 微软的.NET框架在System.xml命名空间提供了一系列的类用于Dom的实现. 以下给出XML文档的组成部分对应.NET中的类: XML文档组成部分 对应 ...

  5. python学习笔记:文件操作和集合(转)

    转自:http://www.nnzhp.cn/article/16/ 这篇博客来说一下python对文件的操作. 对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句 ...

  6. PHP学习笔记--文件目录操作(文件上传实例)

    文件操作是每个语言必须有的,不仅仅局限于PHP,这里我们就仅用PHP进行讲解 php的文件高级操作和文件上传实例我放在文章的最后部分.--以后我还会给大家写一个PHP类似于网盘操作的例子 注意:阅读此 ...

  7. python自动化测试学习笔记-6excel操作xlwt、xlrd、xlutils模块

    python中通过xlwt.xlrd和xlutils操作xls xlwt模块用于在内存中生成一个xls/xlsx对象,增加表格数据,并把内存中的xls对象保存为本地磁盘xls文件; xlrd模块用于把 ...

  8. ThinkPHP5.1学习笔记 数据库操作

    数据库 参见<Thinkphp5.1完全开发手册>学习 Mirror王宇阳 数据库连接 ThinkPHP采用内置抽象层对数据库操作进行封装处理:且基于PDO模式,可以适配各种数据库. 数据 ...

  9. 【最简单的vim教程】vim学习笔记-基础操作

    说明 C-字母 = Ctrl + 字母 char = 任意字符 开始编辑 insert 按键 功能 说明 i(I) insert 当前位置插入(当前行前) a(A) append 当前字符后面插入(当 ...

  10. js学习笔记:操作iframe

    iframe可以说是比较老得话题了,而且网上也基本上在说少用iframe,其原因大致为:堵塞页面加载.安全问题.兼容性问题.搜索引擎抓取不到等等,不过相对于这些缺点,iframe的优点更牛,跨域请求. ...

随机推荐

  1. Pandas 快速入门(二)

    本文的例子需要一些特殊设置,具体可以参考 Pandas快速入门(一) 数据清理和转换 我们在进行数据处理时,拿到的数据可能不符合我们的要求.有很多种情况,包括部分数据缺失,一些数据的格式不正确,一些数 ...

  2. codevs 2190 有理逼近

    2190 有理逼近  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold   题目描述 Description 对于一个素数P,我们可以用一系列有理分数(分子.分母都是 ...

  3. libnids使用举例

    ---[[ libnids应用实例 ]]---------------------------------- 1.nids_next()函数的应用 ========================== ...

  4. vs2010使用svn--浅谈AnkhSvn

    (1)建立本地的服务器版本.Subversion->Add to Subversion 此功能的作用是从将新创建的工程添加到svn服务器上 (2)从svn检出 Subversion->Op ...

  5. [leetcode]Rotate Image @ Python

    原题地址:https://oj.leetcode.com/problems/rotate-image/ 题意: You are given an n x n 2D matrix representin ...

  6. RxJava 操作符 on和doOn 线程切换 调度 Schedulers 线程池 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. 网站设计之合理架构CSS

    架构CSS 在当前浏览器普遍支持的前提下,css被我们赋予了前所未有的使命.然而依赖css越多,样式表文件就会变得越大越复杂.与此同时,文件维护和组织的考验也随之而来. (曾几何时)只要一个css文件 ...

  8. js改变iframe 的src地址

    <script> function dizhi(){ document.getElementById("aaa").src='http://www.sohu.com' ...

  9. 解剖android中的闹钟app 一

    首先,看一看android市场上有哪些主流的闹钟app了,我们来进行一个简单的评测: 一.正点闹钟 这是一款源自金山技术的闹钟app,其主力创始团队都是来自于金山,其装机量,下载量都是排名第一.老样子 ...

  10. Android -- TypedArray

    当我们自定义View的时候,在给View赋值一些长度宽度的时候,一般都是在layout布局文件中进行的.,比如android:layout_height="wrap_content" ...