一种机器人操作系统中的节点通信方法和装置与流程

文档序号:17695378发布日期:2019-05-17 21:27阅读:320来源:国知局
一种机器人操作系统中的节点通信方法和装置与流程

本发明涉及机器人技术领域,特别涉及一种机器人操作系统中的节点通信方法和装置。



背景技术:

现有技术中,机器人操作系统(robotoperationsystem,ros)的通信机制基于tcp/udp通信协议,在ros中,每个节点(node)都是一个进程,节点之间的通信是通过话题注册和订阅的方式实现。talker节点在rosmaster注册话题并向该话题发送一个消息,listener节点只要订阅这个话题就能接收到talker节点发来的消息。

但是ros这种通信机制的实时性不稳定,进程与进程之间的通信效率受网络影响很大,无法满足对数据传输实时性要求比较高的场景(如无人车),而且对内存的频繁拷贝会消耗太多计算机资源。



技术实现要素:

鉴于上述问题,提出了本发明以便提供一种克服上述问题或者至少部分地解决上述问题的机器人操作系统中的节点通信方法和装置。

根据本发明的一个方面,提供了一种机器人操作系统中的节点通信方法,包括:

选取需要进行通信的至少一对机器人操作系统ros节点,并为每对ros节点设置至少一个内存标识符;

根据作为设立端的ros节点的创建请求,在相应主机上为一对ros节点创建一个共享内存,将一个共享内存与一个内存标识符进行绑定;

当发起数据通信时,控制通信一方的ros节点,通过内存标识符查找到共享内存,并写入数据;以及,控制通信另一方的ros节点,通过内存标识符查找到共享内存,并读取共享内存中的数据。

可选地,

为每对ros节点设置多个不相同的内存标识符;

并为一对ros节点创建多个共享内存,分别将一个共享内存与一个内存标识符进行绑定。

可选地,

若设立端所在的主机为第一主机,当创建请求指示待创建的共享内存位于与第一主机不同的第二主机时,先控制设立端ros节点与第二主机建立连接,通过该连接将创建请求发送至第二主机;

利用第二主机中的ros主控接收并处理创建请求,在第二主机上创建共享内存。

可选地,

当发起数据通信时,控制位于第一主机的通信一方的ros节点,与第二主机建立连接,通过该连接将数据通信请求发送至第二主机;

利用第二主机中的ros主控接收并处理数据通信请求,在第二主机上查找到共享内存,实现数据写入或读取。

可选地,

控制位于第一主机的通信一方的ros节点通过publish函数发布数据,与第二主机建立连接;以及,

控制所述第二主机中的ros主控通过调用xmlrpc函数,接收位于第一主机的通信一方的ros节点发布的数据。

可选地,还包括:

为每对ros节点设置指示通信状态的互斥量;

在创建共享内存时,利用相应互斥量为每一个共享内存设置互斥锁;

在进行数据通信时,当一个ros节点向共享内存中写入/读取数据时,控制互斥锁指示处于通信状态,直至写入/读取操作完毕;以及,

当互斥锁指示处于通信状态时,拒绝另一ros节点对该互斥锁对应的共享内存进行写入/读取操作。

可选地,还包括利用下述方式生成创建请求:

利用内存标识符、待创建内存的容量大小,调用ros系统中的shmget函数,生成所述创建请求;以及

当发起数据通信时,控制通信一方的ros节点,通过内存标识符调用具有相同内存标识符的shmget函数,实现向共享内存中写入数据;以及,控制通信另一方的ros节点,通过内存标识符调用具有相同内存标识符的shmget函数,实现读取共享内存中的数据。

可选地,所述在相应主机上为一对ros节点创建一个共享内存包括:

采用shimd_kernel数据结构在ros系统中描述所述共享内存,通过该数据结构中的相应属性,记录进程对内存的使用状况并将创建的内存与相应进程进行关联。

根据本发明的另一个方面,提供了一种机器人操作系统中的节点通信装置,包括:

设置单元,适于选取需要进行通信的至少一对机器人操作系统ros节点,并为每对ros节点设置至少一个内存标识符;

创建单元,适于根据作为设立端的ros节点的创建请求,在相应主机上为一对ros节点创建一个共享内存,将一个共享内存与一个内存标识符进行绑定;

控制单元,适于当发起数据通信时,控制通信一方的ros节点,通过内存标识符查找到共享内存,并写入数据;以及,控制通信另一方的ros节点,通过内存标识符查找到共享内存,并读取共享内存中的数据。

可选地,

所述创建单元,适于若设立端所在的主机为第一主机,当创建请求指示待创建的共享内存位于与第一主机不同的第二主机时,先控制设立端ros节点与第二主机建立连接,通过该连接将创建请求发送至第二主机;利用第二主机中的ros主控接收并处理创建请求,在第二主机上创建共享内存。

根据本发明的技术方案,用内存共享机制实现ros的节点之间的通信,进行通信的节点通过主动访问共享内存获取共享内存中的数据,不会受限于进行通信的节点之间的网络连通性,提高基于ros通信的数据传输效率和稳定性,可以满足对数据传输实时性要求比较高的场景,并减少计算机资源的消耗。

附图说明

通过阅读下文优选实施方式的详细描述,各种其他的优点和益处对于本领域普通技术人员将变得清楚明了。附图仅用于示出优选实施方式的目的,而并不认为是对本发明的限制。而且在整个附图中,用相同的参考符号表示相同的部件。在附图中:

图1示出了根据本发明一个实施例提供的机器人操作系统中的节点通信方法的流程示意图;

图2示出了根据本发明一个实施例提供的机器人操作系统中的节点通信的结构示意图;

图3示出了根据本发明一个实施例提供的内存共享映射的示意图;

图4示出了根据本发明一个实施例提供的机器人操作系统中的节点通信装置的结构示意图;

图5示出了根据本发明一个实施例的电子设备的结构示意图;

图6示出了根据本发明一个实施例的计算机可读存储介质的结构示意图。

具体实施方式

下面将参照附图更详细地描述本公开的示例性实施例。虽然附图中显示了本公开的示例性实施例,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施例所限制。相反,提供这些实施例是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。

图1为本发明一个实施例提供的一种机器人操作系统中的节点通信方法的流程示意图。如图1所示,该方法包括:

步骤s110,选取需要进行通信的至少一对ros(robotoperationsystem,机器人操作系统)节点,并为每对ros节点设置至少一个内存标识符。

步骤s120,根据作为设立端的ros节点的创建请求,在相应主机上为一对ros节点创建一个共享内存,将一个共享内存与一个内存标识符进行绑定。

这里的ros节点相当于ros系统中的一个可执行程序。作为设立端的ros节点通过ros系统提供的api发送创建请求,以便在内存中申请一个共享内存。

步骤s130,当发起数据通信时,控制通信一方的ros节点,通过内存标识符查找到共享内存,并写入数据;以及,控制通信另一方的ros节点,通过内存标识符查找到共享内存,并读取共享内存中的数据。

本实施例中,为每对ros节点设置的内存标识符是系统全局唯一的,可以用key表示。当不同的两个节点都通过同一个key访问共享内存时,即说明这两个节点访问的是同一个共享内存。

共享内存是一种高效的进程间通信方式,两个节点之间可以直接读写内存,而不需要任何数据的拷贝。可见,通过本实施例,用内存共享机制实现ros的节点之间的通信,进行通信的节点通过主动访问共享内存获取共享内存中的数据,不会受限于进行通信的节点之间的网络连通性,提高基于ros通信的数据传输效率和稳定性,并减少计算机资源的消耗,并且提高的程序的安全性,适用于对通信效率要求较高的领域。

图2示出了根据本发明一个实施例提供的机器人操作系统中的节点通信的结构示意图。如图2所示,ros节点1、ros节点2和ros节点3之间可以通过共享内存实现通信。具体地,ros节点1、ros节点2和ros节点3归属于同一个ros主控,在这三个节点中的其中一个发出创建共享内存的请求后,会根据该请求创建一个共享内存,设置一个内存标识符,并将内存标识符与创建的共享内存进行绑定。在进行通信时,本实施例的方案控制ros节点1、ros节点2和ros节点3通过内存标识符访问共享内存,实现数据的写入或读取。这样就可以实现ros节点1、ros节点2和ros节点3之间的通信。

在本发明的一个实施例中,图1所示的方法中,步骤s110进一步包括:为每对ros节点设置多个不相同的内存标识符;并为一对ros节点创建多个共享内存,分别将一个共享内存与一个内存标识符进行绑定。

本实施例中,可以为每对ros节点设置多个不相同的内存标识符,且每对ros节点可以创建多个共享内存,每个共享内存均与一个唯一的内存标识符进行绑定,这样每对ros节点就可以访问多个共享内存。

在本发明的一个实施例中,若设立端所在的主机为第一主机,当创建请求指示待创建的共享内存位于与第一主机不同的第二主机时,步骤s130进一步包括:先控制设立端ros节点与第二主机建立连接,通过该连接将创建请求发送至第二主机;利用第二主机中的ros主控接收并处理创建请求,在第二主机上创建共享内存。

创建共享内存时,创建的共享内存可以在设立端的ros节点所在的主机上,即实现同一主机中的ros节点之间的通信。例如,同一主机间的ros节点通信时,首先,创建共享内存。节点a使用系统提供的shmget(key)通过操作系统提供的api从内存中申请一个共享内存;其次,为共享内存加互斥锁,先初始化互斥锁,再将互斥量保存在共享内存中;最后,节点a通过publish函数发布数据后,将节点a发布的数据写入共享内存;节点b连接共享内存,节点b通过shmat(intkey)将共享内存连接到当前节点的地址空间,就可以进行内存的读取。

本技术方案中,也可以在不同于设立端的ros节点所在的主机上,即实现不同主机的ros节点之间的通信。本实施例中,可以实现在不同的主机上创建共享内存,具体是作为设立端的ros节点与第二主机建立连接,由第二主机的ros主控根据作为设立端的ros节点发送的创建请求创建共享内存。这样也可以实现不同主机之间的节点的通信。即这种场景下,第一主机上的ros节点需要先连接至第二主机,再利用第二主机上的ros主控创建共享内存,一般情况下,第一主机上的ros节点和第二主机上的ros节点归属于同一个ros主控。

进一步地,在上述实施例的基础上,步骤s130进一步包括:当发起数据通信时,控制位于第一主机的通信一方的ros节点,与第二主机建立连接,通过该连接将数据通信请求发送至第二主机;利用第二主机中的ros主控接收并处理数据通信请求,在第二主机上查找到共享内存,实现数据写入或读取。

因为共享内存位于第二主机,位于第一主机的通信一方的ros节点要访问第二主机的共享内存,需要与第二主机建立连接,以便发送数据通信请求。当第二主机的ros主控接收到数据通信请求时,根据数据通信请求,确定相应的共享内存,实现位于第一主机的通信一方的ros节点对第二主机上的共享内存中的数据的写入或读取。

具体地,在上述实施例基础上,步骤s130包括:控制位于第一主机的通信一方的ros节点通过publish函数发布数据,与第二主机建立连接;以及,控制第二主机中的ros主控通过调用xmlrpc函数,接收位于第一主机的通信一方的ros节点发布的数据。

在ros系统中,每个节点相当于一个独立的进程,现有技术中的通信方式是调用publish()函数将数据发送给其他节点,其他节点调用subscribe()来监听数据。本实施例中,位于第一主机的通信一方的ros节点通过publish函数发布数据后,直接调用shmget函数把数据写入共享内存中,其他节点需要数据时直接访问共享内存即可。

在一个具体的例子中,不同主机间的ros节点通信时,首先,创建共享内存,在主机1上的节点a与主机2建立连接,通过该连接将创建请求发送至第二主机,利用第二主机中的ros主控接收并处理创建请求,在第二主机上创建共享内存。然后,为共享内存加互斥锁,先初始化互斥锁,再将互斥量保存在共享内存中。将节点a的数据传输到共享内次所在的主机2,并写入共享内存。节点a通过publish发布器将数据发布出去,然后主机2的rosmaster中的xmlrpc将会接收到节点a发布的数据,然后根据指定的key将数据写入这块共享内存里面。节点b通过shmat(intkey)将共享内存连接到当前节点的地址空间,就可以进行内存的读取。

在本发明的一个实施例中,图1所示的方法还包括:为每对ros节点设置指示通信状态的互斥量;在创建共享内存时,利用相应互斥量为每一个共享内存设置互斥锁;在进行数据通信时,当一个ros节点向共享内存中写入/读取数据时,控制互斥锁指示处于通信状态,直至写入/读取操作完毕;以及,当互斥锁指示处于通信状态时,拒绝另一ros节点对该互斥锁对应的共享内存进行写入/读取操作。

多个节点同时访问一个共享内存,需要同步机制,例如通过互斥锁或者信号量的方式实现。本实施例中,通过互斥锁的方式实现。具体是,为每对ros节点设置指示通信状态的互斥量。在创建共享内存时,首先初始化互斥锁,优选地,可以使用系统提供的pthread_mutex_init()函数完成初始化,并设置相关属性;然后对互斥量进行上锁,为了让不同的节点得到同一个互斥锁,本实施例中,将互斥量保存在共享内存中,在初始化该互斥锁的时候,设置为进程间共享,这两不同的节点连接到共享内存后就可以获得这个互斥锁。

在本发明的一个实施例中,图1所示的方法还包括利用下述方式生成创建请求:利用内存标识符、待创建内存的容量大小,调用ros系统中的shmget函数,生成创建请求;以及当发起数据通信时,控制通信一方的ros节点,通过内存标识符调用具有相同内存标识符的shmget函数,实现向共享内存中写入数据;以及,控制通信另一方的ros节点,通过内存标识符调用具有相同内存标识符的shmget函数,实现读取共享内存中的数据。

在进行共享内存创建时,使用系统提供的shmget函数实现,具体是intshmget(key_tkey,size_tsize,intshmflg),其中,key代表内存标识符,size代表内存的大小,shmflg代表权限。

shmflg是共享内存的权限标志,与文件读写的权限标志相类似,但功能上表示对共享内存的读写权限。当一个ros节点通过shmget函数创建共享内存时,通过设置shmflg的值来设置创建的共享内存的读写权限。例如,设置shmflg取值,用来表示发送创建请求的ros节点可以向创建的共享内存读取和写入数据,即对该共享内存有读和写的权限,而其他ros节点只能读取共享内存中的数据,即只对该共享内存有读的权限。具体地,当shmflg为ipc_creat时,可以创建共享内存,也可以读取共享内存;当shmflg为ipc_excl时,只能读取共享内存,而不能创建共享内存。

可知,本实施例的创建请求中除了内存标识符和容量之外,还可以包括上述权限标志。

同样的,当不同的节点要访问共享内存时,调用intshmger(key_tkey,size_tsize,intshmflg)可以实现共享内存的访问。如果不同的节点使用的key的值相同,即是访问同一共享内存。

在本发明的一个实施例中,图1所示的方法的步骤s120中的在相应主机上为一对ros节点创建一个共享内存包括:采用shimd_kernel数据结构在ros系统中描述共享内存,通过该数据结构中的相应属性,记录进程对内存的使用状况并将创建的内存与相应进程进行关联。

每一个新创建的共享内存都用一个shmid_kernel数据结构来表达。系统中所有的shmid_kernel数据结构都保存在shmid_segs向量表中,该向量表的每一个元素都是一个指向shmid_kernel数据结构的指针。

具体地,数据结构shmid_kernel的定义如下:

structshmid_kernel

{

structshmid_dsu;

unsignedlongshm_npages;

unsignedlong*shm_pages;

structvm_area_struct*attaches;

}

其中,shmid_ds描述了共享内存的认证信息,字节大小,最后一次粘附时间、分离时间、改变时间,创建该共享内存的用户进程,最后一次对它操作的用户进程,当前有多少个用户进程在使用它等信息。

shm_pages代表该共享内存所占据的内存页面数组,数组里面的每个元素当然是每个内存页面的起始地址。

shm_npages则是该共享内存对象占用内存页面的个数,以页为单位。

attaches描述被共享的共享内存所关联的各进程的虚拟地址空间,即内存映射。

这里的内存映射是将设备或者硬盘存储一块空间映射到物理内存,然后操作这块物理内存就是在操作实际的硬盘空间,不需要经过内核传递。在ros系统中,上述的进程即是ros节点。

ros节点都有自己私有的虚拟地址空间,可以防止其它节点修改其数据。但是,许多节点都有相同的只读文本区域,例如内核代码,数据等。如果每个节点运行时都拷贝一份,那就是造成浪费。因此,内存映射正好解决了这个问题,当一个节点将一个共享内存映射到它的虚拟存储器的一个区域时,那么这个节点对这个区域的任何写操作,对于其它把这个共享内存也映射到自己的虚拟存储器也是可见的。

在本技术方案中,每一个要共享这个共享内存的ros节点都必须通过ros系统调用将共享内存映射(attach)到ros节点的虚拟地址空间中。当共享内存创建后,将共享内存关联到ros系统的两个ros节点的虚拟地址空间。

图3示出了根据本发明一个实施例提供的内存共享映射的示意图。如图3所示,系统中的存储器空间是有限的,而且还容易被破坏,因此提供了一种虚拟存储器,以更有效地管理存储器。虚拟存储器将主存储器看作磁盘上的地址空间的高速缓存,为每个进程提供了一致的地址空间,并保护进程的地址空间不被其他进程破坏。本技术方案中,创建的共享内存在内核虚拟存储器中有一个共享内存映射区。ros节点1的虚拟地址空间和ros节点2的虚拟地址空间分别与内核虚拟存储器的共享内存的映射区建立关联,进而实现ros节点对这个区域的任何读写操作。

如图3所示,虚拟存储器还涉及到5个不同的数据段,其中,未初始化的数据段(bsssegment,bss)用来存放程序中未初始化的全局变量的一块内存区域;已初始化的数据段(datasegment)用来存放程序中已初始化的全局变量的一块内存区域;代码段(codesegment/textsegment)用来存放程序执行代码的一块内存区域,在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等;堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减;栈又称堆栈,是用户存放程序临时创建的局部变量。

现有技术中,两个ros节点是通过nodehandle的publish和subscribe函数进行通信。而在本技术方案中,如图3所示,通过ros系统分别把两个ros节点的虚拟地址空间与共享内存进行映射,具体的映射步骤如下:

1)根据指定的key找到相应的共享内存。

2)如果用户没有指定与该共享内存映射的ros节点虚拟地址空间的位置,则由ros系统在ros节点的虚拟地址空间请求一块区域,与共享内存映射。

3)请求一块内存用于建立数据结构。

4)检查共享内存在ros节点的虚拟地址空间的映射区,将其加入到共享内存的队列中。

图4为本发明一个实施例提供的一种机器人操作系统中的节点通信装置的结构示意图。如图4所示,该机器人操作系统中的节点通信装置400包括:

设置单元410,适于选取需要进行通信的至少一对机器人操作系统ros节点,并为每对ros节点设置至少一个内存标识符。

创建单元420,适于根据作为设立端的ros节点的创建请求,在相应主机上为一对ros节点创建一个共享内存,将一个共享内存与一个内存标识符进行绑定。

这里的ros节点相当于ros系统中的一个可执行程序。作为设立端的ros节点通过ros系统提供的api发送创建请求,以便在内存中申请一个共享内存。

控制单元430,适于当发起数据通信时,控制通信一方的ros节点,通过内存标识符查找到共享内存,并写入数据;以及,控制通信另一方的ros节点,通过内存标识符查找到共享内存,并读取共享内存中的数据。

本实施例中,为每对ros节点设置的内存标识符是系统全局唯一的,可以用key表示。当不同的两个节点都通过同一个key访问共享内存时,即说明这两个节点访问的是同一个共享内存。

共享内存是一种高效的进程间通信方式,两个节点之间可以直接读写内存,而不需要任何数据的拷贝。可见,通过本实施例,用内存共享机制实现ros的节点之间的通信,进行通信的节点通过主动访问共享内存获取共享内存中的数据,不会受限于进行通信的节点之间的网络连通性,提高基于ros通信的数据传输效率和稳定性,并减少计算机资源的消耗,并且提高的程序的安全性,适用于对通信效率要求较高的领域。

在本发明的一个实施例中,图4所示的设置单元410,适于为每对ros节点设置多个不相同的内存标识符。

创建单元420,适于为一对ros节点创建多个共享内存,分别将一个共享内存与一个内存标识符进行绑定。

本实施例中,可以为每对ros节点设置多个不相同的内存标识符,且每对ros节点可以创建多个共享内存,每个共享内存均与一个唯一的内存标识符进行绑定,这样每对ros节点就可以访问多个共享内存。

在本发明的一个实施例中,创建单元420,适于若设立端所在的主机为第一主机,当创建请求指示待创建的共享内存位于与第一主机不同的第二主机时,先控制设立端ros节点与第二主机建立连接,通过该连接将创建请求发送至第二主机;利用第二主机中的ros主控接收并处理创建请求,在第二主机上创建共享内存。

创建共享内存时,创建的共享内存可以在设立端的ros节点所在的主机上,即实现同一主机中的ros节点之间的通信。例如,同一主机间的ros节点通信时,首先,创建共享内存。节点a使用系统提供的shmget(key)通过操作系统提供的api从内存中申请一个共享内存;其次,为共享内存加互斥锁,先初始化互斥锁,再将互斥量保存在共享内存中;最后,节点a通过publish函数发布数据后,将节点a发布的数据写入共享内存;节点b连接共享内存,节点b通过shmat(intkey)将共享内存连接到当前节点的地址空间,就可以进行内存的读取。

本技术方案中,也可以是在不同于设立端的ros节点所在的主机上,即实现不同主机的ros节点之间的通信。本实施例中,可以实现在不同的主机上创建共享内存,具体是作为设立端的ros节点与第二主机建立连接,由第二主机的ros主控根据作为设立端的ros节点发送的创建请求创建共享内存。这样也可以实现不同主机之间的节点的通信。

进一步地,在上述实施例基础上,图4所示的控制单元430,适于当发起数据通信时,控制位于第一主机的通信一方的ros节点,与第二主机建立连接,通过该连接将数据通信请求发送至第二主机;利用第二主机中的ros主控接收并处理数据通信请求,在第二主机上查找到共享内存,实现数据写入或读取。

因为共享内存位于第二主机,位于第一主机的通信一方的ros节点要访问第二主机的共享内存,需要与第二主机建立连接,以便发送数据通信请求。当第二主机的ros主控接收到数据通信请求时,根据数据通信请求,确定相应的共享内存,实现位于第一主机的通信一方的ros节点对第二主机上的共享内存中的数据的写入或读取。

具体地,图4所示的控制单元430,适于控制位于第一主机的通信一方的ros节点通过publish函数发布数据,与第二主机建立连接;以及,控制第二主机中的ros主控通过调用xmlrpc函数,接收位于第一主机的通信一方的ros节点发布的数据。

在ros系统中,每个节点相当于一个独立的进程,现有技术中的通信方式是调用publish()函数将数据发送给其他节点,其他节点调用subscribe()来监听数据。本实施例中,位于第一主机的通信一方的ros节点通过publish函数发布数据后,直接调用shmget函数把数据写入共享内存中,其他节点需要数据时直接访问共享内存即可。

在一个具体的例子中,不同主机间的ros节点通信时,首先,创建共享内存,在主机1上的节点a与主机2建立连接,通过该连接将创建请求发送至第二主机,利用第二主机中的ros主控接收并处理创建请求,在第二主机上创建共享内存。然后,为共享内存加互斥锁,先初始化互斥锁,再将互斥量保存在共享内存中。将节点a的数据传输到共享内次所在的主机2,并写入共享内存。节点a通过publish发布器将数据发布出去,然后主机2的rosmaster中的xmlrpc将会接收到节点a发布的数据,然后根据指定的key将数据写入这块共享内存里面。节点b通过shmat(intkey)将共享内存连接到当前节点的地址空间,就可以进行内存的读取。

在本发明的一个实施例中,图4所示的设置单元410,适于为每对ros节点设置指示通信状态的互斥量。

创建单元420,适于在创建共享内存时,利用相应互斥量为每一个共享内存设置互斥锁。

控制单元430,适于在进行数据通信时,当一个ros节点向共享内存中写入/读取数据时,控制互斥锁指示处于通信状态,直至写入/读取操作完毕;以及,当互斥锁指示处于通信状态时,拒绝另一ros节点对该互斥锁对应的共享内存进行写入/读取操作。

多个节点同时访问一个共享内存,需要同步机制,例如通过互斥锁或者信号量的方式实现。本实施例中,通过互斥锁的方式实现。具体是,为每对ros节点设置指示通信状态的互斥量。在创建共享内存时,首先初始化互斥锁,优选地,可以使用系统提供的pthread_mutex_init()函数完成初始化,并设置相关属性;然后对互斥量进行上锁,为了让不同的节点得到同一个互斥锁,本实施例中,将互斥量保存在共享内存中,在初始化该互斥锁的时候,设置为进程间共享,这两不同的节点连接到共享内存后就可以获得这个互斥锁。

在本发明的一个实施例中,图4所示的创建单元420,适于利用下述方式生成创建请求:利用内存标识符、待创建内存的容量大小,调用ros系统中的shmget函数,生成创建请求。

控制单元430,适于当发起数据通信时,控制通信一方的ros节点,通过内存标识符调用具有相同内存标识符的shmget函数,实现向共享内存中写入数据;以及,控制通信另一方的ros节点,通过内存标识符调用具有相同内存标识符的shmget函数,实现读取共享内存中的数据。

在进行共享内存创建时,使用系统提供的shmget函数实现,具体是intshmget(key_tkey,size_tsize,intshmflg),其中,key代表内存标识符,size代表内存的大小,shmflg代表权限。

同样的,当不同的节点要访问共享内存时,控制单元430调用intshmger(key_tkey,size_tsize,intshmflg)可以实现共享内存的访问。如果不同的节点使用的key的值相同,即是访问同一共享内存。

在本发明的一个实施例中,图4所示的创建单元420,适于采用shimd_kernel数据结构在ros系统中描述共享内存,通过该数据结构中的相应属性,记录进程对内存的使用状况并将创建的内存与相应进程进行关联。

每一个新创建的共享内存都用一个shmid_kernel数据结构来表达。系统中所有的shmid_kernel数据结构都保存在shmid_segs向量表中,该向量表的每一个元素都是一个指向shmid_kernel数据结构的指针。

具体地,数据结构shmid_kernel的定义如下:

structshmid_kernel

{

structshmid_dsu;

unsignedlongshm_npages;

unsignedlong*shm_pages;

structvm_area_struct*attaches;

}

其中,shmid_ds描述了共享内存的认证信息,字节大小,最后一次粘附时间、分离时间、改变时间,创建该共享内存的用户进程,最后一次对它操作的进程,当前有多少个用户进程在使用它等信息。

shm_pages代表该共享内存对象的所占据的内存页面数组,数组里面的每个元素当然是每个内存页面的起始地址。

shm_npages则是该共享内存对象占用内存页面的个数,以页为单位。

attaches描述被共享的共享内存所关联的各进程的虚拟地址空间,即内存映射。

这里的内存映射是将设备或者硬盘存储一块空间映射到物理内存,然后操作这块物理内存就是在操作实际的硬盘空间,不需要经过内核传递。在ros系统中,上述的进程即是ros节点。

ros节点都有自己私有的虚拟地址空间,可以防止其它节点修改其数据。但是,许多节点都有相同的只读文本区域,例如内核代码,数据等。如果每个节点运行时都拷贝一份,那就是造成浪费。因此,内存映射正好解决了这个问题,当一个节点将一个共享内存映射到它的虚拟存储器的一个区域时,那么这个节点对这个区域的任何写操作,对于其它把这个共享内存也映射到自己的虚拟存储器也是可见的。

在本技术方案中,每一个要共享这个共享内存的ros节点都必须通过ros系统调用将共享内存映射(attach)到ros节点的虚拟地址空间中。当共享内存创建后,将共享内存关联到ros系统的两个ros节点的虚拟地址空间。

现有技术中,两个ros节点是通过nodehandle的publish和subscribe函数进行通信。而在本技术方案中,如图3所示,通过ros系统分别把两个ros节点的虚拟地址空间与共享内存进行映射,具体的映射步骤如下:

1)根据指定的key找到相应的共享内存。

2)如果用户没有指定与该共享内存映射的ros节点虚拟地址空间的位置,则由ros系统在ros节点的虚拟地址空间请求一块区域,与共享内存映射。

3)请求一块内存用于建立数据结构。

4)检查共享内存在ros节点的虚拟地址空间的映射区,将其加入到共享内存的队列中。

装置实施例中各模块的其他功能参照方法实施例中的相应功能,在此不再赘述。

图5示出了根据本发明一个实施例的电子设备的结构示意图。该电子设备500传统上包括处理器510和被安排成存储计算机可执行指令(程序代码)的存储器520。存储器520可以是诸如闪存、eeprom(电可擦除可编程只读存储器)、eprom、硬盘或者rom之类的电子存储器。存储器520具有存储用于执行图1所示的以及各实施例中的任何方法步骤的程序代码540的存储空间530。例如,用于程序代码的存储空间530可以包括分别用于实现上面的方法中的各种步骤的各个程序代码540。这些程序代码可以从一个或者多个计算机程序产品中读出或者写入到这一个或者多个计算机程序产品中。这些计算机程序产品包括诸如硬盘,紧致盘(cd)、存储卡或者软盘之类的程序代码载体。这样的计算机程序产品通常为例如图6所述的计算机可读存储介质600。该计算机可读存储介质600可以具有与图5的电子设备中的存储器520类似布置的存储段、存储空间等。程序代码可以例如以适当形式进行压缩。通常,存储单元存储有用于执行根据本发明的方法步骤的程序代码610,即可以由诸如510之类的处理器读取的程序代码,当这些程序代码由电子设备运行时,导致该电子设备执行上面所描述的方法中的各个步骤。

需要说明的是,图5所示的电子设备和图6所示的计算机可读存储介质的各实施例与图1所示的方法的各实施例对应相同,上文已有详细说明,在此不再赘述。

综上所述,鉴于现有的ros通信机制是基于tcp/ip,数据传输量小,传输速度慢。本发明的技术方案,适用于同一台主机的两个ros节点,也适用于不同主机中的两个ros节点,且无需重构ros的通信方式,依然采用主控方式,并充分利用现有资源,保留了tcp/ip的同时,方便主机和从机的通信;基于共享内存机制,进行通信的ros节点可以直接对共享内存进行读写,能够提高ros系统中个ros节点之间的通信效率,减少计算机资源的消耗,并提高了程序的安全性,对通信效率要求较高的领域(如无人车、无人机)具有重要意义。

以上所述,仅为本发明的具体实施方式,在本发明的上述教导下,本领域技术人员可以在上述实施例的基础上进行其他的改进或变形。本领域技术人员应该明白,上述的具体描述只是更好的解释本发明的目的,本发明的保护范围应以权利要求的保护范围为准。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1