Creating new proof-of-concept experimental package bagfs.
This commit is contained in:
parent
0ec6214592
commit
055d2fddad
|
@ -54,6 +54,9 @@ python-numpy:
|
|||
rhel: python-numpy
|
||||
arch: python-numpy
|
||||
macports: py25-numpy
|
||||
python-fuse:
|
||||
ubuntu: python-fuse
|
||||
debian: python-fuse
|
||||
python-scipy:
|
||||
ubuntu: python-scipy
|
||||
debian: python-scipy
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
cmake_minimum_required(VERSION 2.4.6)
|
||||
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
|
||||
|
||||
# Set the build type. Options are:
|
||||
# Coverage : w/ debug symbols, w/o optimization, w/ code-coverage
|
||||
# Debug : w/ debug symbols, w/o optimization
|
||||
# Release : w/o debug symbols, w/ optimization
|
||||
# RelWithDebInfo : w/ debug symbols, w/ optimization
|
||||
# MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries
|
||||
#set(ROS_BUILD_TYPE RelWithDebInfo)
|
||||
|
||||
rosbuild_init()
|
||||
|
||||
#set the default path for built executables to the "bin" directory
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
||||
#set the default path for built libraries to the "lib" directory
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
|
||||
|
||||
#uncomment if you have defined messages
|
||||
#rosbuild_genmsg()
|
||||
#uncomment if you have defined services
|
||||
#rosbuild_gensrv()
|
||||
|
||||
#common commands for building c++ executables and libraries
|
||||
#rosbuild_add_library(${PROJECT_NAME} src/example.cpp)
|
||||
#target_link_libraries(${PROJECT_NAME} another_library)
|
||||
#rosbuild_add_boost_directories()
|
||||
#rosbuild_link_boost(${PROJECT_NAME} thread)
|
||||
#rosbuild_add_executable(example examples/example.cpp)
|
||||
#target_link_libraries(example ${PROJECT_NAME})
|
|
@ -0,0 +1 @@
|
|||
include $(shell rospack find mk)/cmake.mk
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
\mainpage
|
||||
\htmlinclude manifest.html
|
||||
|
||||
\b bagfs is ...
|
||||
|
||||
<!--
|
||||
In addition to providing an overview of your package,
|
||||
this is the section where the specification and design/architecture
|
||||
should be detailed. While the original specification may be done on the
|
||||
wiki, it should be transferred here once your package starts to take shape.
|
||||
You can then link to this documentation page from the Wiki.
|
||||
-->
|
||||
|
||||
|
||||
\section codeapi Code API
|
||||
|
||||
<!--
|
||||
Provide links to specific auto-generated API documentation within your
|
||||
package that is of particular interest to a reader. Doxygen will
|
||||
document pretty much every part of your code, so do your best here to
|
||||
point the reader to the actual API.
|
||||
|
||||
If your codebase is fairly large or has different sets of APIs, you
|
||||
should use the doxygen 'group' tag to keep these APIs together. For
|
||||
example, the roscpp documentation has 'libros' group.
|
||||
-->
|
||||
|
||||
|
||||
*/
|
|
@ -0,0 +1,19 @@
|
|||
<package>
|
||||
<description brief="bagfs">
|
||||
Experimental package to create a filesystem representation of a bagfile.
|
||||
</description>
|
||||
<author>Jeremy Leibs</author>
|
||||
<license>BSD</license>
|
||||
<review status="unreviewed" notes=""/>
|
||||
<url>http://ros.org/wiki/bagfs</url>
|
||||
|
||||
<depend package="rospy"/>
|
||||
<depend package="roslib"/>
|
||||
<depend package="std_msgs"/>
|
||||
<depend package="rosrecord"/>
|
||||
|
||||
<!-- We use fuse to create the filesystem -->
|
||||
<rosdep name="python-fuse"/>
|
||||
</package>
|
||||
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
PKG = 'bagfs'
|
||||
import roslib; roslib.load_manifest(PKG)
|
||||
import rospy
|
||||
import rosrecord
|
||||
|
||||
import os, stat, errno, sys
|
||||
import fuse
|
||||
import subprocess
|
||||
from fuse import Fuse
|
||||
from time import time
|
||||
|
||||
fuse.fuse_python_api = (0, 2)
|
||||
|
||||
class MyStat(fuse.Stat):
|
||||
def __init__(self):
|
||||
self.st_mode = 0
|
||||
self.st_ino = 0
|
||||
self.st_dev = 0
|
||||
self.st_nlink = 0
|
||||
self.st_uid = 0
|
||||
self.st_gid = 0
|
||||
self.st_size = 0
|
||||
self.st_atime = 0
|
||||
self.st_mtime = 0
|
||||
self.st_ctime = 0
|
||||
|
||||
|
||||
class BagFS(Fuse):
|
||||
|
||||
def __init__(self, bag, version, usage, dash_s_do):
|
||||
Fuse.__init__(self, version=version, usage=usage, dash_s_do=dash_s_do)
|
||||
self.msgs = {}
|
||||
self.sizecache = {}
|
||||
for i,(topic, msg, t) in enumerate(rosrecord.logplayer(bag, raw=True)):
|
||||
cdir = self.msgs
|
||||
for ns in topic.lstrip('/').split('/'):
|
||||
if not ns in cdir:
|
||||
self.msgs[ns] = {}
|
||||
cdir=cdir[ns]
|
||||
cdir["%.6d"%i] = (topic,msg,t)
|
||||
|
||||
def lookup(self, path):
|
||||
cdir = self.msgs
|
||||
if path == '/':
|
||||
return cdir
|
||||
p = path.split('/')
|
||||
p.remove('')
|
||||
for ns in p[:-1]:
|
||||
if ns in cdir and isinstance(cdir[ns], dict):
|
||||
cdir=cdir[ns]
|
||||
else:
|
||||
return None
|
||||
if p[-1] in cdir:
|
||||
return cdir[p[-1]]
|
||||
else:
|
||||
return None
|
||||
|
||||
def getattr(self, path):
|
||||
st = MyStat()
|
||||
st.st_atime = int(time())
|
||||
st.st_mtime = st.st_atime
|
||||
st.st_ctime = st.st_atime
|
||||
|
||||
fil = self.lookup(path)
|
||||
if fil is None:
|
||||
return -errno.ENOENT
|
||||
elif isinstance(fil, dict):
|
||||
st.st_mode = stat.S_IFDIR | 0755
|
||||
st.st_nlink = len(fil)
|
||||
else:
|
||||
st.st_mode = stat.S_IFREG | 0444
|
||||
st.st_nlink = 1
|
||||
st.st_mtime = int(fil[2].to_sec())
|
||||
st.st_ctime = st.st_mtime
|
||||
|
||||
if path in self.sizecache:
|
||||
st.st_size = self.sizecache[path]
|
||||
else:
|
||||
st.st_size = 1
|
||||
|
||||
return st
|
||||
|
||||
def readdir(self, path, offset):
|
||||
yield fuse.Direntry('.')
|
||||
yield fuse.Direntry('..')
|
||||
|
||||
dir = self.lookup(path)
|
||||
|
||||
for leaf in dir:
|
||||
yield fuse.Direntry(leaf)
|
||||
|
||||
def open(self, path, flags):
|
||||
msg = self.lookup(path)
|
||||
accmode = os.O_RDONLY
|
||||
if (flags & accmode) != os.O_RDONLY:
|
||||
return -errno.EACCES
|
||||
|
||||
m = msg[1][4]()
|
||||
m.deserialize(msg[1][1])
|
||||
|
||||
disp = roslib.message.strify_message(m) + '\n'
|
||||
self.sizecache[path] = len(disp)
|
||||
|
||||
return disp
|
||||
|
||||
def read(self, path, size, offset, fh):
|
||||
return fh[offset:offset+size]
|
||||
|
||||
|
||||
def main():
|
||||
usage="""
|
||||
Userspace script runner
|
||||
""" + Fuse.fusage
|
||||
bag = sys.argv[1]
|
||||
server = BagFS(bag, version="%prog " + fuse.__version__,
|
||||
usage=usage,
|
||||
dash_s_do='setsingle')
|
||||
|
||||
server.parse(errex=1)
|
||||
server.main()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue