summaryrefslogtreecommitdiff
path: root/i
diff options
context:
space:
mode:
authorbecquet2007-05-10 18:49:20 +0000
committerbecquet2007-05-10 18:49:20 +0000
commit8f486613be58ced269db1d437e560c16558604e8 (patch)
tree41e94b2122a118cb06abf6fc2a0038cd1dfbec4a /i
parent4daa2c76c2a028e4b2c8ab379e7d1e0f535a0a31 (diff)
Création de chuck, le programme du robot 2007.
Diffstat (limited to 'i')
-rw-r--r--i/chuck/build/Makefile2
l---------i/chuck/build/rc1
l---------i/chuck/build/update.sh1
-rw-r--r--i/chuck/doc/Doxyfile938
-rw-r--r--i/chuck/runtime/rc/config100
-rw-r--r--i/chuck/src/Makefile.defs112
-rw-r--r--i/chuck/src/README25
-rw-r--r--i/chuck/src/ai/Makefile.defs5
-rw-r--r--i/chuck/src/ai/ai.cc511
-rw-r--r--i/chuck/src/ai/ai.hh86
-rw-r--r--i/chuck/src/ai/test_ai.cc105
-rw-r--r--i/chuck/src/asserv/Makefile.defs5
-rw-r--r--i/chuck/src/asserv/asserv.cc387
-rw-r--r--i/chuck/src/asserv/asserv.hh141
-rw-r--r--i/chuck/src/asserv/test_asserv.cc197
-rw-r--r--i/chuck/src/config/Makefile.defs5
-rw-r--r--i/chuck/src/config/config.cc27
-rw-r--r--i/chuck/src/config/config.hh98
-rw-r--r--i/chuck/src/config/config_data.cc148
-rw-r--r--i/chuck/src/config/config_data.hh68
-rw-r--r--i/chuck/src/config/config_data.tcc59
-rw-r--r--i/chuck/src/config/test_config.cc48
-rw-r--r--i/chuck/src/data/Makefile.defs16
-rw-r--r--i/chuck/src/data/data_buffer.cc130
-rw-r--r--i/chuck/src/data/data_buffer.hh83
-rw-r--r--i/chuck/src/data/data_circular_buffer.cc123
-rw-r--r--i/chuck/src/data/data_circular_buffer.hh64
-rw-r--r--i/chuck/src/data/data_input.cc37
-rw-r--r--i/chuck/src/data/data_input.hh44
-rw-r--r--i/chuck/src/data/data_input_file.cc46
-rw-r--r--i/chuck/src/data/data_input_file.hh45
-rw-r--r--i/chuck/src/data/data_input_zlib.cc84
-rw-r--r--i/chuck/src/data/data_input_zlib.hh48
-rw-r--r--i/chuck/src/data/data_output.cc34
-rw-r--r--i/chuck/src/data/data_output.hh44
-rw-r--r--i/chuck/src/data/test_data.cc56
-rw-r--r--i/chuck/src/data/test_data_buffer.cc77
-rw-r--r--i/chuck/src/data/test_data_circular_buffer.cc92
-rw-r--r--i/chuck/src/es/Makefile.defs5
-rw-r--r--i/chuck/src/es/es.cc752
-rw-r--r--i/chuck/src/es/es.hh207
-rw-r--r--i/chuck/src/es/test_es.cc156
-rw-r--r--i/chuck/src/interpreter/Makefile.defs6
-rw-r--r--i/chuck/src/interpreter/interpreter.cc127
-rw-r--r--i/chuck/src/interpreter/interpreter.hh90
-rw-r--r--i/chuck/src/interpreter/interpreter.tcc142
-rw-r--r--i/chuck/src/interpreter/interpreter_parser.cc43
-rw-r--r--i/chuck/src/interpreter/interpreter_parser.hh43
-rw-r--r--i/chuck/src/interpreter/test_interpreter.cc139
-rw-r--r--i/chuck/src/log/Makefile.defs12
-rw-r--r--i/chuck/src/log/data_circular_buffer_factory.cc72
-rw-r--r--i/chuck/src/log/data_circular_buffer_factory.hh53
-rw-r--r--i/chuck/src/log/log.cc130
-rw-r--r--i/chuck/src/log/log.hh82
-rw-r--r--i/chuck/src/log/log_message.cc74
-rw-r--r--i/chuck/src/log/log_message.hh55
-rw-r--r--i/chuck/src/log/log_message.tcc36
-rw-r--r--i/chuck/src/log/log_server.cc54
-rw-r--r--i/chuck/src/log/log_server.hh50
-rw-r--r--i/chuck/src/log/logger.cc52
-rw-r--r--i/chuck/src/log/logger.hh68
-rw-r--r--i/chuck/src/log/logger_file.cc144
-rw-r--r--i/chuck/src/log/logger_file.hh70
-rw-r--r--i/chuck/src/log/logger_null.hh51
-rw-r--r--i/chuck/src/log/logger_ram.cc98
-rw-r--r--i/chuck/src/log/logger_ram.hh63
-rw-r--r--i/chuck/src/log/logger_stdout.cc68
-rw-r--r--i/chuck/src/log/logger_stdout.hh54
-rw-r--r--i/chuck/src/log/test_log.cc53
-rw-r--r--i/chuck/src/log/test_log_server.cc45
-rw-r--r--i/chuck/src/motor/Makefile.defs5
-rw-r--r--i/chuck/src/motor/motor.cc183
-rw-r--r--i/chuck/src/motor/motor.hh86
-rw-r--r--i/chuck/src/motor/test_motor.cc99
-rw-r--r--i/chuck/src/parser/Makefile.defs14
-rw-r--r--i/chuck/src/parser/parser.cc189
-rw-r--r--i/chuck/src/parser/parser.hh89
-rw-r--r--i/chuck/src/parser/test_parser.cc86
-rw-r--r--i/chuck/src/parser/yylexer.ll148
-rw-r--r--i/chuck/src/parser/yyparser.yy278
-rw-r--r--i/chuck/src/proto/Makefile.defs5
-rw-r--r--i/chuck/src/proto/proto.cc457
-rw-r--r--i/chuck/src/proto/proto.hh140
-rw-r--r--i/chuck/src/proto/test_proto.cc96
-rw-r--r--i/chuck/src/scheduler/Makefile.defs7
-rw-r--r--i/chuck/src/scheduler/schedulable.hh50
-rw-r--r--i/chuck/src/scheduler/schedulable_alarm.cc56
-rw-r--r--i/chuck/src/scheduler/schedulable_alarm.hh60
-rw-r--r--i/chuck/src/scheduler/schedulable_read_fd.cc51
-rw-r--r--i/chuck/src/scheduler/schedulable_read_fd.hh52
-rw-r--r--i/chuck/src/scheduler/scheduler.cc103
-rw-r--r--i/chuck/src/scheduler/scheduler.hh53
-rw-r--r--i/chuck/src/scheduler/test_scheduler.cc68
-rw-r--r--i/chuck/src/serial/Makefile.defs5
-rw-r--r--i/chuck/src/serial/serial.cc66
-rw-r--r--i/chuck/src/serial/serial.hh64
-rw-r--r--i/chuck/src/serial/serial_base.cc84
-rw-r--r--i/chuck/src/serial/serial_base.hh68
-rw-r--r--i/chuck/src/serial/serial_dev.cc168
-rw-r--r--i/chuck/src/serial/serial_dev.hh54
-rw-r--r--i/chuck/src/serial/serial_stdio.cc81
-rw-r--r--i/chuck/src/serial/serial_stdio.hh48
-rw-r--r--i/chuck/src/serial/test_serial.cc88
-rw-r--r--i/chuck/src/socket/Makefile.defs12
-rw-r--r--i/chuck/src/socket/address.cc93
-rw-r--r--i/chuck/src/socket/address.hh76
-rw-r--r--i/chuck/src/socket/server_socket.cc86
-rw-r--r--i/chuck/src/socket/server_socket.hh48
-rw-r--r--i/chuck/src/socket/socket_client.cc115
-rw-r--r--i/chuck/src/socket/socket_client.hh63
-rw-r--r--i/chuck/src/socket/socket_databuffer.cc97
-rw-r--r--i/chuck/src/socket/socket_databuffer.hh52
-rw-r--r--i/chuck/src/socket/socket_server.cc90
-rw-r--r--i/chuck/src/socket/socket_server.hh56
-rw-r--r--i/chuck/src/socket/socket_text.cc236
-rw-r--r--i/chuck/src/socket/socket_text.hh80
-rw-r--r--i/chuck/src/socket/test_server.cc91
-rw-r--r--i/chuck/src/socket/test_socket.cc156
-rw-r--r--i/chuck/src/socket/test_socket_databuffer.cc125
-rw-r--r--i/chuck/src/socket/test_socket_old.cc76
-rw-r--r--i/chuck/src/tester/Makefile.defs5
-rw-r--r--i/chuck/src/tester/test_tester.cc78
-rw-r--r--i/chuck/src/tester/tester.cc141
-rw-r--r--i/chuck/src/tester/tester.hh77
-rw-r--r--i/chuck/src/timer/Makefile.defs5
-rw-r--r--i/chuck/src/timer/test_timer.cc47
-rw-r--r--i/chuck/src/timer/timer.cc89
-rw-r--r--i/chuck/src/timer/timer.hh51
-rw-r--r--i/chuck/src/utils/Makefile.defs11
-rw-r--r--i/chuck/src/utils/any.hh125
-rw-r--r--i/chuck/src/utils/any.tcc185
-rw-r--r--i/chuck/src/utils/bind.hh91
-rw-r--r--i/chuck/src/utils/callback.hh96
-rw-r--r--i/chuck/src/utils/callback.tcc140
-rw-r--r--i/chuck/src/utils/errno_exception.hh48
-rw-r--r--i/chuck/src/utils/fd_set.cc53
-rw-r--r--i/chuck/src/utils/fd_set.hh54
-rw-r--r--i/chuck/src/utils/hexa.cc113
-rw-r--r--i/chuck/src/utils/hexa.hh49
-rw-r--r--i/chuck/src/utils/list_ostream_output.hh62
-rw-r--r--i/chuck/src/utils/mathutil.hh57
-rw-r--r--i/chuck/src/utils/meta/Makefile.defs3
-rw-r--r--i/chuck/src/utils/meta/is_equal.hh44
-rw-r--r--i/chuck/src/utils/meta/is_string.hh45
-rw-r--r--i/chuck/src/utils/meta/remove_reference.hh44
-rw-r--r--i/chuck/src/utils/meta/test_meta.cc57
-rw-r--r--i/chuck/src/utils/non_copyable.hh41
-rw-r--r--i/chuck/src/utils/signalhandler.hh52
-rw-r--r--i/chuck/src/utils/signalhandler.tcc66
-rw-r--r--i/chuck/src/utils/test_any.cc50
-rw-r--r--i/chuck/src/utils/test_bind.cc57
-rw-r--r--i/chuck/src/utils/test_callback.cc84
-rw-r--r--i/chuck/src/utils/test_signalhandler.cc15
153 files changed, 13974 insertions, 0 deletions
diff --git a/i/chuck/build/Makefile b/i/chuck/build/Makefile
new file mode 100644
index 0000000..0ab6550
--- /dev/null
+++ b/i/chuck/build/Makefile
@@ -0,0 +1,2 @@
+SRCDIR = ../src
+include $(SRCDIR)/Makefile.defs
diff --git a/i/chuck/build/rc b/i/chuck/build/rc
new file mode 120000
index 0000000..113a1cb
--- /dev/null
+++ b/i/chuck/build/rc
@@ -0,0 +1 @@
+../runtime/rc \ No newline at end of file
diff --git a/i/chuck/build/update.sh b/i/chuck/build/update.sh
new file mode 120000
index 0000000..f574d8e
--- /dev/null
+++ b/i/chuck/build/update.sh
@@ -0,0 +1 @@
+../../pc104/initrd/update.sh \ No newline at end of file
diff --git a/i/chuck/doc/Doxyfile b/i/chuck/doc/Doxyfile
new file mode 100644
index 0000000..b1168f1
--- /dev/null
+++ b/i/chuck/doc/Doxyfile
@@ -0,0 +1,938 @@
+# Doxyfile 1.2.15
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = marvin
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French,
+# German, Greek, Hungarian, Italian, Japanese, Korean, Norwegian, Polish,
+# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish.
+
+OUTPUT_LANGUAGE = French
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these class will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH =
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower case letters. If set to YES upper case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = YES
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consist of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = ../src
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse.
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the Html help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+,
+# or Internet explorer 4.0+). Note that for large projects the tree generation
+# can take a very long time. In such cases it is better to disable this feature.
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimised for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assigments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_XML = NO
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line and do not end with a semicolon. Such function macros are typically
+# used for boiler-plate code, and will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yield more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermedate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
+
+# The CGI_NAME tag should be the name of the CGI script that
+# starts the search engine (doxysearch) with the correct parameters.
+# A script with this name will be generated by doxygen.
+
+CGI_NAME = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the
+# cgi binaries are located. See the documentation of your http daemon for
+# details.
+
+CGI_URL =
+
+# The DOC_URL tag should be the absolute URL to the directory where the
+# documentation is located. If left blank the absolute path to the
+# documentation, with file:// prepended to it, will be used.
+
+DOC_URL =
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the
+# documentation is located. If left blank the directory on the local machine
+# will be used.
+
+DOC_ABSPATH =
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
+# is installed.
+
+BIN_ABSPATH = /usr/local/bin/
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to
+# documentation generated for other projects. This allows doxysearch to search
+# the documentation for these projects as well.
+
+EXT_DOC_PATHS =
diff --git a/i/chuck/runtime/rc/config b/i/chuck/runtime/rc/config
new file mode 100644
index 0000000..d7eb03f
--- /dev/null
+++ b/i/chuck/runtime/rc/config
@@ -0,0 +1,100 @@
+### Asserv.
+asserv.tty = "/dev/ttyS0"
+asserv.footing = 20841
+asserv.t_accel = 512
+asserv.a_accel = 1024
+asserv.t_max_speed = 64
+asserv.a_max_speed = 64
+asserv.t_max_speed_slow = 8
+asserv.a_max_speed_slow = 8
+asserv.tkp = 100
+asserv.tki = 3
+asserv.tkd = 0
+asserv.akp = 550
+asserv.aki = 7
+asserv.akd = 0
+asserv.esat = 1023
+asserv.isat = 3072
+asserv.l_invert_pwm = true
+asserv.r_invert_pwm = false
+asserv.step_per_mm = 75.78789091394133410940
+# Stats.
+asserv.pos_report = 10
+asserv.in_port_report = 0
+asserv.counter_stat = 0
+asserv.speed_stat = 0
+asserv.pos_stat = 0
+asserv.pwm_stat = 0
+asserv.timer_stat = 0
+
+### ES
+es.tty = "/dev/ttyS1"
+# Frequency of ack when something important happened
+es.ack_freq = 10
+# Frequency of main stats
+es.main_stat = 0
+# Max false input capture before the sensor is ready for a real capture
+es.rvb_sensors_false_ic = 3
+# Max overflow of the TC1 before though the sensor is dead
+es.rvb_sensors_max_ov = 250
+# Ratio for the algorithm that choose if the color is green or not
+es.rvb_sniff_ref_ratio = 3
+# Limits for the algorithm of choosing between a black or white ball
+es.rvb_sniff_green_limit = 4300
+es.rvb_sniff_clear_limit = 4300
+# Stats of RVB Sensor raw data
+es.rvb_sensor_mask_stat = 0xFFFF
+es.rvb_sensor_stat = 0
+# Stats of RVB Sniff data
+es.rvb_sniff_mask_stat = 0xFFFF
+es.rvb_sniff_stat = 0
+# Stats of RVB Ball data
+es.rvb_ball_stat = 0
+# Stats of others module (jack + colour selection)
+es.others_stat = 0
+# Stats for printing out key pressed onto the LCD keyboard
+es.lcd_key_stat = 0
+# Print stat of front sensors
+es.rvb_sniff_front_stat = 0
+# Threshold of front sensors at the bottom
+es.threshold_front_sensors = 4
+# Threshold of ball sensors
+es.threshold_ball_sensors = 4
+# Threshold of hole sensor
+es.threshold_hole_sensors = 4
+
+### Artificial Intelligency !
+# Time of match in milliseconds !
+ai.round_duration = 90000
+# Max time to wait before release hand if nothing happened on serial (ms).
+ai.schedule_time = 100
+# Reference which sensor at boot time
+# 127 for the only the lower ones
+ai.ref_sensor_mask = 127
+
+### Log
+# Default minimum level outputed
+# log.level.default = "debug"
+# Can be specialized for a specific module
+# For example, with the module asserv
+# log.level.asserv = "debug"
+# The same for the logger used to log
+# Possible values are :
+# - null : no log, optimized for time ;
+# - stdout : to stdout ;
+# - file:/path/filename : to a file ;
+# - ram : in a circular buffer for getting it at the end of the program by
+# network.
+# log.logger.default = "ram"
+# log.logger.asserv = "null"
+log.logger.default = "stdout"
+log.level.default = "debug"
+log.logger.proto = "null"
+
+### Exemples
+foo = "toto"
+ bar = ("a" "b" "c")
+foobar = (4 5 6 7 8)
+
+# TestProto
+#testProto.tty = "/home/nicolas/robotSVN/n/asserv/src/asserv/uart0.pts"
diff --git a/i/chuck/src/Makefile.defs b/i/chuck/src/Makefile.defs
new file mode 100644
index 0000000..aa882b7
--- /dev/null
+++ b/i/chuck/src/Makefile.defs
@@ -0,0 +1,112 @@
+# Flags.
+CXXFLAGS = -Wall -g
+CPPFLAGS = -MMD $(INCLUDES)
+INCLUDES = -I$(SRCDIR) -I.
+
+# Tests de coverage (man gcov).
+ifeq ($(COV),)
+CXXFLAGS += -O2
+else
+CXXFLAGS += -fprofile-arcs -ftest-coverage
+endif
+
+# Profiling (man gprof).
+ifneq ($(PROF),)
+CXXFLAGS += -pg
+LDFLAGS += -pg
+endif
+
+# Messages sur une ligne.
+CXXFLAGS += -fmessage-length=0
+
+SUBDIRS = utils utils/meta \
+ parser \
+ interpreter config tester \
+ log serial timer \
+ data scheduler \
+ proto asserv es \
+ motor socket ai
+
+# Répertoire où placer les objets.
+OBJ_DIR := obj
+
+
+# Utilise le compilateur C++ pour l'édition des liens.
+LINK.o = $(CXX) $(LDFLAGS) $(TARGET_ARCH)
+# Et les outils GNU pour lex et yacc.
+LEX := flex
+YACC := bison
+
+# Où trouver les sources, apdmc.
+vpath %.cc $(SUBDIRS:%=$(SRCDIR)/%) $(EXTRA_SUBDIRS)
+vpath %.ll $(SUBDIRS:%=$(SRCDIR)/%) $(EXTRA_SUBDIRS)
+vpath %.yy $(SUBDIRS:%=$(SRCDIR)/%) $(EXTRA_SUBDIRS)
+
+# régle par défault. Le build-all permet de reporter à plus tard sa
+# définition.
+all: build-all
+
+# Inclus les autres répertoires.
+include $(SUBDIRS:%=$(SRCDIR)/%/Makefile.defs) \
+ $(EXTRA_SUBDIRS:%=%/Makefile.defs)
+
+OBJECTS := $(filter %.o,$(foreach PROGRAM,$(PROGRAMS),$($(PROGRAM)_OBJECTS)))
+OBJECTS := $(OBJECTS:%.o=$(OBJ_DIR)/%.o)
+
+build-all: $(PROGRAMS)
+
+utest: $(UTESTS:%=%.utest)
+
+# Fabrique les règles pour créer les exécutables.
+define PROGRAMS_template
+$(1): $$($(1)_OBJECTS:%.o=$$(OBJ_DIR)/%.o)
+ $$(LINK.o) $$^ $$(LOADLIBES) $$(LDLIBS) -o $$@
+endef
+
+$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAMS_template,$(prog))))
+
+# Creation of utest rules
+define UTESTS_template
+ifndef $(1)_UTEST
+$(1)_UTEST = PATH=$$(PATH):. $$^
+endif
+$(1).utest:
+ @echo "$$($(1)_UTEST)"; \
+ $$($(1)_UTEST); \
+ RETVAL=$$$$?; \
+ echo -n "$(1).utest: "; \
+ if [ "$$$$RETVAL" -eq "0" ]; \
+ then \
+ echo "Succeed"; \
+ else \
+ echo "Failed"; \
+ fi; \
+ exit $$$$RETVAL
+endef
+
+$(foreach utest,$(UTESTS),$(eval $(call UTESTS_template,$(utest))))
+
+# Régles implicites.
+%.cc: %.ll
+ $(LEX) $<
+
+%.cc: %.yy
+ $(YACC) -o $@ $<
+
+$(OBJ_DIR)/%.o: %.cc
+ @mkdir -p $(OBJ_DIR)
+ $(COMPILE.cc) $(OUTPUT_OPTION) $<
+
+# Dépendances.
+-include $(OBJECTS:%.o=%.d)
+
+# Ménage.
+clean:
+ rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d $(PROGRAMS)
+ rm -f *.bbg *.bb *.da *.gcov
+ rm -f gmon.out
+ rm -f $(EXTRA_CLEAN)
+ rmdir --ignore-fail-on-non-empty $(OBJ_DIR)
+
+.PHONY: all build-all clean
+.SUFFIXES:
diff --git a/i/chuck/src/README b/i/chuck/src/README
new file mode 100644
index 0000000..90d7926
--- /dev/null
+++ b/i/chuck/src/README
@@ -0,0 +1,25 @@
+marvin - programme du robot 2006.
+
+Programme du concours du robot qui envois les balle en haut... et dans les
+trous aussi.
+
+
+Copyright (C) 2006 Efrei Robotique
+
+Robot APB Team/Efrei 2006.
+ Web: http://assos.efrei.fr/robot/
+ Email: robot AT efrei DOT fr
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
diff --git a/i/chuck/src/ai/Makefile.defs b/i/chuck/src/ai/Makefile.defs
new file mode 100644
index 0000000..5016f06
--- /dev/null
+++ b/i/chuck/src/ai/Makefile.defs
@@ -0,0 +1,5 @@
+PROGRAMS += test_ai
+
+ai_OBJECTS = ai.o $(motor_OBJECTS) $(es_OBJECTS) $(scheduler_OBJECTS)
+
+test_ai_OBJECTS = test_ai.o $(ai_OBJECTS) $(tester_OBJECTS)
diff --git a/i/chuck/src/ai/ai.cc b/i/chuck/src/ai/ai.cc
new file mode 100644
index 0000000..c9be04a
--- /dev/null
+++ b/i/chuck/src/ai/ai.cc
@@ -0,0 +1,511 @@
+// AI.CC
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Haller
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~haller/
+// Email: <nicolas@boiteameuh.org>
+// }}}
+#include "ai.hh"
+#include "config/config.hh"
+#include "timer/timer.hh"
+
+#include <cmath>
+
+/// Fonction callback useless
+static void
+callback (void)
+{}
+
+//constructeur
+Ai::Ai (const Config & config)
+ :es_(config), log_ ("Ai"),
+ schedulableMotor_(callback, motor_.getFd()),
+ schedulableEs_(callback, es_.getFd()),
+ round_duration_ (config.get<int> ("ai.round_duration")),
+ schedule_time_ (config.get<int> ("ai.schedule_time")),
+ reference_sensor_mask_ (config.get<int> ("ai.ref_sensor_mask"))
+{
+ scheduler_.insert (schedulableMotor_);
+ scheduler_.insert (schedulableEs_);
+}
+
+Ai::~Ai(void)
+{
+ // On réinitialise
+ // Initialise les moteurs
+ // XXX
+ motor_.reset ();
+ // initialise la carte es
+ es_.reset ();
+ // On sync
+ do
+ {
+ scheduler_.schedule (500, true);
+ }
+ while (!sync ());
+}
+
+// Initialisation du robal
+void
+Ai::init (void)
+{
+ // Initialisation de motor
+ motor_.reset ();
+ // Initialisation de la carte Es
+ es_.reset ();
+ // Paf on sync
+ while (!update ());
+}
+
+/// Stop the mouvement of the motor
+void
+Ai::stop (void)
+{
+ motor_.stop ();
+ // XXX In fact, we should wait a little here...
+ while (!update ());
+}
+
+/// Synchronize data of under class
+bool
+Ai::sync (void)
+{
+ bool motor = motor_.sync ();
+ bool es = es_.sync ();
+ return es && motor;
+}
+
+/// Wait for something to happened
+bool
+Ai::update (void)
+{
+ /// Wait schedule_time
+ scheduler_.schedule (schedule_time_, true);
+ bool retour = sync ();
+ // On vérifie que le match n'est pas fini
+ if (Timer::getRoundTime () > round_duration_)
+ throw std::runtime_error ("End of match ! You win !");
+ return retour;
+}
+
+/// Function to wait a little but still syncing data
+void
+Ai::temporisation(int msec)
+{
+ // Get current time of process
+ int time = Timer::getProgramTime();
+ time += msec;
+ // Update until we have spend enough time
+ do
+ {
+ update();
+ }
+ while (time > Timer::getProgramTime());
+}
+
+/// Wait until jack is out (true) or in (false)
+void
+Ai::waitJack (bool out)
+{
+ do
+ {
+ update ();
+ }
+ while (es_.isJackOut () != out);
+}
+
+/// Init things for a match.
+void
+Ai::prepare (void)
+{
+ es_.lcdPrint("");
+ es_.lcdPrint("Prepa match...");
+ es_.lcdPrint("Inserer Jack");
+ es_.setOthersStat (10);
+ while (!update ());
+ // XXX We should check if the jack is not already in
+ // We first wait for the jack to be put inside
+ waitJack (false);
+ // We reference all the color
+ referenceSensors ();
+ es_.barilletInit();
+ es_.lcdPrint("Barillet pret ?");
+ es_.lcdPrint("Virer le jack !");
+ while (!update ());
+ // We first wait for the jack to be put inside
+ waitJack (true);
+ // Set actual position
+ motor_.getAsserv().setPos(0,0,0);
+ // Ok the match begin ! Go go go !
+ Timer::startRound ();
+ es_.setOthersStat (0);
+ // Shut up fucking beach !
+ es_.setOthersStat (0);
+ es_.setOthersStat (0);
+ while (!update ());
+}
+
+/// Some after after a match
+void
+Ai::afterMatch(void)
+{
+ // On attend de mettre le jack après le match
+ es_.lcdPrint("FIN DU MATCH");
+// es_.lcdPrint("Inserer jack...");
+ while (!update());
+ waitJack(false);
+ // On vide le barillet
+ es_.barilletEmpty();
+ es_.lcdPrint("Vidange barillet");
+ while (!update());
+ waitJack(true);
+ // On init les cartes histoire de
+ es_.reset();
+ motor_.reset();
+ es_.lcdPrint("Power off!!");
+ while (!update());
+}
+
+/// Reference sensors
+void
+Ai::referenceSensors (void)
+{
+ // Reference sensors
+ es_.refColor (reference_sensor_mask_);
+ // Update data
+ while (!update ());
+ // Disable capturing all sensors
+ es_.enableAllSensors (false);
+ // Update data
+ while (!update ());
+}
+
+/// programme d'homologation du robal
+void Ai::progHomoloRobal(void)
+{
+ /// On init le robal
+ prepare();
+ es_.barilletDebutLancement();
+ while (!update ());
+ temporisation (1000);
+ es_.barilletLancement();
+ while (!update ());
+ /// on avance un poil parce que le mur c'est mal
+ std::cout << "Move !" << std::endl;
+ motorMove(500, 0);
+ std::cout << "Rotate !" << std::endl;
+ motorRotate(-0.54);
+ std::cout << "Move !" << std::endl;
+ motorMove(1200, 0);
+ std::cout << "Rotate !" << std::endl;
+ motorRotate(1.40);
+ motorMove(500, 0);
+// temporisation (100);
+ std::cout << "Find hole !" << std::endl;
+ motorBasicFindHole ();
+
+ /// On tourne XXX
+/// motorRotate(-M_PI/4);
+ /// On cherche au moins une balle (sinon c'est con)
+/// motorMove(1000, 0); /// XXX Voir la distance
+ /// XXX Avancer d'une certaine facon pour choper des balles
+ /// XXX Ouais ba y'a encore ddes truc à faire là
+ /// On cherche un tru (repositionnement??)
+/// motor_.lockGoodHole();
+/// while (!update ());
+/// motor_.findHole();
+/// while (!update ());
+ /// On trouve un trou, chouette
+ /// Aspirer le trou
+ //es_.extraitBalle();
+ /// mettre une baballe
+ es_.dropWhiteBall();
+ while (!update ());
+ temporisation (3000);
+ es_.deposeBalle ();
+ while (!update ());
+ temporisation (3000);
+ motorMove(300, 0);
+
+ std::cout << "Find hole !" << std::endl;
+ motorBasicFindHole ();
+ es_.dropWhiteBall();
+ while (!update ());
+ temporisation (3000);
+ es_.deposeBalle ();
+ while (!update ());
+ temporisation (3000);
+ motorMove(300, 0);
+ /// Tourner 3 fois en chantant du Mickael Jackson
+ /// Again....
+ /// Fin du match
+ afterMatch();
+}
+
+void
+Ai::progMatch(void)
+{
+ double dummy, aStart, aEnd;
+
+ // Init of cards
+ init ();
+ /// On prépare le robot
+ prepare();
+ /// Faire des crêpes...
+ /// Init du barillet
+ es_.barilletDebutLancement();
+ while (!update ());
+ log_ ("match") << "Totem activator";
+ es_.totemActivator (true);
+ /// En avant guingamp
+ log_ ("match") << "Eloignement du bord";
+ motorMove(480,0);
+ es_.barilletLancement();
+ while (!update ());
+ /// On tourner de -90°
+ log_ ("match") << "Petite rotation de 90°";
+ motorMove(216,-216);
+ /// On dit bonjour au mur
+ log_ ("match") << "Va à l'opposé";
+ if (!motorMove (1000, 0))
+ {
+ log_ ("match") << "Un mur ! Reculons";
+ motorMove (-60, 0);
+ }
+ /// On tourne bizarrement mais de 90°
+ log_ ("match") << "On tourne à 90° en deux fois";
+ motorMove(-36,36);
+ motorMove(180, 180);
+ /// On avance un peu
+ log_ ("match") << "On avance de l'autre coté";
+ motorMove (1420, 0);
+ log_ ("match") << "On recule un peu";
+ motorMove (-150, 0);
+ log_ ("match") << "On tourne";
+ motorMove (216, 216);
+ motorMove (-150, 0);
+
+ /* Here, we are in front of all our holes */
+
+ int rotationSens = 1;
+ const double distanceMax[2] = { -1600., 200. };
+ // Force a turn back !
+ double distanceCur, remainingDist;
+ int ret;
+
+ /* Save angle */
+ motor_.getPosition (dummy, dummy, aStart);
+ do
+ {
+ log_ ("match") << "Start loop for finding holes";
+
+ // Save Y position each time
+ motor_.getPosition (dummy, distanceCur, dummy);
+
+ // Look for an hole !
+ if (rotationSens % 2)
+ remainingDist = std::abs (distanceMax[1] - distanceCur);
+ else
+ remainingDist = std::abs (distanceMax[0] - distanceCur);
+ // Protection again stupid computing
+ if (remainingDist > 0.)
+ ret = motorSmartFindHole (remainingDist);
+ else
+ // Force a turn back !
+ ret = 0;
+ switch (ret)
+ {
+ case 0:
+ // Here we should turn back in the other way
+ log_ ("match") << "Trop long, demi tour !";
+ if (rotationSens % 2)
+ motor_.move (432, -432);
+ else
+ motor_.move (432, 432);
+ rotationSens++;
+ /* Compute the new angle */
+ motor_.getPosition (dummy, dummy, aStart);
+ break;
+ case -2:
+ /// La couleur est unknown
+ log_ ("match") << "Hooooo une couleur de l'espace!!!!";
+ // break;
+ case 2:
+ case 1:
+ {
+ log_ ("match") << "Ok on a une couleur!";
+ bool retDrop;
+ //if (((ret == es_.blueColor_) && es_.isColorModeBlue () )
+ // || ((ret != es_.blueColor_) && !es_.isColorModeBlue ()))
+ if (true)
+ {
+ // If it is our colour, put a white ball,
+ log_ ("match") << "C'est notre couleur -> drop white !";
+ retDrop = es_.dropWhiteBall();
+ while (!update ());
+ if (retDrop)
+ {
+ log_ ("match") << "Tempo & depot!";
+ temporisation (3000);
+ es_.deposeBalle ();
+ temporisation (1000);
+ while (!update ());
+ }
+ }
+ else
+ {
+ // otherwise, put a black one.
+ log_ ("match") << "Pas notre couleur, drop noir!";
+ retDrop = es_.dropBlackBall();
+ while (!update ());
+ if (retDrop)
+ {
+ log_ ("match") << "Tempo & depot!";
+ temporisation (3000);
+ es_.deposeBalle ();
+ temporisation (1000);
+ while (!update ());
+ }
+ }
+ // Put ourself back in the right direction
+ motor_.getPosition (dummy, dummy, aEnd);
+ log_ ("match") << "Remise en place de l'angle : " << aStart << " end " << aEnd;
+ motor_.rotate (aStart - aEnd);
+ }
+ break;
+ default:
+ log_ ("match") << "Hooooo on a default!!!!";
+ break;
+ }
+ } while (true);
+
+ afterMatch();
+}
+
+/// Avance le robal et dit si il a finit (true) ou si il a bloqué
+bool
+Ai::motorMove (int d, int a)
+{
+ motor_.move(d, a); /// XXX Voir la distance
+ do
+ {
+ update ();
+ }
+ while (!motor_.finish ()/* && !motor_.blocked()*/);
+ if(motor_.finish())
+ return true;
+ return false;
+}
+
+void
+Ai::motorRotate (double d)
+{
+ motor_.rotate (d);
+ do
+ {
+ update ();
+ }
+ while (!motor_.finish ());
+}
+
+void
+Ai::motorBasicFindHole (void)
+{
+ motor_.findHole ();
+ do
+ {
+ update ();
+ }
+ while (!motor_.finish ());
+ es_.enableAllSensors (true);
+ es_.setRVBHoleStat (2);
+ temporisation (500);
+ log_ ("FindHole") << "We see" << es_.colorSeen (es_.holeRVB_) ;
+ es_.setRVBHoleStat (0);
+}
+
+/// Renvoie une couleur définie dans es ou -1 si on s'est mangé un mur ou 0 si
+/// distanceOut
+int
+Ai::motorSmartFindHole (double distOut)
+{
+ /// On sauvegarde la position actuelle
+ double bx, x, by, y, ba, a;
+ double dist;
+ motor_.getPosition(bx, by, ba);
+ /// on lance le robal à la recherche d'un tru
+ motor_.findHole();
+ do
+ {
+ update();
+ if (distOut != 0)
+ {
+ /// On regarde si on a pas atteint la distOut
+ motor_.getPosition(x, y, a);
+ /// XXX C'est propre ça?
+ dist = sqrt(((x - bx)*(x - bx)) + ((y - by)*(y - by)));
+ if (dist > distOut)
+ return 0;
+ }
+ /// on regarde si les capteurs voit un trou
+ if(es_.colorSeen(es_.leftFrontRVB_) == es_.redColor_ ||
+ es_.colorSeen(es_.leftFrontRVB_) == es_.blueColor_)
+ {
+ // Si c'est le cas on repositionne le robot
+ motor_.stop();
+ while(!update());
+ // XXX Vérifier l'angle
+ motorRotate(0.21);
+ motor_.findHole();
+ }
+ else if(es_.colorSeen(es_.rightFrontRVB_) == es_.redColor_ ||
+ es_.colorSeen(es_.rightFrontRVB_) == es_.blueColor_)
+ {
+ // Si c'est le cas on repositionne le robot
+ motor_.stop();
+ while(!update());
+ // XXX Vérifier l'angle
+ log_ ("SmartFindHole") << "Rotation spéciale ho un trou sous le capteur";
+ motorRotate(-0.21);
+ motor_.findHole();
+ }
+ }
+ while (!motor_.finish() /*&& !motor_.blocked()*/);
+ /// On regarde si on a blocké
+// if(motor_.blocked())
+// return -1;
+ if(motor_.finish())
+ {
+ es_.enableAllSensors (true);
+ es_.setRVBHoleStat (2);
+ temporisation (500);
+ int ret = es_.colorSeen(es_.holeRVB_);
+ es_.setRVBHoleStat (0);
+ es_.enableAllSensors (false);
+ return ret;
+ }
+ /// XXX Le return qui ne doit jamais arriver normalement...
+ return 0;
+}
+
+/// Procedure to unblock the robal
+void
+Ai::motorDeblock (void)
+{
+}
diff --git a/i/chuck/src/ai/ai.hh b/i/chuck/src/ai/ai.hh
new file mode 100644
index 0000000..29598b4
--- /dev/null
+++ b/i/chuck/src/ai/ai.hh
@@ -0,0 +1,86 @@
+#ifndef ai_hh
+#define ai_hh
+// ai.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Haller
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~haller/
+// Email: <nicolas@boiteameuh.org>
+// }}}
+/// Intelligence supérieur(à celui d'une balle de ping-pong) artificielle
+/// (comme une blonde) du robot.
+
+#include "motor/motor.hh"
+#include "es/es.hh"
+#include "scheduler/scheduler.hh"
+#include "scheduler/schedulable_read_fd.hh"
+#include "log/log.hh"
+
+class Ai
+{
+ private:
+ // Modules de contrôles du robot
+ Motor motor_;
+ Es es_;
+ /// Logger
+ Log log_;
+ // Le scheduler
+ scheduler::Scheduler scheduler_;
+ scheduler::SchedulableReadFd schedulableMotor_;
+ scheduler::SchedulableReadFd schedulableEs_;
+ // Paramètres générales du robot
+ const int round_duration_;
+ const int schedule_time_;
+ const int reference_sensor_mask_;
+ bool mustRotate_;
+ public:
+ /// Constructeur
+ Ai(const Config & config);
+ /// Destructeur du robot
+ ~Ai(void);
+
+ /// Initialisation du robal
+ void init(void);
+ /// Arrête complêtement le robot
+ void stop(void);
+ /// Fonction de tempo
+ void temporisation (int msec);
+ /// Attend le jack rentre(false) ou sorte (true)
+ void waitJack (bool out);
+ /// Attend une mise à jour...
+ bool update (void);
+ /// La célèbre fonction sync
+ bool sync (void);
+ /// Init things for a match.
+ void prepare (void);
+ /// Some after after a match
+ void afterMatch(void);
+ /// Reference sensors
+ void referenceSensors (void);
+ /// programme d'homologation du robal
+ void progHomoloRobal(void);
+ /// programme de match du robal
+ void progMatch(void);
+ bool motorMove (int d, int a);
+ void motorRotate (double d);
+ void motorBasicFindHole (void);
+ int motorSmartFindHole (double distOut);
+ void motorDeblock(void);
+};
+#endif // ai_hh
diff --git a/i/chuck/src/ai/test_ai.cc b/i/chuck/src/ai/test_ai.cc
new file mode 100644
index 0000000..6a7d09f
--- /dev/null
+++ b/i/chuck/src/ai/test_ai.cc
@@ -0,0 +1,105 @@
+// test_ai.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "tester/tester.hh"
+#include "ai/ai.hh"
+#include "timer/timer.hh"
+
+class TestAi : public Tester
+{
+ private:
+ Ai ai_;
+ /// Called after each command
+ void postcall (void)
+ {
+ while (!ai_.update ())
+ ;
+ }
+ /// Wait.
+ void wait (int ms)
+ {
+ int t, stop;
+ t = Timer::getProgramTime ();
+ stop = t + ms;
+ while (t < stop)
+ {
+ ai_.temporisation (stop - t);
+ t = Timer::getProgramTime ();
+ }
+ }
+ public:
+ TestAi(int argc, char ** argv)
+ :Tester(argc, argv), ai_(config_)
+ {}
+ void preRun (void)
+ {
+ Interpreter &interpreter = getInterpreter();
+ // Add functions
+ interpreter.add("init", Interpreter::memFunc(ai_, &Ai::init),
+ "Initialise le robal(void)");
+ interpreter.add("prepare", Interpreter::memFunc(ai_, &Ai::prepare),
+ "Lance la procédure pré-Match");
+ interpreter.add("afterMatch", Interpreter::memFunc(ai_,
+ &Ai::afterMatch),
+ "Lance la procédure post match");
+ interpreter.add("stop", Interpreter::memFunc(ai_, &Ai::stop),
+ "Stop le robal(void)");
+ interpreter.add("tempo", Interpreter::memFunc(ai_,
+ &Ai::temporisation),
+ "On temporise(int msec)");
+ interpreter.add("jack", Interpreter::memFunc(ai_, &Ai::waitJack),
+ "On attend que le jack sorte/rentre(bool sorte)");
+ interpreter.add("sensors", Interpreter::memFunc(ai_,
+ &Ai::referenceSensors),
+ "Initialise les capteurs RVB(void)");
+ interpreter.add("homologation", Interpreter::memFunc(ai_,
+ &Ai::progHomoloRobal),
+ "Programme d'homologation du robal");
+ interpreter.add("match", Interpreter::memFunc(ai_, &Ai::progMatch),
+ "Programme de match qui déchire du robal");
+ interpreter.add("findHoleBasic", Interpreter::memFunc(ai_, &Ai::motorBasicFindHole),
+ "Find a hole, basic version");
+ interpreter.add ("_postcall",
+ Interpreter::memFunc (*this, &TestAi::postcall));
+ }
+ void postRun(void)
+ {
+ // On init le robal histoire de ...
+ ai_.init();
+ }
+};
+
+int main (int argc, char **argv)
+{
+ try
+ {
+ TestAi ta(argc, argv);
+ ta.run ();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ }
+}
diff --git a/i/chuck/src/asserv/Makefile.defs b/i/chuck/src/asserv/Makefile.defs
new file mode 100644
index 0000000..22ffdb2
--- /dev/null
+++ b/i/chuck/src/asserv/Makefile.defs
@@ -0,0 +1,5 @@
+PROGRAMS += test_asserv
+
+asserv_OBJECTS = asserv.o $(proto_OBJECTS)
+
+test_asserv_OBJECTS = test_asserv.o $(asserv_OBJECTS) $(tester_OBJECTS)
diff --git a/i/chuck/src/asserv/asserv.cc b/i/chuck/src/asserv/asserv.cc
new file mode 100644
index 0000000..e196803
--- /dev/null
+++ b/i/chuck/src/asserv/asserv.cc
@@ -0,0 +1,387 @@
+// asserv.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "asserv.hh"
+#include "config/config.hh"
+
+#include <math.h>
+
+/// Constructor.
+Asserv::Asserv (Asserv::Receiver &receiver)
+ : proto_ (*this), receiver_ (receiver)
+{
+ // Get Config
+ Config &config = Config::getInstance ();
+ intervalCounterStat_ = config.get<int> ("asserv.counter_stat", 0);
+ intervalPos_ = config.get<int> ("asserv.pos_report");
+ intervalSpeedStat_ = config.get<int> ("asserv.speed_stat", 0);
+ intervalPosStat_ = config.get<int> ("asserv.pos_stat", 0);
+ intervalPwmStat_ = config.get<int> ("asserv.pwm_stat", 0);
+ intervalTimerStat_ = config.get<int> ("asserv.timer_stat", 0);
+ intervalInPort_ = config.get<int> ("asserv.in_port_report");
+ footing_ = config.get<int> ("asserv.footing");
+ tAccel_ = config.get<int> ("asserv.t_accel");
+ aAccel_ = config.get<int> ("asserv.a_accel");
+ tMaxSpeed_ = config.get<int> ("asserv.t_max_speed");
+ aMaxSpeed_ = config.get<int> ("asserv.a_max_speed");
+ tMaxSpeedSlow_ = config.get<int> ("asserv.t_max_speed_slow");
+ aMaxSpeedSlow_ = config.get<int> ("asserv.a_max_speed_slow");
+ tkp_ = config.get<int> ("asserv.tkp");
+ tki_ = config.get<int> ("asserv.tki");
+ tkd_ = config.get<int> ("asserv.tkd");
+ akp_ = config.get<int> ("asserv.akp");
+ aki_ = config.get<int> ("asserv.aki");
+ akd_ = config.get<int> ("asserv.akd");
+ esat_ = config.get<int> ("asserv.esat");
+ isat_ = config.get<int> ("asserv.isat");
+ lInvertPwm_ = config.get<bool> ("asserv.l_invert_pwm");
+ rInvertPwm_ = config.get<bool> ("asserv.r_invert_pwm");
+ stepPerMm_ = config.get<double> ("asserv.step_per_mm");
+ tty_ = config.get<std::string> ("asserv.tty");
+ proto_.open (tty_);
+ reset ();
+}
+
+/// Essaie de purger la liste d'émission et indique si elle est vide.
+bool
+Asserv::sync (void)
+{
+ return proto_.sync ();
+}
+
+/// Attend que toute les émissions soit terminées.
+bool
+Asserv::wait (int timeout/*-1*/)
+{
+ return proto_.wait (timeout);
+}
+
+/// Récupère le File Descriptor
+int
+Asserv::getFd (void) const
+{
+ return proto_.getFd ();
+}
+
+/// Reset the board and send parameters.
+void
+Asserv::reset (void)
+{
+ proto_.send ('z');
+ setIntervalCounterStat (intervalCounterStat_);
+ setIntervalPos (intervalPos_);
+ setIntervalSpeedStat (intervalSpeedStat_);
+ setIntervalPosStat (intervalPosStat_);
+ setIntervalPwmStat (intervalPwmStat_);
+ setIntervalTimerStat (intervalTimerStat_);
+ setIntervalInPort (intervalInPort_);
+ setFooting (footing_);
+ setAccel (tAccel_, aAccel_);
+ setMaxSpeed (tMaxSpeed_, aMaxSpeed_, tMaxSpeedSlow_, aMaxSpeedSlow_);
+ setCoef (tkp_, tki_, tkd_, akp_, akd_, akd_, esat_, isat_);
+ setPwmDir (lInvertPwm_, rInvertPwm_);
+}
+
+/// Set PWM.
+void
+Asserv::pwm (int l, int r)
+{
+ proto_.send ('w', "ww", l, r);
+}
+
+/// Position consign offset.
+void
+Asserv::offset (double t, double a)
+{
+ proto_.send ('c', "ww", mmToStep (t), mmToStep (a));
+}
+
+/// Set speed.
+void
+Asserv::speed (int t, int a)
+{
+ proto_.send ('s', "bb", t, a);
+}
+
+/// Speed controlled position consign offset.
+void
+Asserv::speedTo (double t, double a, int seq)
+{
+ proto_.send ('s', "ddb", mmToStep (t), mmToStep (a), seq);
+}
+
+/// Speed controlled angle consign offset.
+void
+Asserv::speedAngle (double a, int seq)
+{
+ proto_.send ('s', "ddb", 0, radToStep (a), seq);
+}
+
+/// Find a hole.
+void
+Asserv::findHole (int seq)
+{
+ proto_.send ('h', "b", seq);
+}
+
+/// Acknoledge.
+void
+Asserv::ack (int seq)
+{
+ proto_.send ('a', "b", seq);
+}
+
+/// Change counter stat interval.
+void
+Asserv::setIntervalCounterStat (int i)
+{
+ intervalCounterStat_ = i;
+ proto_.send ('C', "b", i);
+}
+
+/// Change position report interval.
+void
+Asserv::setIntervalPos (int i)
+{
+ intervalPos_ = i;
+ proto_.send ('X', "b", i);
+}
+
+/// Change speed stat interval.
+void
+Asserv::setIntervalSpeedStat (int i)
+{
+ intervalSpeedStat_ = i;
+ proto_.send ('S', "b", i);
+}
+
+/// Change position control stat interval.
+void
+Asserv::setIntervalPosStat (int i)
+{
+ intervalPosStat_ = i;
+ proto_.send ('P', "b", i);
+}
+
+/// Change pwm stat interval.
+void
+Asserv::setIntervalPwmStat (int i)
+{
+ intervalPwmStat_ = i;
+ proto_.send ('W', "b", i);
+}
+
+/// Change timer stat interval.
+void
+Asserv::setIntervalTimerStat (int i)
+{
+ intervalTimerStat_ = i;
+ proto_.send ('T', "b", i);
+}
+
+/// Change input port report interval.
+void
+Asserv::setIntervalInPort (int i)
+{
+ intervalInPort_ = i;
+ proto_.send ('I', "b", i);
+}
+
+/// Set current position.
+void
+Asserv::setPos (double x, double y, double a)
+{
+ setXPos (x);
+ setYPos (y);
+ setAngle (a);
+}
+
+/// Set current x position.
+void
+Asserv::setXPos (double x)
+{
+ proto_.send ('p', "bd", 'X', mmToStep (x));
+}
+
+/// Set current y position.
+void
+Asserv::setYPos (double y)
+{
+ proto_.send ('p', "bd", 'Y', mmToStep (y));
+}
+
+/// Set current angle.
+void
+Asserv::setAngle (double a)
+{
+ proto_.send ('p', "bd", 'A', radToAvr (a));
+}
+
+/// Set footing.
+void
+Asserv::setFooting (int f)
+{
+ footing_ = f;
+ proto_.send ('p', "bw", 'f', f);
+}
+
+/// Set acceleration.
+void
+Asserv::setAccel (int t, int a)
+{
+ tAccel_ = t;
+ aAccel_ = a;
+ proto_.send ('p', "bww", 'a', t, a);
+}
+
+/// Set maximum speed for automatic movements.
+void
+Asserv::setMaxSpeed (int t, int a, int ts, int as)
+{
+ tMaxSpeed_ = t;
+ aMaxSpeed_ = a;
+ tMaxSpeedSlow_ = ts;
+ aMaxSpeedSlow_ = as;
+ proto_.send ('p', "bbbbb", 's', t, a, ts, as);
+}
+
+/// Set motor control coeficients.
+void
+Asserv::setCoef (int tkp, int tki, int tkd, int akp, int aki, int akd,
+ int esat, int isat)
+{
+ tkp_ = tkp;
+ tki_ = tki;
+ tkd_ = tkd;
+ akp_ = akp;
+ aki_ = aki;
+ akd_ = akd;
+ esat_ = esat;
+ isat_ = isat;
+ proto_.send ('p', "bww", 'p', tkp, akp);
+ proto_.send ('p', "bww", 'i', tki, aki);
+ proto_.send ('p', "bww", 'd', tkd, akd);
+ proto_.send ('p', "bw", 'E', esat);
+ proto_.send ('p', "bw", 'I', isat);
+}
+
+/// Set PWM direction.
+void
+Asserv::setPwmDir (bool invertL, bool invertR)
+{
+ lInvertPwm_ = invertL;
+ rInvertPwm_ = invertR;
+ proto_.send ('p', "bbb", 'w', invertL ? 1 : 0, invertR ? 1 : 0);
+}
+
+/// Store to eeprom.
+void
+Asserv::storeParams (void)
+{
+ proto_.send ('p', "bb", 'E', 1);
+}
+
+/// Clear eeprom.
+void
+Asserv::clearParams (void)
+{
+ proto_.send ('p', "bb", 'E', 0);
+}
+
+/// Implémentation du proto::Receiver.
+void
+Asserv::receive (char command, const Proto::Frame &frame)
+{
+ int seq, l, r, x, y, a, t, te, ti, ae, ai, port;
+ switch (command)
+ {
+ case 'A':
+ if (proto_.decode (frame, "b", seq))
+ receiver_.receiveAck (seq);
+ break;
+ case 'C':
+ if (proto_.decode (frame, "ww", l, r))
+ receiver_.receiveCounterStat (l, r);
+ break;
+ case 'X':
+ if (proto_.decode (frame, "DDD", x, y, a))
+ receiver_.receivePos (stepToMm (x / 256), stepToMm (y / 256), avrToRad (a));
+ break;
+ case 'S':
+ if (proto_.decode (frame, "BB", t, a))
+ receiver_.receiveSpeedStat (t, a);
+ break;
+ case 'P':
+ if (proto_.decode (frame, "WWWW", te, ti, ae, ai))
+ receiver_.receivePosStat (te, ti, ae, ai);
+ break;
+ case 'W':
+ if (proto_.decode (frame, "WW", l, r))
+ receiver_.receivePwmStat (l, r);
+ break;
+ case 'T':
+ // TODO (si on a le temps).
+ break;
+ case 'I':
+ if (proto_.decode (frame, "w", port))
+ receiver_.receiveInPort (port);
+ break;
+ }
+}
+
+/// Convert mm to steps.
+int
+Asserv::mmToStep (double mm) const
+{
+ return static_cast<int> (mm * stepPerMm_);
+}
+
+/// Convert steps to mm.
+double
+Asserv::stepToMm (int step) const
+{
+ return static_cast<double> (step) / stepPerMm_;
+}
+
+/// Convert rad to avr angles.
+int
+Asserv::radToAvr (double a) const
+{
+ return static_cast<int> (a * M_1_PI * 0.5 * (1 << 24)) & 0xffffff;
+}
+
+/// Convert avr angles to rad.
+double
+Asserv::avrToRad (int a) const
+{
+ return static_cast<double> (a) * 2 * M_PI / (1 << 24);
+}
+
+/// Convert rad to steps.
+int
+Asserv::radToStep (double a) const
+{
+ return static_cast<int> (static_cast<double> (footing_) * a * 0.5);
+}
+
diff --git a/i/chuck/src/asserv/asserv.hh b/i/chuck/src/asserv/asserv.hh
new file mode 100644
index 0000000..ddbc104
--- /dev/null
+++ b/i/chuck/src/asserv/asserv.hh
@@ -0,0 +1,141 @@
+#ifndef asserv_hh
+#define asserv_hh
+// asserv.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "proto/proto.hh"
+
+/// Dialog class with the motor control board.
+/// Units:
+/// - step: one step distance.
+/// - period: one motor control sampling period.
+class Asserv : public Proto::Receiver
+{
+ public:
+ /// Asserv clients must implement Receiver.
+ class Receiver
+ {
+ public:
+ virtual ~Receiver (void) { }
+ virtual void receiveAck (int seq) = 0;
+ virtual void receiveCounterStat (int l, int r) = 0;
+ virtual void receivePos (double x, double y, double a) = 0;
+ virtual void receiveSpeedStat (int t, int a) = 0;
+ virtual void receivePosStat (int te, int ti, int ae, int ai) = 0;
+ virtual void receivePwmStat (int l, int r) = 0;
+ virtual void receiveTimerStat (const int *t, int tn) = 0;
+ virtual void receiveInPort (unsigned int port) = 0;
+ };
+ private:
+ Proto proto_;
+ std::string tty_;
+ Receiver &receiver_;
+ int intervalCounterStat_, intervalPos_, intervalSpeedStat_,
+ intervalPosStat_, intervalPwmStat_, intervalTimerStat_,
+ intervalInPort_;
+ int footing_;
+ int tAccel_, aAccel_;
+ int tMaxSpeed_, aMaxSpeed_, tMaxSpeedSlow_, aMaxSpeedSlow_;
+ int tkp_, tki_, tkd_, akp_, aki_, akd_, esat_, isat_;
+ bool lInvertPwm_, rInvertPwm_;
+ double stepPerMm_;
+ public:
+ /// Constructor.
+ Asserv (Asserv::Receiver &receiver);
+ /// Essaie de purger la liste d'émission et indique si elle est vide.
+ bool sync (void);
+ /// Attend que toute les émissions soit terminées.
+ bool wait (int timeout = -1);
+ /// Récupère le File Descriptor
+ int getFd (void) const;
+ /// Reset the board and send parameters.
+ void reset (void);
+ /// Set PWM.
+ void pwm (int l, int r);
+ /// Position consign offset.
+ void offset (double t, double a);
+ /// Set speed.
+ void speed (int t, int a);
+ /// Speed controlled position consign offset.
+ void speedTo (double t, double a, int seq);
+ /// Speed controlled angle consign offset.
+ void speedAngle (double a, int seq);
+ /// Find a hole.
+ void findHole (int seq);
+ /// Acknoledge.
+ void ack (int seq);
+ /// Change counter stat interval.
+ void setIntervalCounterStat (int i);
+ /// Change position report interval.
+ void setIntervalPos (int i);
+ /// Change speed stat interval.
+ void setIntervalSpeedStat (int i);
+ /// Change position control stat interval.
+ void setIntervalPosStat (int i);
+ /// Change pwm stat interval.
+ void setIntervalPwmStat (int i);
+ /// Change timer stat interval.
+ void setIntervalTimerStat (int i);
+ /// Change input port report interval.
+ void setIntervalInPort (int i);
+ /// Set current position.
+ void setPos (double x, double y, double a);
+ /// Set current x position.
+ void setXPos (double x);
+ /// Set current y position.
+ void setYPos (double y);
+ /// Set current angle.
+ void setAngle (double a);
+ /// Set footing.
+ void setFooting (int f);
+ /// Set acceleration.
+ void setAccel (int t, int a);
+ /// Set maximum speed for automatic movements.
+ void setMaxSpeed (int t, int a, int ts, int as);
+ /// Set motor control coeficients.
+ void setCoef (int tkp, int tki, int tkd, int akp, int aki, int akd,
+ int esat, int isat);
+ /// Set PWM direction.
+ void setPwmDir (bool invertL, bool invertR);
+ /// Store to eeprom.
+ void storeParams (void);
+ /// Clear eeprom.
+ void clearParams (void);
+ /// Implémentation du proto::Receiver.
+ void receive (char command, const Proto::Frame &frame);
+ private:
+ /// Convert mm to steps.
+ int mmToStep (double mm) const;
+ /// Convert steps to mm.
+ double stepToMm (int step) const;
+ /// Convert rad to avr angles.
+ int radToAvr (double a) const;
+ /// Convert avr angles to rad.
+ double avrToRad (int a) const;
+ /// Convert rad to steps.
+ int radToStep (double a) const;
+};
+
+#endif // asserv_hh
diff --git a/i/chuck/src/asserv/test_asserv.cc b/i/chuck/src/asserv/test_asserv.cc
new file mode 100644
index 0000000..2796e33
--- /dev/null
+++ b/i/chuck/src/asserv/test_asserv.cc
@@ -0,0 +1,197 @@
+// test_asserv.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "asserv.hh"
+#include "tester/tester.hh"
+#include "timer/timer.hh"
+
+#include <iostream>
+#include <exception>
+#include <iomanip>
+
+class TestAsserv : public Tester, public Asserv::Receiver
+{
+ private:
+ Asserv asserv_;
+ int seq_;
+ bool ok_;
+ public:
+ /// Constructor.
+ TestAsserv (int argc, char **argv)
+ : Tester (argc, argv), asserv_ (*this), seq_ (0), ok_ (true)
+ { }
+ /// Next seq number.
+ inline void nextSeq (void)
+ {
+ seq_++;
+ if (seq_ > 100)
+ seq_ = 1;
+ }
+ /// Speed controlled position consign offset, handle seq.
+ void speedTo (double t, double a)
+ {
+ nextSeq ();
+ ok_ = false;
+ asserv_.speedTo (t, a, seq_);
+ }
+ /// Speed controlled angle consign offset, handle seq.
+ void speedAngle (double a)
+ {
+ nextSeq ();
+ ok_ = false;
+ asserv_.speedAngle (a, seq_);
+ }
+ /// Find a hole, handle seq.
+ void findHole (void)
+ {
+ nextSeq ();
+ ok_ = false;
+ asserv_.findHole (seq_);
+ }
+ /// Wait.
+ void wait (int ms)
+ {
+ int t, stop;
+ t = Timer::getProgramTime ();
+ stop = t + ms;
+ while (t < stop)
+ {
+ asserv_.wait (stop - t);
+ t = Timer::getProgramTime ();
+ }
+ }
+ /// Called after each command called.
+ void postcall (void)
+ {
+ while (!asserv_.wait () || !ok_)
+ ;
+ }
+ /// Executed before checking/running commands. Good place to add command
+ /// to the interpreter.
+ void preRun (void)
+ {
+ Interpreter &i = getInterpreter ();
+ i.add ("wait", Interpreter::memFunc (*this, &TestAsserv::wait),
+ "wait MS\nwait for a delay in millisecond");
+ i.add ("reset", Interpreter::memFunc (asserv_, &Asserv::reset),
+ "reset\nreset the asserv board");
+ i.add ("pwm", Interpreter::memFunc (asserv_, &Asserv::pwm),
+ "pwm LEFT RIGHT\n"
+ "directly set pwm values, use with caution");
+ i.add ("offset", Interpreter::memFunc (asserv_, &Asserv::offset),
+ "offset THETA(mm) ALPHA(mm)\n"
+ "add value to current position, use for pid callibration");
+ i.add ("speed", Interpreter::memFunc (asserv_, &Asserv::speed),
+ "speed THETA ALPHA\n"
+ "unlimited speed consign");
+ i.add ("speedTo", Interpreter::memFunc (*this, &TestAsserv::speedTo),
+ "speedTo THETA(mm) ANGLE(mm)\n"
+ "speed consign limited in distance");
+ i.add ("speedAngle",
+ Interpreter::memFunc (*this, &TestAsserv::speedAngle),
+ "speedAngle ANGLE(rad)\n"
+ "speed consign limited in angle");
+ i.add ("findHole", Interpreter::memFunc (*this, &TestAsserv::findHole),
+ "findHole\nfind a hole");
+ i.add ("setPos", Interpreter::memFunc (asserv_, &Asserv::setPos),
+ "setPos X(mm) Y(mm) A(rad)\n"
+ "set current position");
+ i.add ("setXPos", Interpreter::memFunc (asserv_, &Asserv::setYPos),
+ "setPos X(mm)\n"
+ "set current X position");
+ i.add ("setYPos", Interpreter::memFunc (asserv_, &Asserv::setXPos),
+ "setPos Y(mm)\n"
+ "set current Y position");
+ i.add ("setAngle", Interpreter::memFunc (asserv_, &Asserv::setAngle),
+ "setPos A(rad)\n"
+ "set current angle");
+ i.add ("storeParams",
+ Interpreter::memFunc (asserv_, &Asserv::storeParams),
+ "storeParams\nstore parameters to eeprom");
+ i.add ("clearParams",
+ Interpreter::memFunc (asserv_, &Asserv::clearParams),
+ "clearParams\nclear parameters stored in eeprom");
+ i.add ("_postcall",
+ Interpreter::memFunc (*this, &TestAsserv::postcall));
+ }
+ /// Executed after running commands.
+ void postRun (void)
+ {
+ asserv_.reset ();
+ }
+ void receiveAck (int seq)
+ {
+ if ((seq & 0x7f) == seq_)
+ {
+ std::cout << "ack received" << std::endl;
+ asserv_.ack (seq);
+ ok_ = true;
+ }
+ }
+ void receiveCounterStat (int l, int r)
+ {
+ std::cout << "C " << l << ' ' << r << std::endl;
+ }
+ void receivePos (double x, double y, double a)
+ {
+ std::cout << "X " << x << ' ' << y << ' ' << a << std::endl;
+ }
+ void receiveSpeedStat (int t, int a)
+ {
+ std::cout << "S " << t << ' ' << a << std::endl;
+ }
+ void receivePosStat (int te, int ti, int ae, int ai)
+ {
+ std::cout << "P " << te << ' ' << ti << ' ' << ae << ' ' << ai <<
+ std::endl;
+ }
+ void receivePwmStat (int l, int r)
+ {
+ std::cout << "W " << l << ' ' << r << std::endl;
+ }
+ void receiveTimerStat (const int *t, int tn)
+ {
+ std::cout << "T ";
+ std::copy (t, t + tn, std::ostream_iterator<int> (std::cout, " "));
+ }
+ void receiveInPort (unsigned int port)
+ {
+ std::cout << "I " << std::hex << std::setw (4) << std::setfill ('0')
+ << port << std::dec << std::endl;
+ }
+};
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ TestAsserv ta (argc, argv);
+ ta.run ();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ }
+}
diff --git a/i/chuck/src/config/Makefile.defs b/i/chuck/src/config/Makefile.defs
new file mode 100644
index 0000000..a06f2a7
--- /dev/null
+++ b/i/chuck/src/config/Makefile.defs
@@ -0,0 +1,5 @@
+PROGRAMS += test_config
+
+config_OBJECTS = config_data.o config.o $(parser_OBJECTS)
+
+test_config_OBJECTS = $(config_OBJECTS) test_config.o
diff --git a/i/chuck/src/config/config.cc b/i/chuck/src/config/config.cc
new file mode 100644
index 0000000..333bd4a
--- /dev/null
+++ b/i/chuck/src/config/config.cc
@@ -0,0 +1,27 @@
+// config.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+#include "config.hh"
+
+
+Config *Config::instance_ = 0;
diff --git a/i/chuck/src/config/config.hh b/i/chuck/src/config/config.hh
new file mode 100644
index 0000000..3034b1a
--- /dev/null
+++ b/i/chuck/src/config/config.hh
@@ -0,0 +1,98 @@
+#ifndef config_hh
+#define config_hh
+// config.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "config_data.hh"
+#include <stdexcept>
+
+#include <list>
+
+/// Classe d'accés à la configuration.
+/// Singleton, created by hand.
+class Config
+{
+ ConfigData configData_;
+ public:
+ typedef std::list<int> IntList;
+ typedef std::list<double> FloatList;
+ typedef std::list<std::string> StringList;
+ private:
+ static Config *instance_;
+ public:
+ /// Boa constricteur, voir ConfigData.
+ Config (int &argc, char **&argv)
+ : configData_ (argc, argv)
+ {
+ create ();
+ }
+ /// Boa constricteur, voir ConfigData.
+ Config (int &argc, char **&argv, const std::string &file)
+ : configData_ (argc, argv, file)
+ {
+ create ();
+ }
+ /// Check and fill the private instance_ variables for singleton
+ void create ()
+ {
+ if (instance_)
+ throw std::runtime_error ("Config already created");
+ instance_ = this;
+ }
+
+ /// Récupère une valeur de configuration, fonction générique.
+ template<typename T>
+ const T &get (const std::string &id) const
+ {
+ return configData_.get<T> (id);
+ }
+ /// Récupère une valeur de configuration, fonction générique avec valeur
+ /// par défaut pour éviter l'exception en cas d'abscence de valeur.
+ template<typename T>
+ const T &get (const std::string &id, const T &defaut) const
+ {
+ return configData_.get<T> (id, defaut);
+ }
+ /// Récupère une valeur de configuration.
+ const any &get (const std::string &id) const
+ {
+ return configData_.get (id);
+ }
+ /// Récupère une valeur de configuration avec valeur par défaut pour
+ /// éviter le renvoie d'exception.
+ const any &get (const std::string &id, const any &defaut) const
+ {
+ return configData_.get (id, defaut);
+ }
+ /// Get the unique instance of the class
+ static inline Config &
+ getInstance ()
+ {
+ if (!instance_)
+ throw std::runtime_error ("Config not created");
+ return *instance_;
+ }
+};
+
+#endif // config_hh
diff --git a/i/chuck/src/config/config_data.cc b/i/chuck/src/config/config_data.cc
new file mode 100644
index 0000000..e4dcf75
--- /dev/null
+++ b/i/chuck/src/config/config_data.cc
@@ -0,0 +1,148 @@
+// config_data.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "config.hh"
+#include "config_data.hh"
+#include "parser/parser.hh"
+
+#include <stdexcept>
+
+/// Constructeur. Traite les arguments de la ligne de commande et lit le
+/// fichier de configuration. Les arguments traités sont retiré de la
+/// ligne de commande.
+ConfigData::ConfigData (int &argc, char **&argv)
+{
+ init (argc, argv, "rc/config");
+}
+
+/// Constructeur. Fourni en plus un fichier de configuration différent de
+/// celui par défaut.
+ConfigData::ConfigData (int &argc, char **&argv, const std::string &file)
+{
+ init (argc, argv, file);
+}
+
+/// Récupère une valeur de configuration.
+const any &
+ConfigData::get (const std::string &id) const
+{
+ Data::const_iterator i = data_.find (id);
+ if (i == data_.end ())
+ throw std::runtime_error (id + ": config item not found");
+ return i->second;
+}
+
+/// Récupère une valeur de configuration avec une valeur par défaut. Ne
+/// renvoye pas d'exception.
+const any &
+ConfigData::get (const std::string &id, const any &defaut) const
+{
+ Data::const_iterator i = data_.find (id);
+ // If not found, return default values
+ if (i == data_.end ())
+ return defaut;
+ else
+ return i->second;
+}
+
+/// Ajoute une valeur de configuration. VAL prend l'ancienne valeur ou un any
+/// vide.
+void
+ConfigData::add (const std::string &id, any &val)
+{
+ any &a = data_[id];
+ a.swap (val);
+}
+
+/// Classe dérivé de Parser pour le parsing de conf.
+class ConfigParser : public Parser
+{
+ ConfigData &data_;
+ public:
+ /// Constructeur.
+ ConfigParser (ConfigData &data) : data_ (data) { }
+ /// Fonction appelée lors d'une affectation. VAL peut être modifié, il est
+ /// détruit suite à l'appel.
+ virtual void assign (const std::string &id, any &val)
+ {
+ data_.add (id, val);
+ }
+};
+
+/// Initialise (lit la ligne de commande et les fichiers de config.
+void
+ConfigData::init (int &argc, char **&argv, const std::string &file)
+{
+ std::string configFile (file);
+ std::string configString;
+ // Parse la ligne de commande.
+ for (int i = 1; i < argc; )
+ {
+ int del = 0;
+ // -F CONFIG_FILE
+ if (argv[i][0] == '-' && argv[i][1] == 'F')
+ {
+ if (argv[i][2] != '\0')
+ {
+ del = 1;
+ configFile = &argv[i][2];
+ }
+ else if (i + 1 < argc)
+ {
+ del = 2;
+ configFile = argv[i + 1];
+ }
+ }
+ // -C CONFIG_STRING
+ if (argv[i][0] == '-' && argv[i][1] == 'C')
+ {
+ configString += ';';
+ if (argv[i][2] != '\0')
+ {
+ del = 1;
+ configString += &argv[i][2];
+ }
+ else if (i + 1 < argc)
+ {
+ del = 2;
+ configString += argv[i + 1];
+ }
+ }
+ // Supprime ces arguments de la liste.
+ if (del)
+ {
+ for (int j = i; j < argc - del + 1; j++)
+ argv[j] = argv[j + del];
+ argc -= del;
+ }
+ else
+ i++;
+ }
+ // Lit le fichier de config.
+ ConfigParser p (*this);
+ p.parseFile (configFile);
+ // Parse les chaînes supplémentaires.
+ p.parseString (configString);
+}
+
diff --git a/i/chuck/src/config/config_data.hh b/i/chuck/src/config/config_data.hh
new file mode 100644
index 0000000..51caabd
--- /dev/null
+++ b/i/chuck/src/config/config_data.hh
@@ -0,0 +1,68 @@
+#ifndef config_data_hh
+#define config_data_hh
+// config_data.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "utils/any.hh"
+
+#include <map>
+#include <string>
+
+/// Classe contenant les informations de configuration.
+class ConfigData
+{
+ typedef std::map<std::string, any> Data;
+ Data data_;
+ public:
+ /// Constructeur. Traite les arguments de la ligne de commande et lit le
+ /// fichier de configuration. Les arguments traités sont retiré de la
+ /// ligne de commande.
+ ConfigData (int &argc, char **&argv);
+ /// Constructeur. Fourni en plus un fichier de configuration différent de
+ /// celui par défaut.
+ ConfigData (int &argc, char **&argv, const std::string &file);
+ /// Récupère une valeur de configuration, fonction générique.
+ template<typename T>
+ const T &get (const std::string &id) const;
+ /// Récupère une valeur de configuration, fonction générique avec valeur
+ /// par défaut. Cette fonction ne renvoie d'exception que si il y a un
+ /// problème de type et non de valeur non existante.
+ template<typename T>
+ const T &get (const std::string &id, const T &defaut) const;
+ /// Récupère une valeur de configuration.
+ const any &get (const std::string &id) const;
+ /// Récupère une valeur de configuration avec une valeur par défaut. Ne
+ /// renvoye pas d'exception.
+ const any &get (const std::string &id, const any &defaut) const;
+ /// Ajoute une valeur de configuration. VAL prend l'ancienne valeur ou un
+ /// any vide.
+ void add (const std::string &id, any &val);
+ private:
+ /// Initialise (lit la ligne de commande et les fichiers de config.
+ void init (int &argc, char **&argv, const std::string &file);
+};
+
+#include "config_data.tcc"
+
+#endif // config_data_hh
diff --git a/i/chuck/src/config/config_data.tcc b/i/chuck/src/config/config_data.tcc
new file mode 100644
index 0000000..71fa6d6
--- /dev/null
+++ b/i/chuck/src/config/config_data.tcc
@@ -0,0 +1,59 @@
+// config_data.tcc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <stdexcept>
+
+/// Récupère une valeur de configuration, fonction générique.
+template<typename T>
+const T &
+ConfigData::get (const std::string &id) const
+{
+ const any &a = get (id);
+ const T *v = any_cast<T> (&a);
+ if (!v)
+ throw std::runtime_error (id + ": config item with bad type");
+ return *v;
+}
+
+/// Récupère une valeur de configuration, fonction générique avec valeur
+/// par défaut. Cette fonction ne renvoie d'exception que si il y a un
+/// problème de type et non de valeur non existante.
+template<typename T>
+const T &
+ConfigData::get (const std::string &id, const T &defaut) const
+{
+ // Construct an empty any
+ any empty;
+ // Get the value with an empty one by default
+ const any &a = get (id, empty);
+ // Empty value returned, not found
+ if (a.empty ())
+ return defaut;
+ const T *v = any_cast<T> (&a);
+ if (!v)
+ throw std::runtime_error (id + ": config item with bad type");
+ return *v;
+}
+
diff --git a/i/chuck/src/config/test_config.cc b/i/chuck/src/config/test_config.cc
new file mode 100644
index 0000000..3b3e368
--- /dev/null
+++ b/i/chuck/src/config/test_config.cc
@@ -0,0 +1,48 @@
+// test_config.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "config.hh"
+
+#include <iterator>
+#include <algorithm>
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ // Create manually the instance of the config class
+ Config c (argc, argv);
+ // Example for getting the unique instance
+ Config &ci = Config::getInstance ();
+ for (int i = 1; i < argc; ++i)
+ std::cout << ci.get (argv[i]) << std::endl;
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/i/chuck/src/data/Makefile.defs b/i/chuck/src/data/Makefile.defs
new file mode 100644
index 0000000..c0fe78d
--- /dev/null
+++ b/i/chuck/src/data/Makefile.defs
@@ -0,0 +1,16 @@
+PROGRAMS += test_data test_data_buffer test_data_circular_buffer
+
+data_OBJECTS = data_input.o data_input_file.o data_input_zlib.o \
+ data_buffer.o data_output.o data_circular_buffer.o -lz
+
+test_data_OBJECTS = test_data.o $(data_OBJECTS)
+
+test_data_buffer_OBJECTS = test_data_buffer.o data_buffer.o
+
+test_data_circular_buffer_OBJECTS = test_data_circular_buffer.o data_circular_buffer.o
+
+#UTESTS += data
+
+#data.utest: test_data
+
+#data_UTEST = ./test_data /tmp/toto.tar.gz > /dev/null
diff --git a/i/chuck/src/data/data_buffer.cc b/i/chuck/src/data/data_buffer.cc
new file mode 100644
index 0000000..c0d8cef
--- /dev/null
+++ b/i/chuck/src/data/data_buffer.cc
@@ -0,0 +1,130 @@
+// data_buffer.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_buffer.hh"
+
+#include <cstring> // std::memcpy
+#include <stdexcept> // std::runtime_error
+#include <algorithm> // std::swap
+
+static const unsigned min_size = 10;
+
+/// Constructeur par defaut
+DataBuffer::DataBuffer (void)
+ : size_ (min_size), headPos_ (0), tailPos_ (0), type_ (NoType)
+{
+ buffer_ = new uint8_t [size_];
+}
+
+/// Constructeur par recopie.
+DataBuffer::DataBuffer (const DataBuffer &d)
+ : headPos_ (0), type_ (NoType)
+{
+ unsigned sizeUse = d.tailPos_ - d.headPos_;
+ size_ = tailPos_ = sizeUse;
+ type_ = d.type_;
+ buffer_ = new uint8_t [size_];
+ std::memcpy (buffer_, &d.buffer_[headPos_], sizeUse);
+}
+
+/// Constructeur avec données.
+DataBuffer::DataBuffer (uint8_t *data, unsigned size, unsigned sizeAllocated,
+ dataType_e type)
+ : size_ (sizeAllocated), headPos_ (0), tailPos_ (size), type_ (type)
+{
+ if (!data || size > sizeAllocated)
+ throw std::invalid_argument ("Paramêtres invalides");
+ buffer_ = new uint8_t [size_];
+ std::memcpy (buffer_, data, tailPos_);
+}
+
+/// Surcharge de l'opérateur d'affectation
+DataBuffer &
+DataBuffer::operator= (const DataBuffer &d)
+{
+ DataBuffer b (d);
+ b.swap (*this);
+ return *this;
+}
+
+/// Lit des données. Même convention que le read de la libc, mais lance
+/// une exception en cas d'erreur.
+unsigned
+DataBuffer::read (uint8_t *buf, unsigned size)
+{
+ if (!buf)
+ throw std::invalid_argument ("Paramêtres invalides");
+ unsigned sizeTmp = tailPos_ - headPos_;
+ // On regarde combien de données peuvent être lues
+ if (size < sizeTmp)
+ sizeTmp = size;
+ std::memcpy (buf, &buffer_[headPos_], sizeTmp);
+ headPos_ += sizeTmp;
+ // Si il n'y a plus de données dans le buffer, on recommence de puis 0
+ if (headPos_ == tailPos_)
+ headPos_ = tailPos_ = 0;
+ return sizeTmp;
+}
+
+/// Écrit des données. Même convention que le write de la libc, mais lance
+/// une exception en cas d'erreur.
+void
+DataBuffer::write (const uint8_t *buf, unsigned size)
+{
+ // Vérification des paramêtres
+ if (!buf)
+ throw std::invalid_argument ("Parametres invalides");
+ // Agrandissement du buffer
+ grow (size);
+ // Ecriture des données
+ std::memcpy (&buffer_[tailPos_], buf, size);
+ tailPos_ += size;
+}
+
+/// Augmente la taille du buffer pour correspondre à size.
+void
+DataBuffer::grow (const unsigned size)
+{
+ // Taille restant non utilisé dans le buffer
+ unsigned tailleLibre = size_ - tailPos_;
+ // Si la taille du buffer n'est pas suffisante
+ if (tailleLibre < size)
+ {
+ // On augmente de deux fois la taille
+ DataBuffer d (&buffer_[headPos_], tailPos_ - headPos_,
+ 2 * size + size_, type_);
+ d.swap (*this);
+ }
+}
+
+/// Echange les buffers.
+void
+DataBuffer::swap (DataBuffer &d)
+{
+ std::swap (buffer_, d.buffer_);
+ std::swap (size_, d.size_);
+ std::swap (headPos_, d.headPos_);
+ std::swap (tailPos_, d.tailPos_);
+ std::swap (type_, d.type_);
+}
diff --git a/i/chuck/src/data/data_buffer.hh b/i/chuck/src/data/data_buffer.hh
new file mode 100644
index 0000000..7b71a4d
--- /dev/null
+++ b/i/chuck/src/data/data_buffer.hh
@@ -0,0 +1,83 @@
+#ifndef data_buffer_hh
+#define data_buffer_hh
+// data_buffer.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+#include "data_input.hh"
+#include "data_output.hh"
+
+#include <stdint.h> // uint8_t
+
+/// Classe contenant un buffer de données accessible en lecture et en
+/// écriture.
+class DataBuffer : public DataInput, public DataOutput
+{
+ public:
+ /// Type de données possible du buffer.
+ enum dataType_e {
+ NoType,
+ Image,
+ AskImage
+ };
+ private:
+ /// Buffer de données.
+ uint8_t *buffer_;
+ /// Taille alloué en mémoire pour le buffer.
+ unsigned size_;
+ /// Position du début et de la fin des données dans le buffer.
+ unsigned headPos_, tailPos_;
+ /// Type de données du buffer.
+ dataType_e type_;
+ /// Augmente la taille du buffer pour correspondre à size.
+ void grow (const unsigned size);
+ public:
+ /// Constructeur par défaut.
+ DataBuffer (void);
+ /// Constructeur par recopie.
+ DataBuffer (const DataBuffer &d);
+ /// Constructeur avec données.
+ DataBuffer (uint8_t *data, unsigned size, unsigned sizeAllocated,
+ dataType_e type = NoType);
+ /// Destructeur par défaut.
+ ~DataBuffer (void) { delete [] buffer_; }
+ /// Surcharge de l'opérateur d'affectation
+ DataBuffer &operator= (const DataBuffer &d);
+ /// Lit des données. Même convention que le read de la libc, mais lance
+ /// une exception en cas d'erreur.
+ unsigned read (uint8_t *buf, unsigned size);
+ /// Écrit des données. Même convention que le write de la libc, mais lance
+ /// une exception en cas d'erreur.
+ void write (const uint8_t *buf, unsigned size);
+ /// Taille utile du buffer.
+ unsigned size (void) const { return tailPos_ - headPos_; }
+ /// Echange les buffers.
+ void swap (DataBuffer &d);
+ /// Type de données du buffer.
+ dataType_e type (void) const { return type_; }
+ /// Change le type de données du buffer.
+ void setType (const dataType_e type) { type_ = type; }
+ /// Empty/clear the content of the buffer.
+ void clear (void) { tailPos_ = headPos_ = 0; }
+};
+#endif // data_buffer_hh
diff --git a/i/chuck/src/data/data_circular_buffer.cc b/i/chuck/src/data/data_circular_buffer.cc
new file mode 100644
index 0000000..be17526
--- /dev/null
+++ b/i/chuck/src/data/data_circular_buffer.cc
@@ -0,0 +1,123 @@
+// data_circular_buffer.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_circular_buffer.hh"
+
+#include <cstring> // std::memcpy
+#include <stdexcept> // std::runtime_error
+#include <algorithm> // std::swap, std::min
+
+#include <iostream> // XXX
+
+/// Default constructor.
+/// Size is the allocated size in memory.
+DataCircularBuffer::DataCircularBuffer (unsigned size)
+ : size_ (size + 1), startPos_ (0), endPos_ (0)
+{
+ // The + 1 for size is because, in some cases, we will have an empty case.
+ buffer_ = new uint8_t [size_];
+}
+
+/// Destructor.
+DataCircularBuffer::~DataCircularBuffer (void)
+{
+ delete [] buffer_;
+}
+
+/// Read data of maximum size in the data pointer (data must be allocated of
+/// size).
+unsigned
+DataCircularBuffer::read (uint8_t *data, unsigned size)
+{
+ if (!data || !size)
+ throw std::invalid_argument ("Invalid parameter");
+ return internalRead (data, size);
+}
+
+/// Internal read, do the real job.
+unsigned
+DataCircularBuffer::internalRead (uint8_t *data, unsigned size)
+{
+ // Size of data to read
+ unsigned sizeToRead = std::min (maxReadableData (), size);
+ // Size of data to read for the end of the buffer
+ unsigned sizeToReadEnd = std::min (size_ - startPos_, sizeToRead);
+ // Copy end part of buffer
+ if (data)
+ std::memcpy (&data[0], &buffer_[startPos_], sizeToReadEnd);
+ // Need to do the begin part of buffer ?
+ int sizeToReadStart = sizeToRead - sizeToReadEnd;
+ if (sizeToReadStart > 0)
+ {
+ if (data)
+ std::memcpy (&data[sizeToReadEnd], &buffer_[0], sizeToReadStart);
+ // Move start of data
+ startPos_ = 0 + sizeToReadStart;
+ }
+ else
+ // Move start of data
+ startPos_ = (startPos_ + sizeToRead) % size_;
+ return sizeToRead;
+}
+
+/// Write data of size length.
+void
+DataCircularBuffer::write (const uint8_t *data, unsigned size)
+{
+ if (!data || !size)
+ throw std::invalid_argument ("Invalid parameter");
+
+ // Max size we can write
+ unsigned sizeToWrite = std::min (size, size_ - 1);
+
+ // Read data before overwrite it if needed
+ int sizeToRead = sizeToWrite - (size_ - maxReadableData ()) + 1;
+ if (sizeToRead > 0)
+ if (internalRead (0, sizeToRead) != (unsigned) sizeToRead)
+ throw std::runtime_error ("Unexpected error");
+
+ // Max size we can write until the end of the buffer
+ unsigned sizeToWriteEnd = std::min (size_ - endPos_, sizeToWrite);
+ // Write first part.
+ std::memcpy (&buffer_[endPos_], &data[size - sizeToWrite + 0], sizeToWriteEnd);
+ // More to write ?
+ unsigned sizeToWriteStart = sizeToWrite - sizeToWriteEnd;
+ if (sizeToWriteStart > 0)
+ {
+ std::memcpy (&buffer_[0], &data[size - sizeToWrite + sizeToWriteEnd], sizeToWriteStart);
+ endPos_ = 0 + sizeToWriteStart;
+ }
+ else
+ endPos_ = (endPos_ + sizeToWrite) % size_;
+}
+
+/// Swap data between tow DataCircularBuffer.
+void
+DataCircularBuffer::swap (DataCircularBuffer &d)
+{
+ std::swap (buffer_, d.buffer_);
+ std::swap (size_, d.size_);
+ std::swap (startPos_, d.startPos_);
+ std::swap (endPos_, d.endPos_);
+}
diff --git a/i/chuck/src/data/data_circular_buffer.hh b/i/chuck/src/data/data_circular_buffer.hh
new file mode 100644
index 0000000..f08426d
--- /dev/null
+++ b/i/chuck/src/data/data_circular_buffer.hh
@@ -0,0 +1,64 @@
+#ifndef data_circular_buffer_hh
+#define data_circular_buffer_hh
+// data_circular_buffer.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "data_input.hh"
+#include "data_output.hh"
+
+#include <stdint.h> // uint8_t
+
+class DataCircularBuffer : public DataInput, public DataOutput
+{
+ private:
+ /// Calculate the quantity of maximum data we can read.
+ unsigned maxReadableData (void)
+ { return (endPos_ + size_ - startPos_) % size_; }
+ /// Internal read, do the real job.
+ unsigned internalRead (uint8_t *data, unsigned size);
+ /// Buffer.
+ uint8_t *buffer_;
+ /// Size of the buffer.
+ unsigned size_;
+ /// Start and end positions of data in the buffer.
+ unsigned startPos_, endPos_;
+ public:
+ /// Default constructor.
+ /// Size is the allocated size in memory.
+ DataCircularBuffer (unsigned size);
+ /// Destructor.
+ ~DataCircularBuffer (void);
+ /// Read data of maximum size in the data pointer (data must be allocated
+ /// of size).
+ unsigned read (uint8_t *data, unsigned size);
+ /// Write data of size length.
+ void write (const uint8_t *data, unsigned size);
+ /// Size of the buffer.
+ unsigned size (void) const { return size_; }
+ /// Swap data between tow DataCircularBuffer.
+ void swap (DataCircularBuffer &d);
+};
+
+#endif // data_circular_buffer_hh
diff --git a/i/chuck/src/data/data_input.cc b/i/chuck/src/data/data_input.cc
new file mode 100644
index 0000000..cfc9b2a
--- /dev/null
+++ b/i/chuck/src/data/data_input.cc
@@ -0,0 +1,37 @@
+// data_input.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_input.hh"
+
+/// Lit un caractère. Renvois -1 en cas de fin de fichier.
+int
+DataInput::getc (void)
+{
+ uint8_t c;
+ if (read (&c, 1) == 1)
+ return c & 0xff;
+ else
+ return -1;
+}
+
diff --git a/i/chuck/src/data/data_input.hh b/i/chuck/src/data/data_input.hh
new file mode 100644
index 0000000..ae59366
--- /dev/null
+++ b/i/chuck/src/data/data_input.hh
@@ -0,0 +1,44 @@
+#ifndef data_input_hh
+#define data_input_hh
+// data_input.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <stdint.h>
+
+/// Classe d'entrée de données. C'est une sorte de istream simplifié
+/// permettant d'accéder à des données en lecture.
+class DataInput
+{
+ public:
+ /// Destructeur.
+ virtual ~DataInput (void) { }
+ /// Lit des données. Même convention que le read de la libc, mais lance
+ /// une exception en cas d'erreur.
+ virtual unsigned read (uint8_t *buf, unsigned size) = 0;
+ /// Lit un caractère. Renvois -1 en cas de fin de fichier.
+ int getc (void);
+};
+
+#endif // data_input_hh
diff --git a/i/chuck/src/data/data_input_file.cc b/i/chuck/src/data/data_input_file.cc
new file mode 100644
index 0000000..75b7500
--- /dev/null
+++ b/i/chuck/src/data/data_input_file.cc
@@ -0,0 +1,46 @@
+// data_input_file.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_input_file.hh"
+#include "utils/errno_exception.hh"
+
+/// Constructeur.
+DataInputFile::DataInputFile (const std::string &name)
+ : name_ (name), file_ (name.c_str ())
+{
+ if (!file_)
+ throw errno_exception (name_, errno);
+}
+
+/// Lit des données. Même convention que le read de la libc, mais lance
+/// une exception en cas d'erreur.
+unsigned
+DataInputFile::read (uint8_t *buf, unsigned size)
+{
+ file_.read (reinterpret_cast<char *> (buf), size);
+ if (file_.bad ())
+ throw errno_exception (name_, errno);
+ return file_.gcount ();
+}
+
diff --git a/i/chuck/src/data/data_input_file.hh b/i/chuck/src/data/data_input_file.hh
new file mode 100644
index 0000000..29d22ca
--- /dev/null
+++ b/i/chuck/src/data/data_input_file.hh
@@ -0,0 +1,45 @@
+#ifndef data_input_file_hh
+#define data_input_file_hh
+// data_input_file.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_input.hh"
+
+#include <string>
+#include <fstream>
+
+/// Data depuis un fichier standard.
+class DataInputFile : public DataInput
+{
+ std::string name_;
+ std::ifstream file_;
+ public:
+ /// Constructeur.
+ DataInputFile (const std::string &name);
+ /// Lit des données. Même convention que le read de la libc, mais lance
+ /// une exception en cas d'erreur.
+ unsigned read (uint8_t *buf, unsigned size);
+};
+
+#endif // data_input_file_hh
diff --git a/i/chuck/src/data/data_input_zlib.cc b/i/chuck/src/data/data_input_zlib.cc
new file mode 100644
index 0000000..f8f5322
--- /dev/null
+++ b/i/chuck/src/data/data_input_zlib.cc
@@ -0,0 +1,84 @@
+// data_input_zlib.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_input_zlib.hh"
+
+#include <stdexcept>
+
+/// Constructeur.
+DataInputZlib::DataInputZlib (DataInput &data)
+ : data_ (data), inBuf_ (0)
+{
+ // Allocate input buffer.
+ inBuf_ = new uint8_t[inBufSize_];
+ // Initialise the zlib structure.
+ zStream_.next_in = 0;
+ zStream_.avail_in = 0;
+ zStream_.next_out = 0;
+ zStream_.avail_out = 0;
+ zStream_.zalloc = 0;
+ zStream_.zfree = 0;
+ zStream_.opaque = 0;
+ if (inflateInit2 (&zStream_, 32 + 15) != Z_OK)
+ {
+ delete[] inBuf_;
+ throw std::runtime_error (zStream_.msg);
+ }
+}
+
+/// Destructeur.
+DataInputZlib::~DataInputZlib (void)
+{
+ inflateEnd (&zStream_);
+ delete[] inBuf_;
+}
+
+/// Lit des données. Même convention que le read de la libc, mais lance
+/// une exception en cas d'erreur.
+unsigned
+DataInputZlib::read (uint8_t *buf, unsigned size)
+{
+ // Set output buffer.
+ zStream_.next_out = buf;
+ zStream_.avail_out = size;
+ // While not satisfied.
+ while (zStream_.avail_out)
+ {
+ // Feed more data.
+ if (zStream_.avail_in == 0)
+ {
+ zStream_.next_in = inBuf_;
+ zStream_.avail_in = data_.read (inBuf_, inBufSize_);
+ }
+ // Uncompress.
+ int r = inflate (&zStream_, Z_SYNC_FLUSH);
+ // Check result.
+ if (r == Z_STREAM_END)
+ return size - zStream_.avail_out;
+ else if (r != Z_OK)
+ throw std::runtime_error (zStream_.msg);
+ }
+ return size;
+}
+
diff --git a/i/chuck/src/data/data_input_zlib.hh b/i/chuck/src/data/data_input_zlib.hh
new file mode 100644
index 0000000..0b7cf5f
--- /dev/null
+++ b/i/chuck/src/data/data_input_zlib.hh
@@ -0,0 +1,48 @@
+#ifndef data_input_zlib_hh
+#define data_input_zlib_hh
+// data_input_zlib.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_input.hh"
+
+#include <zlib.h>
+
+/// Data depuis un data compressé en zlib.
+class DataInputZlib : public DataInput
+{
+ DataInput &data_;
+ uint8_t *inBuf_;
+ static const unsigned inBufSize_ = 1024;
+ z_stream zStream_;
+ public:
+ /// Constructeur.
+ DataInputZlib (DataInput &data);
+ /// Destructeur.
+ ~DataInputZlib (void);
+ /// Lit des données. Même convention que le read de la libc, mais lance
+ /// une exception en cas d'erreur.
+ unsigned read (uint8_t *buf, unsigned size);
+};
+
+#endif // data_input_zlib_hh
diff --git a/i/chuck/src/data/data_output.cc b/i/chuck/src/data/data_output.cc
new file mode 100644
index 0000000..ed04e97
--- /dev/null
+++ b/i/chuck/src/data/data_output.cc
@@ -0,0 +1,34 @@
+// data_output.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_output.hh"
+
+/// Écrit un caractère.
+void
+DataOutput::putc (int c)
+{
+ uint8_t uc = c;
+ write (&uc, 1);
+}
+
diff --git a/i/chuck/src/data/data_output.hh b/i/chuck/src/data/data_output.hh
new file mode 100644
index 0000000..7141892
--- /dev/null
+++ b/i/chuck/src/data/data_output.hh
@@ -0,0 +1,44 @@
+#ifndef data_output_hh
+#define data_output_hh
+// data_output.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <stdint.h>
+
+/// Classe de sortie de données. C'est une sorte de ostream simplifié
+/// permettant d'accéder à des données en écriture.
+class DataOutput
+{
+ public:
+ /// Destructeur.
+ virtual ~DataOutput (void) { }
+ /// Écrit des données. Même convention que le write de la libc, mais lance
+ /// une exception en cas d'erreur.
+ virtual void write (const uint8_t *buf, unsigned size) = 0;
+ /// Écrit un caractère.
+ void putc (int c);
+};
+
+#endif // data_output_hh
diff --git a/i/chuck/src/data/test_data.cc b/i/chuck/src/data/test_data.cc
new file mode 100644
index 0000000..acc57ac
--- /dev/null
+++ b/i/chuck/src/data/test_data.cc
@@ -0,0 +1,56 @@
+// test_data.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_input_file.hh"
+#include "data_input_zlib.hh"
+
+#include <iostream>
+#include <stdexcept>
+#include <unistd.h>
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ if (argc != 2)
+ throw std::runtime_error ("Syntax: test_data file");
+ DataInputFile f (argv[1]);
+ DataInputZlib z (f);
+ uint8_t buf[1024];
+ int r = z.read (buf, 1024);
+ while (r != 0)
+ {
+ write (1, buf, r);
+ r = z.read (buf, r);
+ }
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/i/chuck/src/data/test_data_buffer.cc b/i/chuck/src/data/test_data_buffer.cc
new file mode 100644
index 0000000..36095ab
--- /dev/null
+++ b/i/chuck/src/data/test_data_buffer.cc
@@ -0,0 +1,77 @@
+// test_data_buffer.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+#include "data_buffer.hh"
+
+#include <iostream>
+#include <stdexcept>
+#include <unistd.h>
+
+void
+check_data (uint8_t *b1, uint8_t *b2, unsigned size)
+{
+ for (unsigned i = 0; i < size; i ++)
+ if (b1[i] != b2[i])
+ throw std::runtime_error ("Erreur, buffers invalides");
+}
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ DataBuffer d;
+ uint8_t bufW[100];
+ uint8_t bufR[150];
+ // Remplissage des buffers de test
+ memset (bufW, 42, 100);
+ memset (bufR, 1, 150);
+ // On en écrit 50
+ d.write (bufW, 50);
+ // On en lit 42
+ if (d.read (bufR, 42) == 42)
+ check_data (bufW, bufR, 42);
+ else
+ throw std::runtime_error ("Erreur de taille de données");
+ // On en re écrit 50
+ d.write (&bufW[50], 50);
+ unsigned pos = 42;
+ unsigned status;
+ // On lit jusqu'à la fin
+ do
+ {
+ status = d.read (&bufR[pos], 10);
+ if (status)
+ check_data (&bufW[pos], &bufR[pos], status);
+ pos += status;
+ } while (status);
+ // On vérifie que tout a été bien lue
+ }
+ catch (const std::runtime_error &r)
+ {
+ std::cerr << r.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/i/chuck/src/data/test_data_circular_buffer.cc b/i/chuck/src/data/test_data_circular_buffer.cc
new file mode 100644
index 0000000..9bdc063
--- /dev/null
+++ b/i/chuck/src/data/test_data_circular_buffer.cc
@@ -0,0 +1,92 @@
+// test_data_circular_buffer.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_circular_buffer.hh"
+
+#include <iostream>
+#include <stdexcept>
+#include <unistd.h>
+#include <time.h>
+
+#define MAX_SIZE_BUFF 101
+#define MAX_SIZE_CIRC 99
+
+unsigned
+randVal (double max)
+{
+ return 1 + (int) (max * std::rand () / (RAND_MAX + 1.0));
+}
+
+int
+main (void)
+{
+ // Init random
+ std::srand (std::time (NULL));
+ try
+ {
+ DataCircularBuffer d (MAX_SIZE_CIRC);
+ uint8_t buffOrig[MAX_SIZE_BUFF];
+ uint8_t buffRes[MAX_SIZE_BUFF];
+
+ int i, compt, tmp;
+ // Fill buffer
+ for (i = 0; i < MAX_SIZE_BUFF; i++)
+ memset (&buffOrig[i], i, 1);
+
+ // Fill circular buffer
+ compt = 0;
+ for (i = 0; i < 42; i++)
+ {
+ tmp = randVal (MAX_SIZE_BUFF - compt);
+ d.write (&buffOrig[compt], tmp);
+ compt = (tmp + compt) % MAX_SIZE_BUFF;
+ }
+
+ // Read
+ compt = 0;
+ unsigned res;
+ do
+ {
+ tmp = randVal (7.);
+ res = d.read (&buffRes[compt], tmp);
+ compt += tmp;
+ } while (res != 0);
+
+ // Compare
+ for (i = 0; i < MAX_SIZE_CIRC - 1; i++)
+ {
+ if (buffRes [i] != buffOrig [(buffRes[0] +i) % MAX_SIZE_BUFF])
+ throw std::runtime_error ("Test failed !");
+ }
+
+ }
+
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/i/chuck/src/es/Makefile.defs b/i/chuck/src/es/Makefile.defs
new file mode 100644
index 0000000..66a4e6f
--- /dev/null
+++ b/i/chuck/src/es/Makefile.defs
@@ -0,0 +1,5 @@
+PROGRAMS += test_es
+
+es_OBJECTS = es.o
+
+test_es_OBJECTS = test_es.o $(es_OBJECTS) $(tester_OBJECTS) $(proto_OBJECTS)
diff --git a/i/chuck/src/es/es.cc b/i/chuck/src/es/es.cc
new file mode 100644
index 0000000..66a8fc9
--- /dev/null
+++ b/i/chuck/src/es/es.cc
@@ -0,0 +1,752 @@
+// es.cc
+// robert - programme du robot 2005 {{{
+//
+// Copyright (C) 2005 Nicolas Haller
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "es/es.hh"
+#include "config/config.hh"
+
+#include <cstring>
+#include <iostream>
+
+/// Constructeur
+Es::Es (const Config & config)
+ : proto_ (*this), log_ ("Es"), lcdKeyPressed_ (-1), front_sensor_ (false),
+ jackIn_ (false), colorModeBlue_
+(false),positionBarillet_(avant0),frontTurbineIsFull_(false), unknownColor_
+(-2), redColor_ (2), blueColor_ (1), greenColor_ (0), whiteColor_ (5),
+ blackColor_ (4), leftFrontRVB_ (0), rightFrontRVB_ (1), holeRVB_ (2),
+ frontBallRVB_ (3), rearBallRVB_ (4)
+{
+ // Récupération des valeurs de configuration dans le fichier
+ loadConfig (config);
+ proto_.open (tty_);
+
+ sharps_.resize (3);
+ // Normalement, le barillet est vide...
+ for(int i = 0; i < 5 ; i++)
+ stockBarillet[i] = empty;
+
+ for (int compt = 0; compt < 5; compt++)
+ {
+ seenColors_[compt] = unknownColor_;
+ lastSeenColors_[compt] = unknownColor_;
+ comptSeenColors_[compt] = 0;
+ }
+}
+
+bool
+Es::wait (int timeout /*-1*/)
+{
+ return proto_.wait (timeout);
+}
+
+/// Récupère le File Descriptor
+int
+Es::getFd (void)
+{
+ return proto_.getFd();
+}
+
+bool Es::sync (void)
+{
+ return proto_.sync ();
+}
+
+void
+Es::loadConfig (const Config & config)
+{
+ tty_ = config.get<std::string>("es.tty");
+ ackFreq_ = config.get<int> ("es.ack_freq");
+ mainStat_ = config.get<int> ("es.main_stat");
+ rvbSensorFalseIC_ = config.get<int> ("es.rvb_sensors_false_ic");
+ rvbSensorMaxOv_ = config.get<int> ("es.rvb_sensors_max_ov");
+ rvbSniffRefRatio_ = config.get<int> ("es.rvb_sniff_ref_ratio");
+ rvbSniffGreenLimit_ = config.get<int> ("es.rvb_sniff_green_limit");
+ rvbSniffClearLimit_ = config.get<int> ("es.rvb_sniff_clear_limit");
+ rvbSensorMaskStat_ = config.get<int> ("es.rvb_sensor_mask_stat");
+ rvbSensorStat_ = config.get<int> ("es.rvb_sensor_stat");
+ rvbSniffMaskStat_ = config.get<int> ("es.rvb_sniff_mask_stat");
+ rvbSniffStat_ = config.get<int> ("es.rvb_sniff_stat");
+ rvbSniffFrontStat_ = config.get<int> ("es.rvb_sniff_front_stat");
+ rvbBallStat_ = config.get<int> ("es.rvb_ball_stat");
+ othersStat_ = config.get<int> ("es.others_stat");
+ lcdKeyStat_ = config.get<int> ("es.lcd_key_stat");
+ thresholdFrontSensors_ = config.get<int> ("es.threshold_front_sensors");
+ thresholdBallSensors_ = config.get<int> ("es.threshold_ball_sensors");
+ thresholdHoleSensors_ = config.get<int> ("es.threshold_hole_sensors");
+}
+
+void
+Es::reset (void)
+{
+ // On reset l'AVR
+ proto_.send ('z');
+
+ // First, enable all sensors
+ setRVBSensorsConfig (rvbSensorFalseIC_, rvbSensorMaxOv_);
+
+ // Send configurations
+ setMainStat (mainStat_);
+ setAckStat (ackFreq_);
+ setRVBSniffConfig (rvbSniffRefRatio_, rvbSniffGreenLimit_,
+ rvbSniffClearLimit_);
+ setRVBSensorsStat (rvbSensorMaskStat_, rvbSensorStat_);
+ setRVBSniffStat (rvbSniffMaskStat_, rvbSniffStat_);
+ setRVBBallStat (rvbBallStat_);
+ setOthersStat (othersStat_);
+ setRVBSniffFrontStat (rvbSniffFrontStat_);
+ lcdGetKey (lcdKeyStat_);
+
+ enableAllSensors (true);
+ log_ ("Es", Log::debug) << "Reset Es done.";
+}
+
+/// Stat for the main ()
+void
+Es::setMainStat (int freq)
+{
+ proto_.send ('Z', "b", freq);
+}
+
+/// Shut up !
+void
+Es::shutUp (void)
+{
+ proto_.send ('f');
+}
+
+/// Set frequency of ack
+void
+Es::setAckStat (int freq)
+{
+ ackFreq_ = freq;
+ proto_.send ('F', "b", ackFreq_);
+}
+
+/// Get the state of the jack
+bool
+Es::isJackOut (void)
+{
+ return !jackIn_;
+}
+
+/// Get the color mode of the button
+bool
+Es::isColorModeBlue (void)
+{
+ return colorModeBlue_;
+}
+
+// Envoie de la config des sensors RVB
+void Es::setRVBSensorsConfig(int false_ic, int max_ov)
+{
+ proto_.send ('p',"bb", false_ic, max_ov);
+}
+
+// Envoie de la config des sniff RVB
+void Es::setRVBSniffConfig (int ref_ratio, int green_limit, int clear_limit)
+{
+ proto_.send ('x', "bww", ref_ratio, green_limit, clear_limit);
+}
+
+// Règle les stats des sensors RVB
+void Es::setRVBSensorsStat(int mask_captor, int freq)
+{
+ proto_.send ('S', "wb", mask_captor, freq);
+}
+
+// règle la couleur actuelle comme référente
+void Es::refColor(int mask_captor, int mode)
+{
+ proto_.send ('r', "wb", mask_captor, mode);
+}
+
+/// Règle les stats d'affichage de la couleur
+void
+Es::setRVBSniffStat (int mask_captor, int freq)
+{
+ proto_.send ('A', "wb", mask_captor, freq);
+}
+
+/// Configure statistic for the sensor of the ball
+void
+Es::setRVBBallStat (int freq)
+{
+ proto_.send ('B', "b", freq);
+}
+
+/// Set frequency of front sensor in analyse mode
+void
+Es::setRVBSniffFrontStat (int freq)
+{
+ proto_.send ('C', "b", freq);
+}
+
+/// Enable all the sensors or just the 4 and 1 near the ground
+void
+Es::enableAllSensors (bool enable)
+{
+ if (enable)
+ proto_.send ('u', "b", 1);
+ else
+ proto_.send ('u', "b", 0);
+}
+
+/// Set frequency of jack, selectoul printed out function
+void
+Es::setOthersStat (int freq)
+{
+ proto_.send ('O', "b", freq);
+}
+
+// Discute avec les servo...
+void Es::setServoPos (int servo_mask, int servoPos)
+{
+ proto_.send ('m', "bb", servo_mask, servoPos);
+}
+
+/// Set update frequency of sharps
+void
+Es::setSharpUpdate (int sharp_mask, int freq)
+{
+ proto_.send ('h', "bb", sharp_mask, freq);
+}
+
+/// Set statistics frequency of sharps
+void
+Es::setSharpStat (int sharp_mask, int freq)
+{
+ proto_.send ('H', "bb", sharp_mask, freq);
+}
+
+/// Set configuration of threshold sharps
+void
+Es::setSharpThreshold (int sharp_num, int threshold_high,
+ int threshold_low)
+{
+ proto_.send ('o', "bww", sharp_num, threshold_high, threshold_low);
+}
+
+/// Print something on the LCD (max 16 char)
+void
+Es::lcdPrint (const std::string &message)
+{
+ std::memset (lcd_mess_char_, ' ', 16);
+ int size = message.size ();
+ std::memcpy (lcd_mess_char_, message.data (), size > 16 ? 16 : size);
+ proto_.sendStr ('l', lcd_mess_char_, 16);
+}
+
+/// Get the current pressed keys of the LCD
+void
+Es::lcdGetKey (int freq)
+{
+ proto_.send ('L', "b", freq);
+}
+
+// Règle la vitesse des turbines
+void Es::setTurbineSpeed(int turbNb, int speed)
+{
+ proto_.send ('v', "bw", turbNb, speed);
+}
+
+// Règle le sens de rotation du barillet
+void Es::setTheMeaningOfRotationOfBarillet(int answer)
+{
+ proto_.send ('w', "b", answer);
+}
+
+/// Init the barillet and put it at the right place
+void
+Es::barilletInit (void)
+{
+ proto_.send ('i');
+ frontTurbineIsFull_ = false;
+}
+
+/// Init turbine to minimal speed
+void Es::barilletDebutLancement (void)
+{
+ proto_.send ('g');
+ frontTurbineIsFull_ = false;
+}
+
+/// Init front turbine to full speed
+void Es::barilletLancement (void)
+{
+ proto_.send ('h');
+ frontTurbineIsFull_ = true;
+ log_ ("Es::Barillet", Log::debug) << "Lancement turbine avant.";
+}
+
+/// Put barillet in sleep mode
+void
+Es::barilletSleep (void)
+{
+ proto_.send ('s');
+ frontTurbineIsFull_ = false;
+}
+
+// Dépose une balle du barillet
+void
+Es::deposeBalle(void)
+{
+ proto_.send ('d');
+ barilletDebutLancement();
+ log_ ("Es::Barillet", Log::debug) << "DROP!! ";
+ frontTurbineIsFull_ = false;
+ wait (400);
+ barilletLancement();
+}
+
+/// Dépose une balle blanche
+bool
+Es::dropWhiteBall(void)
+{
+ for(int i = 0; i < 5; i++)
+ if(stockBarillet[i] == white)
+ {
+ log_ ("Es::Barillet", Log::debug) << "Balle blanche detected en trou: " << i;
+ switch (i)
+ {
+ case 0:
+ rotationBarillet(arriere0);
+ positionBarillet_ = arriere0;
+ stockBarillet[0] = empty;
+ break;
+ case 1:
+ rotationBarillet(arriere1);
+ positionBarillet_ = arriere1;
+ stockBarillet[1] = empty;
+ break;
+ case 2:
+ rotationBarillet(arriere2);
+ positionBarillet_ = arriere2;
+ stockBarillet[2] = empty;
+ break;
+ case 3:
+ rotationBarillet(arriere3);
+ positionBarillet_ = arriere3;
+ stockBarillet[3] = empty;
+ break;
+ case 4:
+ rotationBarillet(arriere4);
+ positionBarillet_ = arriere4;
+ stockBarillet[4] = empty;
+ break;
+ }
+ //deposeBalle();
+ return true;
+ }
+ return false;
+}
+
+/// Dépose une balle noire
+bool
+Es::dropBlackBall(void)
+{
+ for(int i = 0; i < 5; i++)
+ if(stockBarillet[i] == black)
+ {
+ log_ ("Es::Barillet", Log::debug) << "Balle noire detected en trou: " << i;
+ switch (i)
+ {
+ case 0:
+ rotationBarillet(arriere0);
+ positionBarillet_ = arriere0;
+ stockBarillet[0] = empty;
+ break;
+ case 1:
+ rotationBarillet(arriere1);
+ positionBarillet_ = arriere1;
+ stockBarillet[1] = empty;
+ break;
+ case 2:
+ rotationBarillet(arriere2);
+ positionBarillet_ = arriere2;
+ stockBarillet[2] = empty;
+ break;
+ case 3:
+ rotationBarillet(arriere3);
+ positionBarillet_ = arriere3;
+ stockBarillet[3] = empty;
+ break;
+ case 4:
+ rotationBarillet(arriere4);
+ positionBarillet_ = arriere4;
+ stockBarillet[4] = empty;
+ break;
+ }
+ //deposeBalle();
+ return true;
+ }
+ return false;
+}
+
+/// Place un trou vide à l'avant
+bool
+Es::setEmptyHoleFront(void)
+{
+ if(barilletIsFull())
+ return false;
+ for(int i = 0; i < 5; i++)
+ if(stockBarillet[i] == empty)
+ {
+ log_ ("Es::Barillet", Log::debug) << "vide detected en trou: " << i;
+ switch (i)
+ {
+ case 0:
+ rotationBarillet(avant0);
+ positionBarillet_ = avant0;
+ break;
+ case 1:
+ rotationBarillet(avant1);
+ positionBarillet_ = avant1;
+ break;
+ case 2:
+ rotationBarillet(avant2);
+ positionBarillet_ = avant2;
+ break;
+ case 3:
+ rotationBarillet(avant3);
+ positionBarillet_ = avant3;
+ break;
+ case 4:
+ rotationBarillet(avant4);
+ positionBarillet_ = avant4;
+ break;
+ }
+ return true;
+ }
+ return false;
+}
+/// Extrait une balle
+void
+Es::extraitBalle(void)
+{
+ proto_.send ('e');
+ frontTurbineIsFull_ = false;
+ log_ ("Es::Barillet", Log::debug) << "Extraction baballe.";
+}
+
+/// Rotation du barillet
+void Es::rotationBarillet(int posFinal)
+{
+ proto_.send ('t', "b", posFinal);
+ frontTurbineIsFull_ = false;
+}
+
+/// Empty everything in the barillet
+void Es::barilletEmpty (void)
+{
+ proto_.send ('n');
+ frontTurbineIsFull_ = false;
+}
+
+void Es::receive(char command, const Proto::Frame & frame)
+{
+ int errCode, red, blue, clear, green, compt, value;
+ int stat1, stat2, stat3, stat4;
+
+ switch (command)
+ {
+ /* Main stat */
+ case 'Z':
+ if (proto_.decode (frame, "bbbb", stat1, stat2, stat3, stat4))
+ {
+ log_ ("Stats main", Log::debug) << stat1 << " " << stat2 << " "
+ << stat3 << " " << stat4;
+ }
+ break;
+ /* Ack */
+ case 'F':
+ if (proto_.decode (frame, "b", errCode))
+ {
+ log_ ("Ack", Log::debug) << "ErrCode :" << errCode;
+ switch (errCode)
+ {
+ case 1:
+ front_sensor_ = true;
+ break;
+ case 2: // une balle miam par l'avant
+ newBallFront();
+ break;
+ case 3: // une balle miam par l'arrière
+ newBallRear();
+ break;
+ case 4:
+ // A ball has been by the sensor at the front of the barillet
+ enableAllSensors (true);
+ setRVBBallStat (5);
+ break;
+ }
+ shutUp ();
+ }
+ break;
+ /* RVB Sensors raw stat */
+ case 'S':
+ if (proto_.decode (frame, "wwwww", compt, red, blue, clear, green))
+ {
+ log_ ("Stats RVB Raw", Log::debug) << "[" << compt << "] = {"
+ << red << "," << blue << "," << clear << "," << green << "}";
+ }
+ break;
+ /* RVB Sniff stats */
+ case 'A':
+ if (proto_.decode (frame, "bb", compt, value))
+ {
+ log_ ("Stats RVB Sniff", Log::debug) << "[" << compt << "] = "
+ << decodeColor (value);
+ }
+ break;
+ case 'C':
+ if (proto_.decode (frame, "bb", stat1, stat2))
+ {
+ log_ ("Stats RVB Front", Log::debug) << decodeColor (stat1)
+ << " - " << decodeColor (stat2);
+ updateAnalysisSensor (stat2, leftFrontRVB_, thresholdFrontSensors_);
+ updateAnalysisSensor (stat1, rightFrontRVB_, thresholdFrontSensors_);
+ }
+ break;
+ /* RVB Hole */
+ case 'D':
+ if (proto_.decode (frame, "b", stat1))
+ {
+ log_ ("Stats RVB Hole", Log::debug) << decodeColor (stat1);
+ updateAnalysisSensor (stat1, holeRVB_, thresholdHoleSensors_);
+ }
+ break;
+ /* RVB Balls */
+ case 'B':
+ if (proto_.decode (frame, "bb", stat1 /* Rear */, stat2 /* Front */))
+ {
+// log_ ("Stats RVB Ball", Log::debug) << "[" << decodeColor
+// (stat1) << "] [" << decodeColor (stat2) << "]";
+ updateAnalysisSensor (stat1, rearBallRVB_, thresholdBallSensors_);
+ updateAnalysisSensor (stat2, frontBallRVB_, thresholdBallSensors_);
+ log_ ("Ball") << "Devant : " << (colorSeen (frontBallRVB_) ==
+ whiteColor_ ? "white" : "black") << " Arr : " << (colorSeen
+ (rearBallRVB_) == whiteColor_ ? "white" : "black");
+ }
+ break;
+ /* Others */
+ case 'O':
+ if (proto_.decode (frame, "b", value))
+ {
+ // XXX Use a decallage please
+ if (value & 0x01)
+ jackIn_ = true;
+ else
+ jackIn_ = false;
+ if (value & 0x02)
+ colorModeBlue_ = true;
+ else
+ colorModeBlue_ = false;
+// log_ ("Others", Log::debug) << "Color mode " << (colorModeBlue_ ? "Blue" : "Red")
+// << (jackIn_ ? ", jack in..." : ", jack out !!!");
+ }
+ break;
+ /* LCD */
+ case 'L':
+ if (proto_.decode (frame, "b", value))
+ lcdKeyPressed_ = value;
+ break;
+ /* Sharps */
+ case 'H':
+ if (proto_.decode (frame, "ww", compt, value))
+ {
+ std::cout << "[" << compt << "]" << " = " << value << std::endl;
+ sharps_[compt] = value;
+ }
+ break;
+ /* Barillet */
+ case 'W':
+ if (proto_.decode (frame, "bb", stat1, stat2))
+ {
+ log_ ("Barillet", Log::debug) << stat1 << " " << stat2;
+ }
+ break;
+ }
+}
+
+void Es::setRVBHoleStat (int freq)
+{
+ proto_.send ('D', "b", freq);
+}
+
+/// Decode a color into a string
+std::string
+Es::decodeColor (int color)
+{
+ switch (color)
+ {
+ case 0:
+ return "green";
+ break;
+ case 1:
+ return "blue";
+ break;
+ case 2:
+ return "red";
+ break;
+ case 3:
+ return "other";
+ break;
+ case 4:
+ return "black";
+ break;
+ case 5:
+ return "white";
+ break;
+ default:
+ return "unknow";
+ }
+}
+
+/// Analyse une balle arrivant par devant
+void
+Es::newBallFront(void)
+{
+ /// La turbine est off
+ frontTurbineIsFull_ = false;
+ /// On analyse la baballe
+ switch (positionBarillet_)
+ {
+ case avant0:
+ stockBarillet[0] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = avant4;
+ log_ ("Es::Barillet", Log::debug) << "trou 0:" << ((stockBarillet[0] == white)?"white":"pas white");
+ break;
+ case avant1:
+ stockBarillet[1] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = avant0;
+ log_ ("Es::Barillet", Log::debug) << "trou 1:" << ((stockBarillet[1] == white)?"white":"pas white");
+ break;
+ case avant2:
+ stockBarillet[2] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = avant1;
+ log_ ("Es::Barillet", Log::debug) << "trou 2:" << ((stockBarillet[2] == white)?"white":"pas white");
+ break;
+ case avant3:
+ stockBarillet[3] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = avant2;
+ log_ ("Es::Barillet", Log::debug) << "trou 3:" << ((stockBarillet[3] == white)?"white":"pas white");
+ break;
+ case avant4:
+ stockBarillet[4] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = avant3;
+ log_ ("Es::Barillet", Log::debug) << "trou 4:" << ((stockBarillet[4] == white)?"white":"pas white");
+ break;
+ default:
+ log_ ("Es::Barillet", Log::debug) << "trou default...";
+ break;
+ }
+ /// On regarde si on redémarre la turbine
+ if(!barilletIsFull())
+ barilletLancement();
+ log_ ("Es::Barillet", Log::debug) << "gobage balle par l'avant.";
+ enableAllSensors (false);
+ setRVBBallStat (0);
+}
+
+/// Analyse une balle arrivant par derrière
+void
+Es::newBallRear(void)
+{
+ /// On analyse la baballe
+ switch (positionBarillet_)
+ {
+ case arriere0:
+ stockBarillet[0] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = arriere4;
+ log_ ("Es::Barillet", Log::debug) << "trou 0";
+ break;
+ case arriere1:
+ stockBarillet[1] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = arriere0;
+ log_ ("Es::Barillet", Log::debug) << "trou 1";
+ break;
+ case arriere2:
+ stockBarillet[2] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = arriere1;
+ log_ ("Es::Barillet", Log::debug) << "trou 2";
+ break;
+ case arriere3:
+ stockBarillet[3] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = arriere2;
+ log_ ("Es::Barillet", Log::debug) << "trou 3";
+ break;
+ case arriere4:
+ stockBarillet[4] = ((colorSeen(frontBallRVB_))==whiteColor_)?white:white;
+ positionBarillet_ = arriere3;
+ log_ ("Es::Barillet", Log::debug) << "trou 4";
+ break;
+ default:
+ break;
+ }
+ log_ ("Es::Barillet", Log::debug) << "gobage balle par l'arriere.";
+ enableAllSensors (false);
+ setRVBBallStat (0);
+}
+
+/// Update system for one sensor
+void
+Es::updateAnalysisSensor (int value, int index, int threshold)
+{
+ if (value == lastSeenColors_[index])
+ comptSeenColors_[index]++;
+ else
+ {
+ comptSeenColors_[index] = 0;
+ lastSeenColors_[index] = value;
+ }
+ if (comptSeenColors_[index] > threshold)
+ seenColors_[index] = lastSeenColors_[index];
+}
+
+/// Say if barillet is full
+bool
+Es::barilletIsFull(void)
+{
+ for (int i = 0; i < 5; i++)
+ if (stockBarillet[i] == empty)
+ return false;
+ return true;
+}
+/// What color do you see my lord ?
+int
+Es::colorSeen (int sensor_num)
+{
+ return seenColors_[sensor_num];
+}
+
+/// Totems activator
+void
+Es::totemActivator (bool out)
+{
+ // Right
+ setServoPos (2, out ? 0 : 200);
+ // Left
+ setServoPos (4, out ? 200 : 0);
+}
diff --git a/i/chuck/src/es/es.hh b/i/chuck/src/es/es.hh
new file mode 100644
index 0000000..0a53ff3
--- /dev/null
+++ b/i/chuck/src/es/es.hh
@@ -0,0 +1,207 @@
+#ifndef es_hh
+#define es_hh
+// es.hh
+// robert - programme du robot 2005 {{{
+//
+// Copyright (C) 2005 Nicolas Haller
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "proto/proto.hh"
+
+#include <string>
+#include <vector>
+
+class Config;
+
+/// Gère la carte es et ses capteurs et actionneurs
+class Es : public Proto::Receiver
+{
+ public:
+ enum etatBarillet{empty,white,black};
+ enum posBar{avant0 = 0x00, arriere2 = 0x04, avant4 = 0x08, arriere1 =
+ 0x0C, avant3 = 0x10, arriere0 = 0x14, avant2 = 0x18, arriere4 = 0x1C,
+ avant1 = 0x20, arriere3 = 0x24};
+ typedef std::vector<int> Sharps;
+
+ private:
+ // Objet Proto de communication vers la carte es
+ Proto proto_;
+ // le tty est ...
+ std::string tty_;
+ /// Système de log
+ Log log_;
+ /// For LCD communication
+ char lcd_mess_char_[16];
+ /// Key pressed by the LCD Keyboard
+ int lcdKeyPressed_, lcdKeyStat_;
+ /// Frontal choc !
+ bool front_sensor_;
+ /// Ack frequency
+ int ackFreq_;
+ /// Main stat frequency
+ int mainStat_;
+ /// Config of RVB sensors
+ int rvbSensorFalseIC_, rvbSensorMaxOv_;
+ /// Config of RVB sniff
+ int rvbSniffRefRatio_, rvbSniffGreenLimit_, rvbSniffClearLimit_;
+ /// RVB Sensors raw stats
+ int rvbSensorMaskStat_, rvbSensorStat_;
+ /// RVB Sniff stats
+ int rvbSniffMaskStat_, rvbSniffStat_;
+ /// RVB Sensors raw stats
+ int rvbBallStat_;
+ /// Sharps
+ Sharps sharps_;
+ /// Others module, jack & colour
+ bool jackIn_, colorModeBlue_;
+ int othersStat_;
+ /// Stat of front sensors
+ int rvbSniffFrontStat_;
+ int thresholdFrontSensors_, thresholdBallSensors_, thresholdHoleSensors_;
+ /// Stock du barillet
+ etatBarillet stockBarillet[5];
+ /// Position du barillet
+ posBar positionBarillet_;
+ /// System for analyse a ball
+ int seenColors_[5], lastSeenColors_[5], comptSeenColors_[5];
+ /// Si la turbine avant est allumé
+ bool frontTurbineIsFull_;
+
+ public:
+ // Some fucking defines !
+ const int unknownColor_, redColor_, blueColor_, greenColor_, whiteColor_,
+ blackColor_;
+ const int leftFrontRVB_, rightFrontRVB_, holeRVB_, frontBallRVB_,
+ rearBallRVB_;
+ /// Constructeur
+ Es (const Config & config);
+ /// On attend ...
+ bool wait (int timeout = -1);
+ /// Récupère le File Descriptor
+ int getFd (void);
+ /// définition du receiver::receive
+ void receive (char command, const Proto::Frame & frame);
+ /// sync..
+ bool sync (void);
+ /// Charge les paramètre du fichier de config
+ void loadConfig (const Config & config);
+
+ /// Initialise les capteurs et actionneurs, reset
+ void reset (void);
+ /// Stat for the main ()
+ void setMainStat (int freq);
+ /// Shut up !
+ void shutUp (void);
+ /// Set frequency of ack
+ void setAckStat (int freq);
+ /// Get the state of the jack
+ bool isJackOut (void);
+ /// Get the color mode of the button
+ bool isColorModeBlue (void);
+
+ /// Envoie de la config des sensors RVB
+ void setRVBSensorsConfig(int false_ic, int max_ov);
+ /// Envoie de la config des sniff RVB
+ void setRVBSniffConfig(int ref_ratio, int green_limit, int clear_limit);
+ /// Règle les stats des sensors RVB
+ void setRVBSensorsStat(int mask_captor, int freq);
+ /// règle la couleur actuelle comme référente
+ void refColor(int mask_captor, int mode = 0);
+ /// Règle les stats d'affichage de la couleur
+ void setRVBSniffStat (int mask_captor, int freq);
+ /// Configure statistic for the sensor of the ball
+ void setRVBBallStat (int freq);
+ /// Set frequency of front sensor in analyse mode
+ void setRVBSniffFrontStat (int freq);
+ /// Enable all the sensors or just the 4 and 1 near the ground
+ void enableAllSensors (bool enable);
+ //
+ void setRVBHoleStat (int freq);
+
+ /// Set frequency of jack, selectoul printed out function
+ /// Use this function with frequency 0 to disable this stat.
+ void setOthersStat (int freq);
+
+ /// Discute avec les servo...
+ void setServoPos (int servo_mask, int servoPos);
+
+ /// Set update frequency of sharps
+ void setSharpUpdate (int sharp_mask, int freq);
+ /// Set statistics frequency of sharps
+ void setSharpStat (int sharp_mask, int freq);
+ /// Set configuration of threshold sharps
+ void setSharpThreshold (int sharp_num, int threshold_high,
+ int threshold_low);
+
+ /// Print something on the LCD (max 32 char)
+ void lcdPrint (const std::string &message);
+ /// Get the current pressed keys of the LCD
+ void lcdGetKey (int freq);
+
+ /// Règle la vitesse des turbines
+ void setTurbineSpeed (int turbNb, int speed);
+ /// Règle le sens de rotation du barillet
+ void setTheMeaningOfRotationOfBarillet (int answer);
+ /// Init the barillet and put it at the right place
+ void barilletInit (void);
+ /// Init turbine to minimal speed
+ void barilletDebutLancement (void);
+ /// Init front turbine to full speed
+ void barilletLancement (void);
+ /// Put barillet in sleep mode
+ void barilletSleep (void);
+ /// Dépose une balle du barillet
+ void deposeBalle(void);
+ /// Dépose une balle blanche
+ bool dropWhiteBall(void);
+ /// Dépose une balle noire
+ bool dropBlackBall(void);
+ /// Place un trou vide à l'avant
+ bool setEmptyHoleFront(void);
+ /// Extrait une balle
+ void extraitBalle(void);
+ /// Rotation du barillet
+ void rotationBarillet(int posFinal);
+ /// Empty everything in the barillet
+ void barilletEmpty (void);
+ /// Say if barillet is full
+ bool barilletIsFull(void);
+ /// What color do you see my lord ?
+ int colorSeen (int sensor_num);
+ /// Totems activator
+ void totemActivator (bool out);
+ /// Front sensor
+ bool frontSensor (void) { return front_sensor_; }
+ /// Clear sensor
+ void clearFrontSensor (void) { front_sensor_ = false; }
+
+ private:
+ /// Decode a color into a string
+ std::string decodeColor (int color);
+ /// Analyse une balle arrivant par devant
+ void newBallFront (void);
+ /// Analyse une balle arrivant par derrière
+ void newBallRear (void);
+ /// Update system for one sensor
+ void updateAnalysisSensor (int value, int index, int threshold);
+};
+#endif // es_hh
diff --git a/i/chuck/src/es/test_es.cc b/i/chuck/src/es/test_es.cc
new file mode 100644
index 0000000..2990d73
--- /dev/null
+++ b/i/chuck/src/es/test_es.cc
@@ -0,0 +1,156 @@
+// test_es.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Haller
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "tester/tester.hh"
+#include "es/es.hh"
+#include "timer/timer.hh"
+
+#include <iostream>
+
+class TestEs : public Tester
+{
+ private:
+ Es es_;
+ /// Called after each command called.
+ void postcall (void)
+ {
+ while (!es_.wait ())
+ ;
+ }
+ /// Wait.
+ void wait (int ms)
+ {
+ int t, stop;
+ t = Timer::getProgramTime ();
+ stop = t + ms;
+ while (t < stop)
+ {
+ es_.wait (stop - t);
+ t = Timer::getProgramTime ();
+ }
+ }
+ public:
+ // Constructor
+ TestEs (int argc, char ** argv)
+ : Tester (argc, argv), es_(config_) { }
+ void preRun (void)
+ {
+ Interpreter &interpreter = getInterpreter ();
+ // Add functions.
+ interpreter.add ("reset", Interpreter::memFunc (es_, &Es::reset),
+ "Reset ()");
+ interpreter.add ("wait", Interpreter::memFunc (*this, &TestEs::wait),
+ "Blocking wait (time)\n"
+ " - time : time to wait in ms");
+ interpreter.add
+ ("colorRef", Interpreter::memFunc (es_, &Es::refColor),
+ "Reference current color as green for sensors (mask)");
+ interpreter.add
+ ("rvbAll", Interpreter::memFunc (es_, &Es::enableAllSensors),
+ "Drop a ball at the rear ()");
+ interpreter.add
+ ("servoPos", Interpreter::memFunc (es_, &Es::setServoPos),
+ "Set servo position (mask, pos)");
+ interpreter.add
+ ("sharpUp", Interpreter::memFunc (es_, &Es::setSharpUpdate),
+ "Set sharp update frequency (mask, freq)");
+ interpreter.add
+ ("sharpStat", Interpreter::memFunc (es_, &Es::setSharpStat),
+ "Set sharp stats (mask, freq)");
+ interpreter.add
+ ("sharpThreshold", Interpreter::memFunc (es_, &Es::setSharpThreshold),
+ "Set sharp threshold (num, high, low)\n"
+ " - num : sharp number (1-3)\n"
+ " - high : high threshold\n"
+ " - low : low threshold");
+ interpreter.add
+ ("lcdPrint", Interpreter::memFunc (es_, &Es::lcdPrint),
+ "Print a message (32 char max) onto the LCD (message)");
+ interpreter.add
+ ("lcdKey", Interpreter::memFunc (es_, &Es::lcdGetKey),
+ "Set stat for key if pressed (freq)");
+ interpreter.add
+ ("turbSpeed", Interpreter::memFunc (es_, &Es::setTurbineSpeed),
+ "Set turbine speed (num, speed)\n"
+ " - num : 1 front, 2 rear\n"
+ " - speed : 256 - 819");
+ interpreter.add
+ ("turbMinSpeed", Interpreter::memFunc (es_,
+ &Es::barilletDebutLancement),
+ "Turbine minimal speed ()");
+ interpreter.add
+ ("turbFrontFull", Interpreter::memFunc (es_,
+ &Es::barilletLancement),
+ "Turbine front full speed ()");
+ interpreter.add
+ ("barSleep", Interpreter::memFunc (es_, &Es::barilletSleep),
+ "Barillet in sleep mode (low speed turbine)");
+ interpreter.add
+ ("turbDepose", Interpreter::memFunc (es_, &Es::deposeBalle),
+ "Drop a ball at the rear ()");
+ interpreter.add
+ ("barDropWhite", Interpreter::memFunc (es_, &Es::dropWhiteBall),
+ "drop une balle blanche");
+ interpreter.add("barDropBlack", Interpreter::memFunc (es_,
+ &Es::dropBlackBall),
+ "drop une balle noire");
+ interpreter.add("barSetEmpty", Interpreter::memFunc (es_,
+ &Es::setEmptyHoleFront),
+ "met un trou vide en position avale une balle");
+ interpreter.add
+ ("barExtract", Interpreter::memFunc (es_, &Es::extraitBalle),
+ "Extract a ball ()");
+ interpreter.add
+ ("barInit", Interpreter::memFunc (es_, &Es::barilletInit),
+ "Init barillet ()");
+ interpreter.add
+ ("barGoTo", Interpreter::memFunc (es_, &Es::rotationBarillet),
+ "Barillet go to position (pos)\n"
+ " - pos : in 40° of a round");
+ interpreter.add
+ ("barPurge", Interpreter::memFunc (es_, &Es::barilletEmpty),
+ "Extract a ball ()");
+ interpreter.add ("_postcall",
+ Interpreter::memFunc (*this, &TestEs::postcall));
+ }
+ void postRun (void)
+ {
+ es_.reset ();
+ }
+};
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ TestEs te (argc, argv);
+ te.run ();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ }
+}
diff --git a/i/chuck/src/interpreter/Makefile.defs b/i/chuck/src/interpreter/Makefile.defs
new file mode 100644
index 0000000..32c9e48
--- /dev/null
+++ b/i/chuck/src/interpreter/Makefile.defs
@@ -0,0 +1,6 @@
+PROGRAMS += test_interpreter
+
+interpreter_OBJECTS = interpreter.o interpreter_parser.o \
+ $(utils_OBJECTS) $(parser_OBJECTS)
+
+test_interpreter_OBJECTS = test_interpreter.o $(interpreter_OBJECTS)
diff --git a/i/chuck/src/interpreter/interpreter.cc b/i/chuck/src/interpreter/interpreter.cc
new file mode 100644
index 0000000..bbf4767
--- /dev/null
+++ b/i/chuck/src/interpreter/interpreter.cc
@@ -0,0 +1,127 @@
+// interpreter.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "interpreter.hh"
+#include "interpreter_parser.hh"
+
+/// Destructor.
+Interpreter::~Interpreter (void)
+{
+ for (Funcs::iterator i = funcs_.begin (); i != funcs_.end (); ++i)
+ {
+ delete i->second.func;
+ }
+}
+
+/// Add a function, Interpreter owns f.
+void
+Interpreter::add (const std::string &s, Func *f, const std::string &desc)
+{
+ if (!funcs_.insert (Funcs::value_type (s, FuncDesc (f, desc))).second)
+ {
+ // Interpreter owns f, therefore, f must be deleted.
+ delete f;
+ throw std::runtime_error ("function \'" + s
+ + "\' inserted two times");
+ }
+}
+
+/// Add a function without description, Interpreter owns f.
+void
+Interpreter::add (const std::string &s, Func *f)
+{
+ add (s, f, "");
+}
+
+/// Test if a function is defined.
+bool
+Interpreter::exists (const std::string &s) const
+{
+ Funcs::const_iterator i;
+ i = funcs_.find (s);
+ return i != funcs_.end ();
+}
+
+/// Call a function by name.
+void
+Interpreter::call (const std::string &s, const Args &a,
+ bool dryrun/*false*/) const
+{
+ Funcs::const_iterator i;
+ i = funcs_.find (s);
+ if (i == funcs_.end ())
+ throw std::runtime_error ("function \'" + s + "\' does not exist");
+ try
+ {
+ (*i->second.func) (a, dryrun);
+ }
+ catch (const std::exception &e)
+ {
+ throw std::runtime_error ("while calling \'" + s + "\', "
+ + e.what ());
+ }
+}
+
+/// Interpret a string.
+void
+Interpreter::interpretString (const std::string &s, bool dryrun/*false*/)
+{
+ InterpreterParser p (*this, dryrun);
+ p.parseString (s);
+}
+
+/// Interpret a file.
+void
+Interpreter::interpretFile (const std::string &file, bool dryrun/*false*/)
+{
+ InterpreterParser p (*this, dryrun);
+ p.parseFile (file);
+}
+
+/// Return an help string.
+std::string
+Interpreter::help (void) const
+{
+ std::string ret;
+ for (Funcs::const_iterator i = funcs_.begin (); i != funcs_.end (); ++i)
+ {
+ ret += i->first;
+ if (!i->second.desc.empty ())
+ {
+ ret += " : ";
+ // Well, if you really want to implement this better, please do...
+ for (std::string::const_iterator j = i->second.desc.begin ();
+ j != i->second.desc.end (); j++)
+ {
+ if (*j == '\n')
+ ret += "\n ";
+ else
+ ret += *j;
+ }
+ }
+ ret += '\n';
+ }
+ return ret;
+}
+
diff --git a/i/chuck/src/interpreter/interpreter.hh b/i/chuck/src/interpreter/interpreter.hh
new file mode 100644
index 0000000..3341ea1
--- /dev/null
+++ b/i/chuck/src/interpreter/interpreter.hh
@@ -0,0 +1,90 @@
+#ifndef interpreter_hh
+#define interpreter_hh
+// interpreter.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "utils/any.hh"
+
+#include <map>
+
+class Interpreter
+{
+ public:
+ /// Function arguments.
+ typedef any Arg;
+ /// Function arguments list.
+ typedef std::list<Arg> Args;
+ /// Functions must inherit from this type.
+ class Func
+ {
+ public:
+ /// Mandatory virtual destructor.
+ virtual ~Func (void)
+ { }
+ /// Called on function invocation, getting the argument list and
+ /// returning true on success.
+ virtual void operator() (const Args &, bool dryrun) = 0;
+ };
+ private:
+ /// Func class construction helper.
+ template<class T, typename F>
+ class MemFunc;
+ private:
+ struct FuncDesc
+ {
+ Func *func;
+ std::string desc;
+ FuncDesc (Func *func_, const std::string &desc_)
+ : func (func_), desc (desc_) { }
+ };
+ /// Type of the private function map.
+ typedef std::map<std::string, FuncDesc> Funcs;
+ /// The function map itself.
+ Funcs funcs_;
+ public:
+ /// Destructor.
+ ~Interpreter (void);
+ /// Add a function, Interpreter owns f.
+ void add (const std::string &s, Func *f, const std::string &desc);
+ /// Add a function without description, Interpreter owns f.
+ void add (const std::string &s, Func *f);
+ /// Test if a function is defined.
+ bool exists (const std::string &s) const;
+ /// Call a function by name.
+ void call (const std::string &s, const Args &a,
+ bool dryrun = false) const;
+ /// Interpret a string.
+ void interpretString (const std::string &s, bool dryrun = false);
+ /// Interpret a file.
+ void interpretFile (const std::string &file, bool dryrun = false);
+ /// Return an help string.
+ std::string help (void) const;
+ /// Take all the template sophistications out of the programmer hands.
+ template<class T, typename F>
+ static Func *memFunc (T &i, F f);
+};
+
+#include "interpreter.tcc"
+
+#endif // interpreter_hh
diff --git a/i/chuck/src/interpreter/interpreter.tcc b/i/chuck/src/interpreter/interpreter.tcc
new file mode 100644
index 0000000..5af0e0a
--- /dev/null
+++ b/i/chuck/src/interpreter/interpreter.tcc
@@ -0,0 +1,142 @@
+#ifndef interpreter_tcc
+#define interpreter_tcc
+// interpreter.tcc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "utils/meta/remove_reference.hh"
+
+#include <stdexcept>
+
+/// Func class construction helper.
+template<class T, typename F>
+class Interpreter::MemFunc
+{
+};
+
+/// Partially specialised for member functions taking an arguments list.
+template<class T>
+class Interpreter::MemFunc<T, void (T::*) (const Interpreter::Args &, bool)>
+: public Func
+{
+ T &i_;
+ typedef void (T::*F) (const Interpreter::Args &, bool);
+ F f_;
+ public:
+ MemFunc (T &i, F f) : i_ (i), f_ (f) { }
+ void operator() (const Args &a, bool dryrun)
+ {
+ (i_.*f_) (a, dryrun);
+ }
+};
+
+/// Partially specialised for members functions taking no argument.
+template<class T, typename R>
+class Interpreter::MemFunc<T, R (T::*) (void)> : public Func
+{
+ T &i_;
+ typedef R (T::*F) (void);
+ F f_;
+ public:
+ MemFunc (T &i, F f) : i_ (i), f_ (f) { }
+ void operator() (const Args &a, bool dryrun)
+ {
+ if (!a.empty ())
+ throw std::runtime_error ("no argument expected");
+ if (!dryrun)
+ (i_.*f_) ();
+ }
+};
+
+/// Partially specialised for members functions taking one argument.
+template<class T, typename A1, typename R>
+class Interpreter::MemFunc<T, R (T::*) (A1)> : public Func
+{
+ T &i_;
+ typedef R (T::*F) (A1);
+ F f_;
+ public:
+ MemFunc (T &i, F f) : i_ (i), f_ (f) { }
+ void operator() (const Args &a, bool dryrun)
+ {
+ Args::const_iterator i = a.begin ();
+ if (a.size () != 1)
+ throw std::runtime_error ("one argument expected");
+ A1 a1 = any_cast<typename meta::removeReference<A1>::type> (*i);
+ if (!dryrun)
+ (i_.*f_) (a1);
+ }
+};
+
+/// Partially specialised for members functions taking two arguments.
+template<class T, typename A1, typename A2, typename R>
+class Interpreter::MemFunc<T, R (T::*) (A1, A2)> : public Func
+{
+ T &i_;
+ typedef R (T::*F) (A1, A2);
+ F f_;
+ public:
+ MemFunc (T &i, F f) : i_ (i), f_ (f) { }
+ void operator() (const Args &a, bool dryrun)
+ {
+ Args::const_iterator i = a.begin ();
+ if (a.size () != 2)
+ throw std::runtime_error ("two arguments expected");
+ A1 a1 = any_cast<typename meta::removeReference<A1>::type> (*i);
+ A2 a2 = any_cast<typename meta::removeReference<A2>::type> (*++i);
+ if (!dryrun)
+ (i_.*f_) (a1, a2);
+ }
+};
+
+/// Partially specialised for members functions taking three arguments.
+template<class T, typename A1, typename A2, typename A3, typename R>
+class Interpreter::MemFunc<T, R (T::*) (A1, A2, A3)> : public Func
+{
+ T &i_;
+ typedef R (T::*F) (A1, A2, A3);
+ F f_;
+ public:
+ MemFunc (T &i, F f) : i_ (i), f_ (f) { }
+ void operator() (const Args &a, bool dryrun)
+ {
+ Args::const_iterator i = a.begin ();
+ if (a.size () != 3)
+ throw std::runtime_error ("three arguments expected");
+ A1 a1 = any_cast<typename meta::removeReference<A1>::type> (*i);
+ A2 a2 = any_cast<typename meta::removeReference<A2>::type> (*++i);
+ A3 a3 = any_cast<typename meta::removeReference<A3>::type> (*++i);
+ if (!dryrun)
+ (i_.*f_) (a1, a2, a3);
+ }
+};
+
+/// Take all the template sophistications out of the programmer hands.
+template<class T, typename F>
+Interpreter::Func *
+Interpreter::memFunc (T &i, F f)
+{
+ return new MemFunc<T, F> (i, f);
+}
+
+#endif // interpreter_tcc
diff --git a/i/chuck/src/interpreter/interpreter_parser.cc b/i/chuck/src/interpreter/interpreter_parser.cc
new file mode 100644
index 0000000..f10e8ec
--- /dev/null
+++ b/i/chuck/src/interpreter/interpreter_parser.cc
@@ -0,0 +1,43 @@
+// interpreter_parser.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "interpreter_parser.hh"
+#include "interpreter.hh"
+
+/// Constructor.
+InterpreterParser::InterpreterParser (Interpreter &interpreter,
+ bool dryrun/*false*/)
+ : interpreter_ (interpreter), dryrun_ (dryrun)
+{
+}
+
+/// Function called by the parser to make a call.
+void
+InterpreterParser::call (const std::string &id, AnyList &args)
+{
+ interpreter_.call (id, args, dryrun_);
+ if (interpreter_.exists ("_postcall"))
+ interpreter_.call ("_postcall", AnyList (), dryrun_);
+}
+
diff --git a/i/chuck/src/interpreter/interpreter_parser.hh b/i/chuck/src/interpreter/interpreter_parser.hh
new file mode 100644
index 0000000..3bd256d
--- /dev/null
+++ b/i/chuck/src/interpreter/interpreter_parser.hh
@@ -0,0 +1,43 @@
+#ifndef interpreter_parser_hh
+#define interpreter_parser_hh
+// interpreter_parser.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "parser/parser.hh"
+
+class Interpreter;
+
+/// Parser used by Interpreter.
+class InterpreterParser : public Parser
+{
+ Interpreter &interpreter_;
+ bool dryrun_;
+ public:
+ /// Constructor.
+ InterpreterParser (Interpreter &interpreter, bool dryrun = false);
+ /// Function called by the parser to make a call.
+ void call (const std::string &id, AnyList &args);
+};
+
+#endif // interpreter_parser_hh
diff --git a/i/chuck/src/interpreter/test_interpreter.cc b/i/chuck/src/interpreter/test_interpreter.cc
new file mode 100644
index 0000000..631d10d
--- /dev/null
+++ b/i/chuck/src/interpreter/test_interpreter.cc
@@ -0,0 +1,139 @@
+// test_interpreter.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "interpreter.hh"
+
+#include <iostream>
+#include <algorithm>
+#include <iterator>
+
+class TestInterpreter
+{
+ Interpreter t;
+ public:
+ void funcA (const Interpreter::Args &a, bool dryrun)
+ {
+ if (!dryrun)
+ std::cout << " a " << a << std::endl;
+ }
+ bool funcB (void)
+ {
+ std::cout << " b ( )" << std::endl;
+ return true;
+ }
+ int funcC (int i)
+ {
+ std::cout << " c ( " << i << " )" << std::endl;
+ return 0;
+ }
+ void funcD (const std::string &s)
+ {
+ std::cout << " d ( " << s << " )" << std::endl;
+ }
+ void funcE (int i, const std::string &s, double d)
+ {
+ std::cout << " e ( " << i << ' ' << s << ' ' << d << " )" << std::endl;
+ }
+ void call (const std::string &s, const Interpreter::Args &a)
+ {
+ try
+ {
+ std::cout << "call " << s << ' ' << a << std::endl;
+ t.call (s, a);
+ }
+ catch (const std::exception &e)
+ {
+ // Do not use std::cerr as there should be only normal errors.
+ std::cout << ' ' << e.what () << std::endl;
+ }
+ }
+ void interpretString (const std::string &s)
+ {
+ try
+ {
+ std::cout << "interpret dry \"" << s << "\"" << std::endl;
+ t.interpretString (s, true);
+ std::cout << "interpret \"" << s << "\"" << std::endl;
+ t.interpretString (s);
+ }
+ catch (const std::exception &e)
+ {
+ // Do not use std::cerr as there should be only normal errors.
+ std::cout << ' ' << e.what () << std::endl;
+ }
+ }
+ int main (void)
+ {
+ // Add functions.
+ t.add ("a", Interpreter::memFunc (*this, &TestInterpreter::funcA),
+ "a ARGS...\n"
+ "the wonderful `a' function taking any number of any arguments");
+ t.add ("b", Interpreter::memFunc (*this, &TestInterpreter::funcB),
+ "b\ntakes no argument");
+ t.add ("c", Interpreter::memFunc (*this, &TestInterpreter::funcC),
+ "c THE_MIGHTY_NUMBER\n"
+ "takes one integer");
+ t.add ("d", Interpreter::memFunc (*this, &TestInterpreter::funcD),
+ "d THE_STRING\n"
+ "takes one string");
+ t.add ("e", Interpreter::memFunc (*this, &TestInterpreter::funcE),
+ "e INT STRING DOUBLE\n"
+ "takes one integer, one string and one double");
+ // Make argument lists.
+ Interpreter::Args a[4];
+ a[1].push_back (71117);
+ a[2].push_back (std::string ("robert"));
+ a[3].push_back (42);
+ a[3].push_back (std::string ("merguez"));
+ a[3].push_back (51.1664);
+ // Need help?
+ std::cout << t.help () << std::endl;
+ // Call all those wonderful functions.
+ call ("unknown", a[0]);
+ for (unsigned int i = 0; i < sizeof (a) / sizeof (a[0]); ++i)
+ {
+ for (char f = 'a'; f <= 'e'; f++)
+ {
+ call (std::string (1, f), a[i]);
+ }
+ }
+ // Now, with the interpreter.
+ interpretString ("a = 42");
+ interpretString ("42");
+ for (char f = 'a'; f <= 'e'; f++)
+ {
+ interpretString (std::string (1, f));
+ interpretString (std::string (1, f) + " 42 ");
+ interpretString (std::string (1, f) + " \"robert\";; ");
+ interpretString (std::string (1, f) + " 757 \"tintin\" 0.3141516e+1");
+ }
+ return 0;
+ }
+};
+
+int main (void)
+{
+ TestInterpreter tt;
+ return tt.main ();
+}
diff --git a/i/chuck/src/log/Makefile.defs b/i/chuck/src/log/Makefile.defs
new file mode 100644
index 0000000..43aaed4
--- /dev/null
+++ b/i/chuck/src/log/Makefile.defs
@@ -0,0 +1,12 @@
+PROGRAMS += test_log test_log_server
+
+log_server_OBJECTS = log_server.o $(socket_databuffer_OBJECTS)
+
+log_OBJECTS = log.o log_message.o logger.o \
+ logger_stdout.o logger_file.o logger_ram.o \
+ data_circular_buffer_factory.o \
+ $(log_server_OBJECTS) \
+ $(config_OBJECTS) $(data_OBJECTS)
+
+test_log_OBJECTS = test_log.o $(log_OBJECTS)
+test_log_server_OBJECTS = test_log_server.o $(log_server_OBJECTS) $(data_OBJECTS)
diff --git a/i/chuck/src/log/data_circular_buffer_factory.cc b/i/chuck/src/log/data_circular_buffer_factory.cc
new file mode 100644
index 0000000..a45d3bc
--- /dev/null
+++ b/i/chuck/src/log/data_circular_buffer_factory.cc
@@ -0,0 +1,72 @@
+// data_circular_buffer_factory.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_circular_buffer_factory.hh"
+#include "log_server.hh"
+
+#include <iostream>
+
+/// Initialisation of static member.
+DataCircularBuffer *DataCircularBufferFactory::dbBuffer_ = 0;
+unsigned DataCircularBufferFactory::refCount_ = 0;
+
+/// Default empty constructor.
+DataCircularBufferFactory::DataCircularBufferFactory (void)
+{
+ refCount_++;
+}
+/// Destructor.
+DataCircularBufferFactory::~DataCircularBufferFactory (void)
+{
+ refCount_--;
+ // End of use ?
+ if (!refCount_ && dbBuffer_)
+ {
+ // XXX Create a server in a try/catch block for removing exception.
+ try
+ {
+ LogServer(*dbBuffer_, "", 2442);
+ }
+ catch(std::exception & ex)
+ {
+ std::cout << ex.what() << std::endl;
+ }
+// uint8_t c;
+// while (dbBuffer_-> read (&c, 1))
+// std::cout << c;
+ delete dbBuffer_;
+ dbBuffer_ = 0;
+ }
+}
+
+/// Get a DataCircularBuffer.
+DataCircularBuffer &
+DataCircularBufferFactory::getDataCircularBuffer (void)
+{
+ if (!dbBuffer_)
+ // 100Ko
+ // TODO: config ?
+ dbBuffer_ = new DataCircularBuffer (100000);
+ return *dbBuffer_;
+}
diff --git a/i/chuck/src/log/data_circular_buffer_factory.hh b/i/chuck/src/log/data_circular_buffer_factory.hh
new file mode 100644
index 0000000..8f0874f
--- /dev/null
+++ b/i/chuck/src/log/data_circular_buffer_factory.hh
@@ -0,0 +1,53 @@
+#ifndef data_circular_buffer_factory_hh
+#define data_circular_buffer_factory_hh
+// data_circular_buffer_factory.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "data/data_circular_buffer.hh"
+
+/// The purpose of this class is to provide a factory of data_circular_buffer.
+/// In fact, we will create only one data_circula_buffer and we provide a
+/// reference to this one to logger_ram. When the data_circular_buffer will be
+/// deleted, we will launch a socket server for fetching data remotely with a
+/// netcat.
+
+class DataCircularBufferFactory
+{
+ friend class LoggerRam;
+ friend class Tester;
+ private:
+ /// The only DataCircularBuffer.
+ static DataCircularBuffer *dbBuffer_;
+ /// Reference counter.
+ static unsigned refCount_;
+ /// Default empty constructor.
+ DataCircularBufferFactory (void);
+ /// Destructor.
+ ~DataCircularBufferFactory (void);
+ /// Get a DataCircularBuffer.
+ DataCircularBuffer & getDataCircularBuffer (void);
+};
+
+#endif // data_circular_buffer_factory_hh
diff --git a/i/chuck/src/log/log.cc b/i/chuck/src/log/log.cc
new file mode 100644
index 0000000..cd7bb32
--- /dev/null
+++ b/i/chuck/src/log/log.cc
@@ -0,0 +1,130 @@
+// log.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "log.hh"
+
+#include "config/config.hh"
+#include "logger.hh"
+
+#include <string>
+
+/// Constructeur.
+Log::Log (const char *module, const char *instance)
+ : module_ (module), instance_ (instance)
+{
+ // Get Config
+ Config &config = Config::getInstance ();
+ // Get default level log
+ std::string defaultLvl = config.get<std::string>("log.level.default",
+ "info");
+ level_ = toLevel (defaultLvl);
+ // Get private level if exist
+ level_ = toLevel (config.get<std::string>
+ (std::string ("log.level.") + module_, defaultLvl));
+
+ // Create the null logger
+ loggerNull_ = Logger::create ("null");
+ // Create the real logger
+ logger_ = Logger::create (config.get<std::string>
+ (std::string ("log.logger.") + module_,
+ config.get<std::string>
+ (std::string ("log.logger.default"), "stdout")));
+}
+
+Log::~Log (void)
+{
+ delete loggerNull_;
+ delete logger_;
+}
+
+/// Crée un nouveau LogMessage.
+LogMessage
+Log::operator() (const char *msg, Level level/*info*/) const
+{
+ // Check level
+ if (level <= getLevel())
+ // Use real logger
+ return LogMessage (*this, *logger_, msg, level);
+ else
+ // Use null logger
+ return LogMessage (*this, *loggerNull_, msg, level);
+}
+
+/// Traduit le niveau de log.
+std::string
+Log::toString (Level level)
+{
+ switch (level)
+ {
+ case none:
+ return "none";
+ case fatal:
+ return "fatal";
+ case error:
+ return "error";
+ case warning:
+ return "warning";
+ case info:
+ return "info";
+ case debug:
+ return "debug";
+ case verydebug:
+ return "verydebug";
+ default:
+ return "logunknown";
+ }
+}
+
+/// Traduit le niveau de log.
+Log::Level
+Log::toLevel (const std::string &level)
+{
+ switch (level[0])
+ {
+ case 'n':
+ return none;
+ case 'f':
+ return fatal;
+ case 'e':
+ return error;
+ case 'w':
+ return warning;
+ case 'i':
+ return info;
+ case 'd':
+ return debug;
+ case 'v':
+ return verydebug;
+ default:
+ return levelReserved;
+ }
+}
+
+/// Change un niveau de log en masque.
+Log::Level
+Log::toLevelMask (Log::Level level)
+{
+ return static_cast <Level> ((level - 1) | level);
+}
+
diff --git a/i/chuck/src/log/log.hh b/i/chuck/src/log/log.hh
new file mode 100644
index 0000000..1141962
--- /dev/null
+++ b/i/chuck/src/log/log.hh
@@ -0,0 +1,82 @@
+#ifndef log_hh
+#define log_hh
+// log.h
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include <string>
+#include <iostream>
+
+class LogMessage;
+class Logger;
+
+/// Classe de log. Permet de construire des LogMessage.
+class Log
+{
+ public:
+ enum Level
+ {
+ none = 0x00,
+ fatal = 0x01,
+ error = 0x02,
+ warning = 0x04,
+ info = 0x08,
+ debug = 0x10,
+ verydebug = 0x20,
+ levelReserved = 0xffff
+ };
+ private:
+ const char *module_;
+ const char *instance_;
+ Level level_;
+ /// Null logger.
+ Logger *loggerNull_;
+ /// Real logger.
+ Logger *logger_;
+
+ public:
+ /// Constructeur.
+ Log (const char *module, const char *instance = 0);
+ /// Destructor.
+ ~Log (void);
+ /// Crée un nouveau LogMessage.
+ LogMessage operator() (const char *msg, Level level = info) const;
+ /// Récupère le module.
+ const char *getModule (void) const { return module_; }
+ /// Récupère l'instance.
+ const char *getInstance (void) const { return instance_; }
+ /// Traduit le niveau de log.
+ static std::string toString (Level level);
+ /// Traduit le niveau de log.
+ static Level toLevel (const std::string &level);
+ /// Change un niveau de log en masque.
+ static Level toLevelMask (Level level);
+ /// Récupère le niveau de log
+ Level getLevel(void) const { return level_; }
+ /// Set le niveau de log
+ void setLevel(Level level) { level_ = level; }
+};
+
+#include "log_message.hh"
+
+#endif // log_hh
diff --git a/i/chuck/src/log/log_message.cc b/i/chuck/src/log/log_message.cc
new file mode 100644
index 0000000..4305374
--- /dev/null
+++ b/i/chuck/src/log/log_message.cc
@@ -0,0 +1,74 @@
+// log_message.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "log_message.hh"
+
+#include <iostream>
+
+/// Constructeur.
+LogMessage::LogMessage (const Log &log, Logger &logger, const char *msg,
+ Log::Level level)
+: logger_ (logger)
+{
+ logger_.start (log, msg, level);
+}
+
+/// Destructeur.
+LogMessage::~LogMessage (void)
+{
+ logger_.stop ();
+}
+
+/// Output a string or a variable name.
+LogMessage &
+LogMessage::operator<< (const char *s)
+{
+ logger_ << s;
+ return *this;
+}
+
+/// Output a string or a variable name.
+LogMessage &
+LogMessage::operator<< (const std::string &s)
+{
+ logger_ << s;
+ return *this;
+}
+
+/// Output a integer.
+LogMessage &
+LogMessage::operator<< (int i)
+{
+ logger_ << i;
+ return *this;
+}
+
+/// Output a double.
+LogMessage &
+LogMessage::operator<< (double d)
+{
+ logger_ << d;
+ return *this;
+}
+
diff --git a/i/chuck/src/log/log_message.hh b/i/chuck/src/log/log_message.hh
new file mode 100644
index 0000000..718e6ae
--- /dev/null
+++ b/i/chuck/src/log/log_message.hh
@@ -0,0 +1,55 @@
+#ifndef log_message_hh
+#define log_message_hh
+// log_message.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "log.hh"
+#include "logger.hh"
+
+class LogMessage
+{
+ private:
+ Logger &logger_;
+ public:
+ /// Constructeur.
+ LogMessage (const Log &log, Logger &logger, const char *msg, Log::Level level);
+ /// Destructeur.
+ ~LogMessage (void);
+ /// Output a string or a variable name.
+ LogMessage &operator<< (const char *s);
+ /// Output a string or a variable name.
+ LogMessage &operator<< (const std::string &s);
+ /// Output a integer.
+ LogMessage &operator<< (int i);
+ /// Output a double.
+ LogMessage &operator<< (double d);
+ /// Output a OutputStreamable as a string.
+ template<typename OutputStreamable>
+ LogMessage &operator<< (const OutputStreamable &o);
+};
+
+#include "log_message.tcc"
+
+#endif // log_message_hh
diff --git a/i/chuck/src/log/log_message.tcc b/i/chuck/src/log/log_message.tcc
new file mode 100644
index 0000000..4928d59
--- /dev/null
+++ b/i/chuck/src/log/log_message.tcc
@@ -0,0 +1,36 @@
+// log_message.tcc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <iostream>
+
+/// Output a OutputStreamable as a string.
+template<typename OutputStreamable>
+LogMessage &
+LogMessage::operator<< (const OutputStreamable &o)
+{
+ logger_ << o;
+ return *this;
+}
+
diff --git a/i/chuck/src/log/log_server.cc b/i/chuck/src/log/log_server.cc
new file mode 100644
index 0000000..126ed66
--- /dev/null
+++ b/i/chuck/src/log/log_server.cc
@@ -0,0 +1,54 @@
+// log_server.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Haller
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "log_server.hh"
+#include "socket/socket_client.hh"
+
+LogServer::LogServer(DataInput & di, const Address & address)
+ :ss_(address),di_(di)
+{
+}
+
+LogServer::LogServer(DataInput & di, const std::string & address,
+ int port)
+ :ss_(address, port),di_(di)
+{
+}
+
+void
+LogServer::listen(void)
+{
+ int charBuffer;
+
+ const unsigned BUFFER_SIZE = 256;
+ // Buffer de taille completement arbitraire
+ uint8_t buffer[BUFFER_SIZE];
+ // Ouvre les oreilles du socket
+ ss_.listen(1);
+ // Attend gentillement une connection
+ SocketClient sc(ss_);
+ // Paf on envoie la sauce
+ while((charBuffer = di_.read(buffer, BUFFER_SIZE)) != 0)
+ sc.write(buffer, charBuffer);
+}
diff --git a/i/chuck/src/log/log_server.hh b/i/chuck/src/log/log_server.hh
new file mode 100644
index 0000000..a18de15
--- /dev/null
+++ b/i/chuck/src/log/log_server.hh
@@ -0,0 +1,50 @@
+#ifndef log_server_hh
+#define log_server_hh
+// log_server.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Haller
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "socket/socket_server.hh"
+#include "data/data_input.hh"
+
+/// Classe pour récupérer les logs.
+/// La classe construit un serveur en fin de match pour pouvoir récupérer les
+/// logs de la pc104
+class LogServer
+{
+ private:
+ /// La socket serveur qui attend la ze connection
+ SocketServer ss_;
+ /// La dataBuffer à transmettre (avec les logs dedans c'est mieux)
+ DataInput & di_;
+ public:
+ /// Constructeur
+ LogServer(DataInput & di, const Address & address);
+ /// Constructeur
+ LogServer(DataInput & di, const std::string & address, int port);
+ /// Mise en écoute du serveur
+ void listen(void);
+};
+
+#endif // log_server_hh
diff --git a/i/chuck/src/log/logger.cc b/i/chuck/src/log/logger.cc
new file mode 100644
index 0000000..128aa16
--- /dev/null
+++ b/i/chuck/src/log/logger.cc
@@ -0,0 +1,52 @@
+// logger.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+#include "logger.hh"
+
+#include "logger_null.hh"
+#include "logger_stdout.hh"
+#include "logger_file.hh"
+#include "logger_ram.hh"
+
+#include <stdexcept>
+
+/// Create a logger from the name.
+Logger *
+Logger::create (const std::string &loggerName)
+{
+ if (loggerName == "null")
+ return new LoggerNull;
+ else if (loggerName == "stdout")
+ return new LoggerStdout;
+ else if (loggerName.substr (0, 4) == "file")
+ if (loggerName.size () < 6)
+ throw std::runtime_error ("Missing filename");
+ else
+ return new LoggerFile (loggerName.substr (5));
+ else
+ if (loggerName.substr (0, 3) == "ram")
+ return new LoggerRam;
+ throw std::invalid_argument ("Unknown logger : " + loggerName);
+ return 0;
+}
+
diff --git a/i/chuck/src/log/logger.hh b/i/chuck/src/log/logger.hh
new file mode 100644
index 0000000..cc47095
--- /dev/null
+++ b/i/chuck/src/log/logger.hh
@@ -0,0 +1,68 @@
+#ifndef logger_hh
+#define logger_hh
+// logger.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+#include "log.hh"
+
+#include <string>
+
+class Logger
+{
+ public:
+ /// Empty destructor.
+ virtual ~Logger (void) { }
+ /// Create a logger.
+ static Logger *create (const std::string &loggerName);
+ /// Called when a message will be logged.
+ virtual void start (const Log &log, const char *msg, Log::Level level) = 0;
+ /// Called when a message has been logged.
+ virtual void stop (void) = 0;
+ /// Output a string or a variable name.
+ virtual Logger &operator<< (const char *s) = 0;
+ /// Output a string or a variable name.
+ virtual Logger &operator<< (const std::string &s) = 0;
+ /// Output a integer.
+ virtual Logger &operator<< (int i) = 0;
+ /// Output a double.
+ virtual Logger &operator<< (double d) = 0;
+ /// TODO vector
+
+ protected:
+ /// Private empty constructor.
+ Logger (void) { }
+};
+
+#include <sstream>
+
+template<typename T>
+Logger &operator<< (Logger &l, const T &v)
+{
+ std::ostringstream ss;
+ ss << v;
+ l << ss.str ();
+ return l;
+}
+
+#endif // logger_hh
diff --git a/i/chuck/src/log/logger_file.cc b/i/chuck/src/log/logger_file.cc
new file mode 100644
index 0000000..011a470
--- /dev/null
+++ b/i/chuck/src/log/logger_file.cc
@@ -0,0 +1,144 @@
+// logger_file.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "logger_file.hh"
+
+#include <stdexcept>
+#include <fstream>
+#include <iostream>
+
+LoggerFile::t_files_ LoggerFile::files_;
+
+/// Default constructor.
+LoggerFile::LoggerFile (const std::string &param)
+ : filename_ (param)
+{
+ if (param.empty ())
+ throw std::invalid_argument ("Missing filename for file logger");
+ file_ = getFile ();
+}
+
+/// Default destructor.
+LoggerFile::~LoggerFile (void)
+{
+ try
+ {
+ releaseFile ();
+ }
+ catch (std::runtime_error &)
+ {
+ }
+}
+
+/// Get a ofstream associated to the filename.
+/// This function manage multiple log to the same file by couting the number
+/// reference to the file.
+std::ofstream *
+LoggerFile::getFile (void)
+{
+ t_files_::iterator i = files_.find (filename_);
+ // If file does not exist
+ if (i == files_.end ())
+ {
+ // Create it
+ std::ofstream *file = new std::ofstream (filename_.c_str ());
+ // Add it
+ files_[filename_] = t_pair_files_ (1, file);
+ return file;
+ }
+ else
+ {
+ // Increment number of reference
+ t_pair_files_ &pair_file = i->second;
+ pair_file.first++;
+ return pair_file.second;
+ }
+}
+
+/// Release the file from the map if needed. Return true if deleted.
+bool
+LoggerFile::releaseFile (void)
+{
+ t_files_::iterator i = files_.find (filename_);
+ // If file does not exist
+ if (i == files_.end ())
+ throw std::runtime_error ("Trying to release an unknown file ?!");
+ else
+ {
+ t_pair_files_ &pair_file = i->second;
+ // Decrement number of reference
+ pair_file.first--;
+ // Delete it if needed
+ if (pair_file.first == 0)
+ {
+ delete pair_file.second;
+ files_.erase (i);
+ return true;
+ }
+ }
+ return false;
+}
+
+/// Called at the begining of a message.
+void
+LoggerFile::start (const Log &log, const char *msg, Log::Level level)
+{
+ *file_ << log.getModule () << ':';
+ const char *instance = log.getInstance ();
+ if (instance)
+ *file_ << ' ' << instance << ':';
+ *file_ << " (" << msg << ')';
+}
+
+/// Output a string or a variable name.
+LoggerFile &
+LoggerFile::operator<< (const char *s)
+{
+ *file_ << ' ' << s;
+ return *this;
+}
+
+/// Output a string or a variable name.
+LoggerFile &
+LoggerFile::operator<< (const std::string &s)
+{
+ *file_ << ' ' << s;
+ return *this;
+}
+
+/// Output a integer.
+LoggerFile &
+LoggerFile::operator<< (int i)
+{
+ *file_ << ' ' << i;
+ return *this;
+}
+
+/// Output a double.
+LoggerFile &
+LoggerFile::operator<< (double d)
+{
+ *file_ << ' ' << d;
+ return *this;
+}
diff --git a/i/chuck/src/log/logger_file.hh b/i/chuck/src/log/logger_file.hh
new file mode 100644
index 0000000..2cfd4d4
--- /dev/null
+++ b/i/chuck/src/log/logger_file.hh
@@ -0,0 +1,70 @@
+#ifndef logger_file_hh
+#define logger_file_hh
+// logger_file.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "logger.hh"
+
+#include <string>
+#include <map>
+#include <fstream>
+
+/// Logger to a file.
+class LoggerFile : public Logger
+{
+ /// The pair contains the number of log reference to the file.
+ typedef std::pair<unsigned int, std::ofstream *> t_pair_files_;
+ /// Map of opened file, to manage multiple module access to the same file.
+ typedef std::map<const std::string, t_pair_files_> t_files_;
+ static t_files_ files_;
+ /// Local file used by this instance of the logger file.
+ std::ofstream *file_;
+ /// Local file name.
+ std::string filename_;
+ public:
+ /// Default constructor.
+ LoggerFile (const std::string &param);
+ /// Default destructor.
+ ~LoggerFile (void);
+ /// Called at the begining of a message.
+ void start (const Log &log, const char *msg, Log::Level level);
+ /// Called at the end of a message.
+ void stop (void) { *file_ << std::endl; }
+ /// Output a string or a variable name.
+ LoggerFile &operator<< (const char *s);
+ /// Output a string or a variable name.
+ LoggerFile &operator<< (const std::string &s);
+ /// Output a integer.
+ LoggerFile &operator<< (int i);
+ /// Output a double.
+ LoggerFile &operator << (double d);
+ private:
+ /// Get a ofstream associated to the filename.
+ std::ofstream *getFile (void);
+ /// Release the file from the map if needed. Return true if deleted.
+ bool releaseFile (void);
+};
+
+#endif // logger_file_hh
diff --git a/i/chuck/src/log/logger_null.hh b/i/chuck/src/log/logger_null.hh
new file mode 100644
index 0000000..03c71a6
--- /dev/null
+++ b/i/chuck/src/log/logger_null.hh
@@ -0,0 +1,51 @@
+#ifndef logger_null_hh
+#define logger_null_hh
+// logger_null.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+#include "logger.hh"
+
+/// Null logger to prevent losing time.
+class LoggerNull : public Logger
+{
+ public:
+ /// Default empty constructor.
+ LoggerNull (void) { }
+ /// Default empty destructor.
+ ~LoggerNull (void) { }
+ /// Empty start.
+ void start (const Log &, const char *, Log::Level) { }
+ /// Empty stop.
+ void stop (void) { }
+ /// Empty << string or variable name.
+ LoggerNull &operator<< (const char *) { return *this; }
+ /// Empty << string or variable name.
+ LoggerNull &operator<< (const std::string &) { return *this; }
+ /// Empty << integer.
+ LoggerNull &operator<< (int) { return *this; }
+ /// Empty << double.
+ LoggerNull &operator << (double) { return *this; }
+};
+
+#endif // logger_null_hh
diff --git a/i/chuck/src/log/logger_ram.cc b/i/chuck/src/log/logger_ram.cc
new file mode 100644
index 0000000..720d0e8
--- /dev/null
+++ b/i/chuck/src/log/logger_ram.cc
@@ -0,0 +1,98 @@
+// logger_ram.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "logger_ram.hh"
+
+#include <stdexcept>
+#include <sstream> // Convertion from num to string
+
+/// Default constructor.
+LoggerRam::LoggerRam (void)
+ : buffer_ (bufferFactory_.getDataCircularBuffer ())
+{
+}
+
+/// Called at the begining of a message.
+void
+LoggerRam::start (const Log &log, const char *msg, Log::Level level)
+{
+ strTmp_ = log.getModule ();
+ strTmp_.append (":");
+
+ const char *instance = log.getInstance ();
+ if (instance)
+ {
+ strTmp_.append (" ");
+ strTmp_.append (instance);
+ strTmp_.append (":");
+ }
+ strTmp_.append (" (");
+ strTmp_.append (msg);
+ strTmp_.append (")");
+
+ buffer_.write (reinterpret_cast<const uint8_t *> (strTmp_.data ()), strTmp_.size ());
+}
+
+/// Output a string or a variable name.
+LoggerRam &
+LoggerRam::operator<< (const char *s)
+{
+ strTmp_ = " ";
+ strTmp_.append (s);
+ buffer_.write (reinterpret_cast<const uint8_t *> (strTmp_.data ()), strTmp_.size ());
+ return *this;
+}
+
+/// Output a string or a variable name.
+LoggerRam &
+LoggerRam::operator<< (const std::string &s)
+{
+ strTmp_ = " " + s;
+ buffer_.write (reinterpret_cast<const uint8_t *> (strTmp_.data ()), strTmp_.size ());
+ return *this;
+}
+
+/// Output a integer.
+LoggerRam &
+LoggerRam::operator<< (int i)
+{
+ strTmp_ = " ";
+ std::ostringstream oStr;
+ oStr << i;
+ strTmp_.append (oStr.str ());
+ buffer_.write (reinterpret_cast<const uint8_t *> (strTmp_.data ()), strTmp_.size ());
+ return *this;
+}
+
+/// Output a double.
+LoggerRam &
+LoggerRam::operator<< (double d)
+{
+ strTmp_ = " ";
+ std::ostringstream oStr;
+ oStr << d;
+ strTmp_.append (oStr.str ());
+ buffer_.write (reinterpret_cast<const uint8_t *> (strTmp_.data ()), strTmp_.size ());
+ return *this;
+}
diff --git a/i/chuck/src/log/logger_ram.hh b/i/chuck/src/log/logger_ram.hh
new file mode 100644
index 0000000..03838c2
--- /dev/null
+++ b/i/chuck/src/log/logger_ram.hh
@@ -0,0 +1,63 @@
+#ifndef logger_ram_hh
+#define logger_ram_hh
+// logger_ram.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "logger.hh"
+#include "data_circular_buffer_factory.hh"
+#include "data/data_circular_buffer.hh"
+
+#include <string>
+
+/// Logger into ram (with a data circular buffer).
+class LoggerRam : public Logger
+{
+ /// Factory for creating DataCircularBuffer.
+ DataCircularBufferFactory bufferFactory_;
+ /// Reference to the current DataCircularBuffer used.
+ DataCircularBuffer &buffer_;
+ /// Temporary string.
+ std::string strTmp_;
+ public:
+ /// Default constructor.
+ LoggerRam (void);
+ /// Default destructor.
+ ~LoggerRam (void) { }
+ /// Called at the begining of a message.
+ void start (const Log &log, const char *msg, Log::Level level);
+ /// Called at the end of a message.
+ void stop (void) { uint8_t cr = '\n'; buffer_.write (&cr, 1); }
+ /// Output a string or a variable name.
+ LoggerRam &operator<< (const char *s);
+ /// Output a string or a variable name.
+ LoggerRam &operator<< (const std::string &s);
+ /// Output a integer.
+ LoggerRam &operator<< (int i);
+ /// Output a double.
+ LoggerRam &operator << (double d);
+ private:
+};
+
+#endif // logger_ram_hh
diff --git a/i/chuck/src/log/logger_stdout.cc b/i/chuck/src/log/logger_stdout.cc
new file mode 100644
index 0000000..5956d67
--- /dev/null
+++ b/i/chuck/src/log/logger_stdout.cc
@@ -0,0 +1,68 @@
+// logger_stdout.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+#include "logger_stdout.hh"
+
+/// Called at the begining of a message.
+void
+LoggerStdout::start (const Log &log, const char *msg, Log::Level level)
+{
+ std::cout << log.getModule () << ':';
+ const char *instance = log.getInstance ();
+ if (instance)
+ std::cout << ' ' << instance << ':';
+ std::cout << " (" << msg << ')';
+
+}
+
+/// Output a string or a variable name.
+LoggerStdout &
+LoggerStdout::operator<< (const char *s)
+{
+ std::cout << ' ' << s;
+ return *this;
+}
+
+/// Output a string or a variable name.
+LoggerStdout &
+LoggerStdout::operator<< (const std::string &s)
+{
+ std::cout << ' ' << s;
+ return *this;
+}
+
+/// Output a integer.
+LoggerStdout &
+LoggerStdout::operator<< (int i)
+{
+ std::cout << ' ' << i;
+ return *this;
+}
+
+/// Output a double.
+LoggerStdout &
+LoggerStdout::operator<< (double d)
+{
+ std::cout << ' ' << d;
+ return *this;
+}
diff --git a/i/chuck/src/log/logger_stdout.hh b/i/chuck/src/log/logger_stdout.hh
new file mode 100644
index 0000000..eaa706a
--- /dev/null
+++ b/i/chuck/src/log/logger_stdout.hh
@@ -0,0 +1,54 @@
+#ifndef logger_stdout_hh
+#define logger_stdout_hh
+// logger_stdout.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+#include "logger.hh"
+
+#include <iostream>
+#include <string>
+
+/// Logger to stdout.
+class LoggerStdout : public Logger
+{
+ public:
+ /// Default empty constructor.
+ LoggerStdout (void) { }
+ /// Default empty destructor.
+ ~LoggerStdout (void) { }
+ /// Called at the begining of a message.
+ void start (const Log &log, const char *msg, Log::Level level);
+ /// Called at the end of a message.
+ void stop (void) { std::cout << std::endl; }
+ /// Output a string or a variable name.
+ LoggerStdout &operator<< (const char *s);
+ /// Output a string or a variable name.
+ LoggerStdout &operator<< (const std::string &s);
+ /// Output a integer.
+ LoggerStdout &operator<< (int i);
+ /// Output a double.
+ LoggerStdout &operator << (double d);
+};
+
+#endif // logger_stdout_hh
diff --git a/i/chuck/src/log/test_log.cc b/i/chuck/src/log/test_log.cc
new file mode 100644
index 0000000..64989b5
--- /dev/null
+++ b/i/chuck/src/log/test_log.cc
@@ -0,0 +1,53 @@
+// test_log.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "log.hh"
+#include "data_circular_buffer_factory.hh"
+
+#include "config/config.hh"
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ Config config (argc, argv);
+ Log log ("main");
+ Log log2 ("chier");
+ log ("foo") << "[Default] bar" << 4 << "foobar" << 5.6;
+ log ("bar", Log::error) << "[Error] foo" << 5;
+ log ("bar", Log::info) << "[Info] Chier" << 3 << "Info" << 2.3;
+ log ("bar", Log::debug) << "[Debug] Partout" << 3 << "Debug" << 2.3;
+ log2 ("foo") << "[Default] bar" << 4 << "foobar" << 5.6;
+ log2 ("bar", Log::error) << "[Error] foo" << 5;
+ log2 ("bar", Log::info) << "[Info] Chier" << 3 << "Info" << 2.3;
+ log2 ("bar", Log::debug) << "[Debug] Partout" << 3 << "Debug" << 2.3;
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/i/chuck/src/log/test_log_server.cc b/i/chuck/src/log/test_log_server.cc
new file mode 100644
index 0000000..70792f6
--- /dev/null
+++ b/i/chuck/src/log/test_log_server.cc
@@ -0,0 +1,45 @@
+// test_log_server.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Haller
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "data/data_buffer.hh"
+#include "log_server.hh"
+#include "socket/address.hh"
+
+#include <string.h>
+
+int main (void)
+{
+ // On fait un zolie DataBuffer
+ DataBuffer db_;
+ // On ecrit des betises dedans
+ char * betise = "J'aime bien la choucroute traditionnelle.\n";
+ db_.write(reinterpret_cast<const uint8_t *>(betise), strlen(betise));
+ // On crée le serveur de la mort qui tue
+ LogServer ls(db_, std::string(), 2042);
+ // On écoute tranquillement
+ ls.listen();
+
+ return 0;
+}
diff --git a/i/chuck/src/motor/Makefile.defs b/i/chuck/src/motor/Makefile.defs
new file mode 100644
index 0000000..ce79e10
--- /dev/null
+++ b/i/chuck/src/motor/Makefile.defs
@@ -0,0 +1,5 @@
+PROGRAMS += test_motor
+
+motor_OBJECTS = motor.o $(asserv_OBJECTS) $(log_OBJECTS)
+
+test_motor_OBJECTS = test_motor.o $(motor_OBJECTS) $(tester_OBJECTS)
diff --git a/i/chuck/src/motor/motor.cc b/i/chuck/src/motor/motor.cc
new file mode 100644
index 0000000..32d94eb
--- /dev/null
+++ b/i/chuck/src/motor/motor.cc
@@ -0,0 +1,183 @@
+// motor.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "motor.hh"
+
+#include <cmath>
+
+/// Constructor.
+Motor::Motor (void)
+ : asserv_ (*this), seq_ (0), finish_ (true), blocked_ (false),
+ x_ (0.0), y_ (0.0), a_ (0.0), log_ ("Motor")
+{
+}
+
+/// Reset.
+void
+Motor::reset (void)
+{
+ finish_ = true;
+ blocked_ = false;
+ asserv_.reset ();
+}
+
+/// Linear and angular move. T(mm) is the linear distance. A(mm) is the
+/// angular distance which means the arc length.
+void
+Motor::move (double t, double a)
+{
+ nextSeq ();
+ finish_ = false;
+ blocked_ = false;
+ asserv_.speedTo (t, a, seq_);
+}
+
+/// Rotate (rad).
+void
+Motor::rotate (double a)
+{
+ nextSeq ();
+ finish_ = false;
+ blocked_ = false;
+ asserv_.speedAngle (a, seq_);
+}
+
+/// Find a hole.
+void
+Motor::findHole (void)
+{
+ nextSeq ();
+ finish_ = false;
+ blocked_ = false;
+ asserv_.findHole (seq_);
+}
+
+void Motor::lockGoodHole (void)
+{
+ ///XXX VERIFIER LES COORDONNEES
+ const int xGood = 2000;
+ const int yGood = -1100;
+ ///XXX VERIFIER LES CALCULS D'AILLEURS...
+ double rotation = atan2((yGood - y_), (xGood - x_));
+ rotate(rotation);
+}
+
+void Motor::lockBadHole (void)
+{
+ ///XXX VERIFIER LES COORDONNEES
+ const int xGood = 600;
+ const int yGood = -1100;
+ ///XXX VERIFIER LES CALCULS D'AILLEURS...
+ double rotation = atan2((yGood - y_), (xGood - x_));
+ rotate(rotation);
+}
+
+/// Stop now.
+void
+Motor::stop (void)
+{
+ finish_ = true;
+ blocked_ = false;
+ asserv_.speed (0, 0);
+}
+
+/// get the file descriptor
+int
+Motor::getFd(void) const
+{
+ return asserv_.getFd();
+}
+
+/// get the position of robal
+void
+Motor::getPosition(double & x, double & y, double & a) const
+{
+ x = x_;
+ y = y_;
+ a = a_;
+}
+
+/// Next seq number.
+void
+Motor::nextSeq (void)
+{
+ seq_++;
+ if (seq_ > 100)
+ seq_ = 1;
+}
+
+/// Implement Asserv::Receiver callbacks.
+void
+Motor::receiveAck (int seq)
+{
+ if ((seq & 0x7f) == seq_)
+ {
+ asserv_.ack (seq);
+ finish_ = true;
+ if (seq & 0x80)
+ {
+ blocked_ = true;
+ }
+ }
+}
+
+void
+Motor::receiveCounterStat (int l, int r)
+{
+}
+
+void
+Motor::receivePos (double x, double y, double a)
+{
+ x_ = x;
+ y_ = y;
+ a_ = a;
+ log_ ("Pos") << "x " << x << " y " << y << " a " << a / (2 * M_PI) * 360;
+}
+
+void
+Motor::receiveSpeedStat (int t, int a)
+{
+}
+
+void
+Motor::receivePosStat (int te, int ti, int ae, int ai)
+{
+}
+
+void
+Motor::receivePwmStat (int l, int r)
+{
+}
+
+void
+Motor::receiveTimerStat (const int *t, int tn)
+{
+}
+
+void
+Motor::receiveInPort (unsigned int port)
+{
+}
+
diff --git a/i/chuck/src/motor/motor.hh b/i/chuck/src/motor/motor.hh
new file mode 100644
index 0000000..548c7bd
--- /dev/null
+++ b/i/chuck/src/motor/motor.hh
@@ -0,0 +1,86 @@
+#ifndef motor_hh
+#define motor_hh
+// motor.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "asserv/asserv.hh"
+#include "log/log.hh"
+
+/// Handle movements.
+class Motor : public Asserv::Receiver
+{
+ private:
+ Asserv asserv_;
+ int seq_;
+ bool finish_;
+ bool blocked_;
+ double x_, y_, a_;
+ Log log_;
+ public:
+ /// Constructor.
+ Motor (void);
+ /// Try to empty emission queue, return true if empty.
+ bool sync (void) { return asserv_.sync (); }
+ /// Wait until emission queue is empty or timed out.
+ bool wait (int timeout = -1) { return asserv_.wait (timeout); }
+ /// Get asserv reference to change parameters.
+ Asserv &getAsserv (void) { return asserv_; }
+ /// True if last long move is finished.
+ bool finish (void) const { return finish_; }
+ /// True if blocked.
+ bool blocked (void) const { return blocked_; }
+ /// Linear and angular move. T(mm) is the linear distance. A(mm) is the
+ /// angular distance which means the arc length.
+ void move (double t, double a);
+ /// Rotate (rad).
+ void rotate (double a);
+ /// Find a hole.
+ void findHole (void);
+ /// Lock good hole (approximatively...)
+ void lockGoodHole(void);
+ /// Lock ennemy hole (non pas son cul)
+ void lockBadHole(void);
+ /// Stop now.
+ void stop (void);
+ /// get the file descriptor
+ int getFd(void) const;
+ /// Reset.
+ void reset (void);
+ /// get the position of robal
+ void getPosition(double & x, double & y, double & a) const;
+ private:
+ /// Next seq number.
+ inline void nextSeq (void);
+ /// Implement Asserv::Receiver callbacks.
+ void receiveAck (int seq);
+ void receiveCounterStat (int l, int r);
+ void receivePos (double x, double y, double a);
+ void receiveSpeedStat (int t, int a);
+ void receivePosStat (int te, int ti, int ae, int ai);
+ void receivePwmStat (int l, int r);
+ void receiveTimerStat (const int *t, int tn);
+ void receiveInPort (unsigned int port);
+};
+
+#endif // motor_hh
diff --git a/i/chuck/src/motor/test_motor.cc b/i/chuck/src/motor/test_motor.cc
new file mode 100644
index 0000000..760dfd6
--- /dev/null
+++ b/i/chuck/src/motor/test_motor.cc
@@ -0,0 +1,99 @@
+// test_motor.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "motor.hh"
+#include "tester/tester.hh"
+#include "timer/timer.hh"
+
+#include <iostream>
+#include <exception>
+#include <iomanip>
+
+class TestMotor : public Tester
+{
+ private:
+ Motor motor_;
+ public:
+ /// Constructor.
+ TestMotor (int argc, char **argv)
+ : Tester (argc, argv)
+ { }
+ /// Wait.
+ void wait (int ms)
+ {
+ int t, stop;
+ t = Timer::getProgramTime ();
+ stop = t + ms;
+ while (t < stop)
+ {
+ motor_.wait (stop - t);
+ t = Timer::getProgramTime ();
+ }
+ }
+ /// Called after each command called.
+ void postcall (void)
+ {
+ while (!motor_.wait () || !motor_.finish ())
+ ;
+ }
+ /// Executed before checking/running commands. Good place to add command
+ /// to the interpreter.
+ void preRun (void)
+ {
+ Interpreter &i = getInterpreter ();
+ i.add ("wait", Interpreter::memFunc (*this, &TestMotor::wait),
+ "wait MS\nwait for a delay in millisecond");
+ i.add ("move", Interpreter::memFunc (motor_, &Motor::move),
+ "move T(mm) A(mm)\n"
+ "linear and angular move");
+ i.add ("rotate", Interpreter::memFunc (motor_, &Motor::rotate),
+ "rotate A(rad)\n"
+ "rotate round axis center");
+ i.add ("findHole", Interpreter::memFunc (motor_, &Motor::findHole),
+ "findHole\nfind a hole");
+ i.add ("stop", Interpreter::memFunc (motor_, &Motor::stop),
+ "stop\nguess what");
+ i.add ("_postcall",
+ Interpreter::memFunc (*this, &TestMotor::postcall));
+ }
+ /// Executed after running commands.
+ void postRun (void)
+ {
+ motor_.getAsserv ().reset ();
+ }
+};
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ TestMotor tm (argc, argv);
+ tm.run ();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ }
+}
diff --git a/i/chuck/src/parser/Makefile.defs b/i/chuck/src/parser/Makefile.defs
new file mode 100644
index 0000000..61b4b97
--- /dev/null
+++ b/i/chuck/src/parser/Makefile.defs
@@ -0,0 +1,14 @@
+PROGRAMS += test_parser
+
+parser_OBJECTS = yylexer.o yyparser.o parser.o
+
+test_parser_OBJECTS = $(parser_OBJECTS) test_parser.o
+
+EXTRA_CLEAN += yyparser.hh yyparser.cc yylexer.hh yylexer.cc
+
+yyparser.hh: yyparser.cc
+$(OBJ_DIR)/yylexer.o: yyparser.hh
+
+yylexer.hh: yylexer.cc
+$(OBJ_DIR)/yyparser.o: yylexer.hh
+$(OBJ_DIR)/parser.o: yylexer.hh
diff --git a/i/chuck/src/parser/parser.cc b/i/chuck/src/parser/parser.cc
new file mode 100644
index 0000000..4981474
--- /dev/null
+++ b/i/chuck/src/parser/parser.cc
@@ -0,0 +1,189 @@
+// parser.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "parser.hh"
+
+#include "yyparser.hh"
+#include "yylexer.hh"
+
+#include <stdexcept>
+#include <sstream>
+
+int yyparse (void *);
+
+/// Constructeur.
+Parser::Parser (void)
+{
+}
+
+/// Destructeur
+Parser::~Parser (void)
+{
+}
+
+/// Lance le parseur sur un fichier.
+void
+Parser::parseFile (const std::string &file)
+{
+ FILE *f;
+ f = fopen (file.c_str (), "r");
+ if (!f)
+ throw std::runtime_error ("can not open file \"" + file + "\"");
+ try
+ {
+ // Crée un scanner, initialise son tampon d'entré, puis parse.
+ yyscan_t scanner;
+ YY_BUFFER_STATE buf;
+ Extra e (*this, true);
+ yylex_init (&scanner);
+ yyset_extra (&e, scanner);
+ buf = yy_create_buffer (f, YY_READ_BUF_SIZE, scanner);
+ yy_switch_to_buffer (buf, scanner);
+ int ret = yyparse (scanner);
+ yy_delete_buffer (buf, scanner);
+ yylex_destroy (scanner);
+ if (ret)
+ {
+ if (!e.error_.empty ())
+ throw std::runtime_error (e.error_);
+ else
+ throw std::runtime_error ("parse error");
+ }
+ }
+ catch (const std::exception &e)
+ {
+ fclose (f);
+ throw std::runtime_error ("in file \"" + file + "\": " + e.what ());
+ }
+ fclose (f);
+}
+
+/// Lance le parseur sur une chaîne.
+void
+Parser::parseString (const std::string &s)
+{
+ try
+ {
+ // Crée un scanner, initialise son tampon d'entré, puis parse.
+ yyscan_t scanner;
+ YY_BUFFER_STATE buf;
+ Extra e (*this, false);
+ yylex_init (&scanner);
+ yyset_extra (&e, scanner);
+ buf = yy_scan_bytes (s.data (), s.size (), scanner);
+ int ret = yyparse (scanner);
+ yy_delete_buffer (buf, scanner);
+ yylex_destroy (scanner);
+ if (ret)
+ {
+ if (!e.error_.empty ())
+ throw std::runtime_error (e.error_);
+ else
+ throw std::runtime_error ("parse error");
+ }
+ }
+ catch (const std::exception &e)
+ {
+ throw std::runtime_error ("in string \"" + s + "\": " + e.what ());
+ }
+}
+
+/// Fonction appelée lors d'une affectation. VAL peut être modifié, il est
+/// détruit suite à l'appel.
+void
+Parser::assign (const std::string &id, any &val)
+{
+ throw std::runtime_error ("unexpected assignement");
+}
+
+/// Fonction appelée lors d'un appel. ARGS peut être modifié, il est
+/// détruit suite à l'appel.
+void
+Parser::call (const std::string &id, AnyList &args)
+{
+ throw std::runtime_error ("unexpected call");
+}
+
+/// Constructeur pour initialiser les références.
+Parser::Extra::Extra (Parser &parser, bool useLine)
+ : line (1), parser_ (parser), useLine_ (useLine)
+{
+}
+
+/// Recueille l'erreur de bison.
+void
+Parser::Extra::error (const std::string &e)
+{
+ if (error_.empty ())
+ {
+ error_ = e;
+ if (useLine_)
+ {
+ std::stringstream os;
+ os << line;
+ error_ += ", line ";
+ error_ += os.str ();
+ }
+ }
+}
+
+/// Fonction appelée lors d'une affectation par bison.
+bool
+Parser::Extra::assign (const std::string &id, any &val)
+{
+ try
+ {
+ parser_.assign (id, val);
+ }
+ catch (const std::exception &e)
+ {
+ error (e.what ());
+ return false;
+ }
+ return true;
+}
+
+/// Fonction appelée lors d'un appel par bison.
+bool
+Parser::Extra::call (const std::string &id, AnyList &args)
+{
+ try
+ {
+ parser_.call (id, args);
+ }
+ catch (const std::exception &e)
+ {
+ error (e.what ());
+ return false;
+ }
+ return true;
+}
+
+/* Shut up warning for this wrongly declared static function. */
+static int
+yy_init_globals (yyscan_t yyscanner)
+{
+ return yy_init_globals (yyscanner);
+}
+
diff --git a/i/chuck/src/parser/parser.hh b/i/chuck/src/parser/parser.hh
new file mode 100644
index 0000000..573d5f6
--- /dev/null
+++ b/i/chuck/src/parser/parser.hh
@@ -0,0 +1,89 @@
+#ifndef parser_hh
+#define parser_hh
+// parser.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "utils/any.hh"
+
+#include <string>
+#include <list>
+
+/// Classe de parsing. Pour l'utiliser, dériver une classe et implémenter les
+/// méthodes que l'on veut supporter.
+class Parser
+{
+ public:
+ /// Les types supportés sont bool, char, int, double, std::string,
+ /// IntList, DoubleList, StringList.
+ typedef std::list<int> IntList;
+ typedef std::list<double> DoubleList;
+ typedef std::list<std::string> StringList;
+ typedef std::list<any> AnyList;
+ /// Cette structure est passée au parser en bison, puis au lexer en flex.
+ class Extra
+ {
+ public:
+ /// Chaîne temporaire utilisée pendant l'analyse lexicale.
+ std::string tmp;
+ /// Ligne courante.
+ int line;
+ private:
+ /// Référence vers l'instance de Parser.
+ Parser &parser_;
+ /// Permet de stocker l'erreur de bison.
+ std::string error_;
+ /// Utilise ou non le comptage de lignes.
+ bool useLine_;
+ public:
+ /// Constructeur pour initialiser les références.
+ Extra (Parser &parser, bool useLine);
+ /// Recueille l'erreur de bison.
+ void error (const std::string &e);
+ /// Fonction appelée lors d'une affectation par bison.
+ bool assign (const std::string &id, any &val);
+ /// Fonction appelée lors d'un appel par bison.
+ bool call (const std::string &id, AnyList &args);
+ /// Accés réservé pour Parser.
+ friend class Parser;
+ };
+ public:
+ /// Constructeur.
+ Parser (void);
+ /// Destructeur virtuel
+ virtual ~Parser (void);
+ /// Lance le parseur sur un fichier.
+ void parseFile (const std::string &file);
+ /// Lance le parseur sur une chaîne.
+ void parseString (const std::string &s);
+ /// Fonction appelée lors d'une affectation. VAL peut être modifié, il est
+ /// détruit suite à l'appel.
+ virtual void assign (const std::string &id, any &val);
+ /// Fonction appelée lors d'un appel. ARGS peut être modifié, il est
+ /// détruit suite à l'appel.
+ virtual void call (const std::string &id, AnyList &args);
+};
+
+#define YY_EXTRA_TYPE Parser::Extra *
+
+#endif // parser_hh
diff --git a/i/chuck/src/parser/test_parser.cc b/i/chuck/src/parser/test_parser.cc
new file mode 100644
index 0000000..dedbd83
--- /dev/null
+++ b/i/chuck/src/parser/test_parser.cc
@@ -0,0 +1,86 @@
+// test_parser.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "parser.hh"
+
+#include <iostream>
+#include <exception>
+
+class TestParser : public Parser
+{
+ public:
+ /// Fonction appelée lors d'une affectation. VAL peut être modifié, il est
+ /// détruit suite à l'appel.
+ virtual void assign (const std::string &id, any &val)
+ {
+ std::cout << id << " = " << val << std::endl;
+ }
+ /// Fonction appelée lors d'un appel. ARGS peut être modifié, il est
+ /// détruit suite à l'appel.
+ virtual void call (const std::string &id, AnyList &args)
+ {
+ std::cout << "call " << id << ' ' << args << std::endl;
+ }
+};
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ if (argc <= 1)
+ {
+ std::cerr << "test_parser - test le parser.\n"
+ "Utilisation: test_parser [-f FILE | STRING]\n"
+ << std::endl;
+ }
+ TestParser tp;
+ for (int i = 1; i < argc; i++)
+ {
+ try
+ {
+ if (i + 1 < argc && strcmp (argv[i], "-f") == 0)
+ {
+ tp.parseFile (argv[++i]);
+ }
+ else
+ {
+ tp.parseString (argv[i]);
+ }
+ }
+ catch (const std::exception &e)
+ {
+ // L'erreur est humaine... heu, normale, elle fait parti du
+ // test donc pas de cerr.
+ std::cout << "error: " << e.what () << std::endl;
+ }
+ }
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/i/chuck/src/parser/yylexer.ll b/i/chuck/src/parser/yylexer.ll
new file mode 100644
index 0000000..be8d41c
--- /dev/null
+++ b/i/chuck/src/parser/yylexer.ll
@@ -0,0 +1,148 @@
+%{
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "parser/parser.hh"
+#include "yyparser.hh"
+%}
+
+%option reentrant
+%option header-file="yylexer.hh"
+%option outfile="yylexer.cc"
+%option bison-bridge
+%option noyywrap nodefault nounput
+
+%x strst
+
+INTDEC [+-]?[0-9]+
+INTHEX "0x"[0-9a-fA-F]+
+INTNUM {INTDEC}|{INTHEX}
+DOUBLEEX [eE]{INTDEC}
+DOUBLE1 [+-]?\.[0-9]+{DOUBLEEX}?
+DOUBLE2 [+-]?[0-9]+\.[0-9]*{DOUBLEEX}?
+DOUBLE3 {INTDEC}{DOUBLEEX}
+DOUBLENUM {DOUBLE1}|{DOUBLE2}|{DOUBLE3}
+
+%%
+
+"true"|"on"|"yes" {
+ yylval->b = true;
+ return BOOLEAN;
+}
+
+"false"|"off"|"no" {
+ yylval->b = false;
+ return BOOLEAN;
+}
+
+"'"\\n"'" {
+ yylval->c = '\n';
+ return CHAR;
+}
+"'"\\r"'" {
+ yylval->c = '\r';
+ return CHAR;
+}
+"'"\\t"'" {
+ yylval->c = '\t';
+ return CHAR;
+}
+"'"\\."'" {
+ yylval->c = yytext[1];
+ return CHAR;
+}
+"'"\\\n"'" {
+ yyextra->line++;
+ yylval->c = yytext[1];
+ return CHAR;
+}
+"'"."'" {
+ yylval->c = yytext[1];
+ return CHAR;
+}
+
+[a-zA-Z][_a-zA-Z0-9.-]* {
+ yylval->s = new std::string (yytext);
+ return ID;
+}
+
+{DOUBLENUM} {
+ yylval->d = strtod (yytext, 0);
+ return DOUBLE;
+}
+
+{INTNUM} {
+ yylval->i = strtol (yytext, 0, 0);
+ return INT;
+}
+
+\" {
+ BEGIN(strst);
+ yyextra->tmp.clear ();
+}
+
+\n {
+ yyextra->line++;
+ return SEP;
+}
+
+; {
+ return SEP;
+}
+
+[=()] return yytext[0];
+
+[ \t]+ /* Skip. */
+#.* /* Skip comments. */
+
+. {
+ yyextra->error (std::string ("unexpected character \'") \
+ + yytext[0] + '\'');
+ return UNKNOWN;
+}
+
+<strst>\" {
+ BEGIN (INITIAL);
+ yylval->s = new std::string (yyextra->tmp);
+ return STRING;
+}
+
+<strst>\\n yyextra->tmp += '\n';
+<strst>\\r yyextra->tmp += '\r';
+<strst>\\t yyextra->tmp += '\t';
+<strst>\\. yyextra->tmp += yytext[1];
+<strst>\\\n {
+ yyextra->line++;
+ yyextra->tmp += yytext[1];
+}
+<strst>. yyextra->tmp += yytext[0];
+<strst>\n {
+ yyextra->error ("unexpected end of line inside string");
+ yyextra->line++;
+ return UNKNOWN;
+}
+
+%%
+
+/* vim:ft=lex:
+*/
diff --git a/i/chuck/src/parser/yyparser.yy b/i/chuck/src/parser/yyparser.yy
new file mode 100644
index 0000000..86db4a5
--- /dev/null
+++ b/i/chuck/src/parser/yyparser.yy
@@ -0,0 +1,278 @@
+%{
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "parser/parser.hh"
+
+// Fichiers d'en-tête générés.
+#include "yyparser.hh"
+#include "yylexer.hh"
+
+#undef yyextra
+#define yyextra (yyget_extra (scanner))
+
+void yyerror (void *scanner, const char *e);
+
+%}
+
+%error-verbose
+%pure-parser
+%lex-param {void *scanner}
+%parse-param {void *scanner}
+%defines
+%union {
+ bool b;
+ char c;
+ int i;
+ double d;
+ std::string *s;
+ struct {
+ any *a;
+ Parser::IntList *il;
+ } il;
+ struct {
+ any *a;
+ Parser::DoubleList *dl;
+ } dl;
+ struct {
+ any *a;
+ Parser::StringList *sl;
+ } sl;
+ Parser::AnyList *al;
+}
+
+%token SEP
+
+%token<b> BOOLEAN
+%token<c> UNKNOWN
+%token<c> CHAR
+%token<i> INT
+%token<d> DOUBLE
+%token<s> ID STRING
+
+%type<il> int_list int_list_i
+%type<dl> double_list double_list_i
+%type<sl> string_list string_list_i
+%type<al> arg_list
+
+%destructor { delete $$; } ID STRING
+%destructor { delete $$.a; } int_list int_list_i
+%destructor { delete $$.a; } double_list double_list_i
+%destructor { delete $$.a; } string_list string_list_i
+%destructor { delete $$; } arg_list
+
+%%
+
+input:
+ /* Nothing. */
+ | item
+ | input SEP item
+ | input SEP
+;
+
+item:
+ ID '=' BOOLEAN {
+ any a ($3);
+ if (!yyextra->assign (*$1, a))
+ YYERROR;
+ delete $1;
+ }
+ | ID '=' CHAR {
+ any a ($3);
+ if (!yyextra->assign (*$1, a))
+ YYERROR;
+ delete $1;
+ }
+ | ID '=' INT {
+ any a ($3);
+ if (!yyextra->assign (*$1, a))
+ YYERROR;
+ delete $1;
+ }
+ | ID '=' DOUBLE {
+ any a ($3);
+ if (!yyextra->assign (*$1, a))
+ YYERROR;
+ delete $1;
+ }
+ | ID '=' STRING {
+ any a (*$3);
+ if (!yyextra->assign (*$1, a))
+ YYERROR;
+ delete $1;
+ delete $3;
+ }
+ | ID '=' int_list {
+ if (!yyextra->assign (*$1, *$3.a))
+ YYERROR;
+ delete $1;
+ delete $3.a;
+ }
+ | ID '=' double_list {
+ if (!yyextra->assign (*$1, *$3.a))
+ YYERROR;
+ delete $1;
+ delete $3.a;
+ }
+ | ID '=' string_list {
+ if (!yyextra->assign (*$1, *$3.a))
+ YYERROR;
+ delete $1;
+ delete $3.a;
+ }
+ | ID arg_list {
+ if (!yyextra->call (*$1, *$2))
+ YYERROR;
+ delete $1;
+ delete $2;
+ }
+;
+
+int_list:
+ '(' int_list_i ')' {
+ $$ = $2;
+ }
+;
+
+int_list_i:
+ INT {
+ $$.a = new any (Parser::IntList ());
+ $$.il = any_cast<Parser::IntList> ($$.a);
+ $$.il->push_back ($1);
+ }
+ | int_list_i INT {
+ $1.il->push_back ($2);
+ $$ = $1;
+ }
+;
+
+double_list:
+ '(' double_list_i ')' {
+ $$ = $2;
+ }
+;
+
+double_list_i:
+ DOUBLE {
+ $$.a = new any (Parser::DoubleList ());
+ $$.dl = any_cast<Parser::DoubleList> ($$.a);
+ $$.dl->push_back ($1);
+ }
+ | double_list_i DOUBLE {
+ $1.dl->push_back ($2);
+ $$ = $1;
+ }
+;
+
+string_list:
+ '(' string_list_i ')' {
+ $$ = $2;
+ }
+;
+
+string_list_i:
+ STRING {
+ $$.a = new any (Parser::StringList ());
+ $$.sl = any_cast<Parser::StringList> ($$.a);
+ $$.sl->push_back (*$1);
+ delete $1;
+ }
+ | string_list_i STRING {
+ $1.sl->push_back (*$2);
+ $$ = $1;
+ delete $2;
+ }
+;
+
+arg_list:
+ /* empty */ {
+ $$ = new Parser::AnyList;
+ }
+ | arg_list BOOLEAN {
+ any a ($2);
+ $1->push_back (any ());
+ $1->back ().swap (a);
+ $$ = $1;
+ }
+ | arg_list CHAR {
+ any a ($2);
+ $1->push_back (any ());
+ $1->back ().swap (a);
+ $$ = $1;
+ }
+ | arg_list INT {
+ any a ($2);
+ $1->push_back (any ());
+ $1->back ().swap (a);
+ $$ = $1;
+ }
+ | arg_list DOUBLE {
+ any a ($2);
+ $1->push_back (any ());
+ $1->back ().swap (a);
+ $$ = $1;
+ }
+ | arg_list STRING {
+ any a (*$2);
+ $1->push_back (any ());
+ $1->back ().swap (a);
+ delete $2;
+ $$ = $1;
+ }
+ | arg_list int_list {
+ $1->push_back (any ());
+ $1->back ().swap (*$2.a);
+ delete $2.a;
+ $$ = $1;
+ }
+ | arg_list double_list {
+ $1->push_back (any ());
+ $1->back ().swap (*$2.a);
+ delete $2.a;
+ $$ = $1;
+ }
+ | arg_list string_list {
+ $1->push_back (any ());
+ $1->back ().swap (*$2.a);
+ delete $2.a;
+ $$ = $1;
+ }
+;
+%%
+
+/// Traite une erreur de Bison.
+void
+yyerror (void *scanner, const char *e)
+{
+ yyextra->error (e);
+}
+
+/* Shut up warning for this wrongly declared static function. */
+static int
+yy_init_globals (yyscan_t yyscanner)
+{
+ return yy_init_globals (yyscanner);
+}
+
+/* vim:ft=yacc:
+*/
diff --git a/i/chuck/src/proto/Makefile.defs b/i/chuck/src/proto/Makefile.defs
new file mode 100644
index 0000000..b351026
--- /dev/null
+++ b/i/chuck/src/proto/Makefile.defs
@@ -0,0 +1,5 @@
+PROGRAMS += test_proto
+
+proto_OBJECTS = proto.o $(serial_OBJECTS) $(log_OBJECTS) $(utils_OBJECTS) $(timer_OBJECTS)
+
+test_proto_OBJECTS = test_proto.o $(proto_OBJECTS) $(tester_OBJECTS)
diff --git a/i/chuck/src/proto/proto.cc b/i/chuck/src/proto/proto.cc
new file mode 100644
index 0000000..50e363d
--- /dev/null
+++ b/i/chuck/src/proto/proto.cc
@@ -0,0 +1,457 @@
+// proto.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Haller
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "timer/timer.hh"
+#include "utils/hexa.hh"
+#include "proto.hh"
+
+#include <iostream>
+#include <algorithm>
+#include <iterator>
+
+/// Constructeur.
+Proto::Proto(Receiver &receiver)
+ : log_ ("proto"), receiver_(receiver), tLastSend_(0), revState_(0)
+{
+}
+
+/// Ouvre le port série.
+void
+Proto::open(const std::string &ttyname)
+{
+ serial_.open(ttyname);
+}
+
+/// Ferme le port série
+void
+Proto::close(void)
+{
+ serial_.close();
+}
+
+/// Teste si tout les packets ont été envoyés et aquités, sinon, essaye de
+/// le faire.
+bool
+Proto::sync(void)
+{
+ // Récupération de la frame
+ while (getFrame())
+ {
+ log_ ("recv", Log::debug) << "frame" << currentFrame_;
+ // Si la frame est un aquittement
+ if(currentFrame_ == frameQueue_.front())
+ {
+ // on vire la commande de la queue
+ frameQueue_.pop();
+ // Et on envoie la suivante si elle existe
+ if(!frameQueue_.empty())
+ sendFrame(frameQueue_.front());
+ }
+ // Si c'est une nouvelle commande, on l'envoie avec receive
+ else
+ receiver_.receive(currentFrame_.command, currentFrame_);
+ }
+ // On regarde depuis combien de temps on a envoyé une commande
+ if(!frameQueue_.empty())
+ {
+ // Si on dépasse la milliseconde, on renvoie
+ if(Timer::getProgramTime() - tLastSend_ >= timeout_)
+ sendFrame(frameQueue_.front());
+ }
+ return frameQueue_.empty();
+}
+
+/// Envoie un packet
+void
+Proto::send (const Frame & frame, bool reliable)
+{
+ if(reliable)
+ {
+ if(frameQueue_.empty())
+ tLastSend_ = -timeout_;
+ frameQueue_.push(frame);
+ }
+ else
+ sendFrame(frame);
+}
+
+
+/// Envois un packet. COMMAND est la commande à envoyer, FORMAT, donne le
+/// format et le nombre de paramètres ('b' : 8 bits, 'w' : 16 bits, 'd' :
+/// 32 bits, majuscule pour signé).
+void
+Proto::send (char command, const char *format, int a0, int a1,
+ int a2, int a3, int a4, int a5, bool reliable)
+{
+ // Constitution de la frame
+ Proto::Frame frame;
+ frame.command = command;
+
+ if (format[0] != '\0')
+ {
+ newArgFrame(frame, format[0],a0);
+ if (format[1] != '\0')
+ {
+ newArgFrame(frame, format[1],a1);
+ if (format[2] != '\0')
+ {
+ newArgFrame(frame, format[2],a2);
+ if (format[3] != '\0')
+ {
+ newArgFrame(frame, format[3],a3);
+ if(format[4] != '\0')
+ {
+ newArgFrame(frame, format[4],a4);
+ if(format[5] != '\0')
+ newArgFrame(frame, format[5],a5);
+ }
+
+ }
+ }
+ }
+ }
+ send(frame,reliable);
+}
+
+/// Send a string of size number.
+void
+Proto::sendStr (char command, const char *str, int size, bool reliable)
+{
+ Proto::Frame frame;
+
+ frame.command = command;
+
+ for (int compt = 0; compt < size; compt++)
+ newArgFrame (frame, 'b', str[compt]);
+
+ send (frame,reliable);
+}
+
+/// permet d'envoyer un packet pas fiable
+void
+Proto::sendUnreliable (char command, const char *format, int a0, int a1,
+ int a2, int a3, int a4, int a5)
+{
+ send(command, format, a0, a1, a2, a3, a4, a5, false);
+}
+
+/// Teste si le packet correspond au format et décode les valeurs. Utilise
+/// le même format que send.
+bool
+Proto::decode (const Proto::Frame &frame)
+{
+ int dummy;
+ return decode(frame, "", dummy, dummy, dummy, dummy, dummy);
+}
+
+bool
+Proto::decode (const Frame &frame, const char *format, int &a0)
+{
+ int dummy;
+ return decode(frame, format, a0, dummy, dummy, dummy, dummy);
+}
+
+bool
+Proto::decode (const Frame &frame, const char *format, int &a0, int &a1)
+{
+ int dummy;
+ return decode(frame, format, a0, a1, dummy, dummy, dummy);
+}
+
+bool
+Proto::decode (const Frame &frame, const char *format, int &a0,
+ int &a1, int &a2)
+{
+ int dummy;
+ return decode(frame, format, a0, a1, a2, dummy, dummy);
+}
+
+bool
+Proto::decode (const Frame &frame, const char *format, int &a0,
+ int &a1, int &a2, int &a3)
+{
+ int dummy;
+ return decode(frame, format, a0, a1, a2, a3, dummy);
+}
+
+bool
+Proto::decode (const Frame &frame, const char *format, int &a0,
+ int &a1, int &a2, int &a3, int &a4)
+{
+ // Teste si il y a bien le bon nombre d'argument
+ if (static_cast<int>(frame.args.size()) != argsFrameSize(format))
+ return false;
+ // On décode et on envoie
+ decodeArg(frame, format, a0, a1, a2, a3, a4);
+
+ return true;
+}
+
+/// Attend que des caractères soit disponible pendant un temps maximum en
+/// milliseconde et les traite. Renvois le résultat de sync (). Attention,
+/// fonction bloquante, n'utiliser que pour les tests.
+bool
+Proto::wait (int timeout/*-1*/)
+{
+ // On apelle serial_.wait avec un timeout toujours inf ou égal à proto::timeout_
+ serial_.wait (timeout < timeout_ && timeout != -1 ? timeout : timeout_);
+ return sync ();
+}
+
+/// Récupère le File Descriptor
+int Proto::getFd(void) const
+{
+ return serial_.getFd();
+}
+
+/// Récupère les infos de l'AVR pour construire une frame
+bool
+Proto::getFrame(void)
+{
+ int receivedChar, d;
+ bool erreur = false;
+ // tant que le tampon n'est pas vide, on teste
+ while((receivedChar = serial_.getchar()) != -1)
+ {
+ // Si on reçoit un bang
+ if(receivedChar == '!')
+ {
+ revState_ = 1;
+ currentFrame_.command = 0;
+ currentFrame_.args.clear();
+ }
+ // Si on reçoit le retour chariot et que on reçevait les args
+ else if(receivedChar == '\r' && revState_ == 2)
+ {
+ revState_ = 0;
+ return true;
+ }
+ // Pour les autres charactères
+ // Si on attend la commande
+ else
+ switch(revState_)
+ {
+ case 1:
+ if (!isalpha (receivedChar) || receivedChar == '?')
+ erreur = true;
+ else
+ {
+ currentFrame_.command = receivedChar;
+ revState_ = 2;
+ }
+ break;
+ case 2:
+ d = hex2digit (receivedChar);
+ if (d == hexInvalid)
+ erreur = true;
+ else
+ {
+ currentFrame_.args.push_back (static_cast<uint8_t>(d) << 4);
+ revState_ = 3;
+ }
+ break;
+ case 3:
+ d = hex2digit (receivedChar);
+ if (d == hexInvalid)
+ erreur = true;
+ else
+ {
+ currentFrame_.args.back() |= static_cast<uint8_t>(d);
+ revState_ = 2;
+ break;
+ }
+ }
+ // Si revState == 0 alors on jette
+ // Si on a reçu une erreur on renvoie
+ if(erreur)
+ {
+ // On renvoie en mettant le compteur à 0, la commande sera
+ // renvoyer de retour à sync
+ log_("Erreur de reception", Log::debug)
+ << "commande inconnue" << "";
+ tLastSend_ = 0;
+ revState_ = 0;
+ return false;
+ }
+ }
+ return false;
+}
+
+/// Envoie la frame dans l'AVR
+void
+Proto::sendFrame(const Frame & frame)
+{
+ log_ ("send", Log::debug) << "frame" << frame;
+ // envoyer le bang
+ serial_.putchar('!');
+
+ // Envoyer la commande
+ serial_.putchar(frame.command);
+
+ // Envoyer les arguments
+ for(std::vector<uint8_t>::const_iterator it = frame.args.begin();
+ it != frame.args.end(); ++it)
+ {
+ serial_.putchar(digit2hex(*it >> 4));
+ serial_.putchar(digit2hex(*it & 0x0f));
+ }
+
+ // Envoyer le retour chariot
+ serial_.putchar('\r');
+
+ // actualiser le timer
+ tLastSend_ = Timer::getProgramTime();
+}
+
+/// Remplie une frame avec un argument
+void
+Proto::newArgFrame(Proto::Frame & frame, char format, int arg)
+{
+ switch(format)
+ {
+ case 'b':
+ case 'B':
+ frame.args.push_back(static_cast<uint8_t>(arg));
+ break;
+ case 'w':
+ case 'W':
+ frame.args.push_back(static_cast<uint8_t>(arg >> 8));
+ frame.args.push_back(static_cast<uint8_t>(arg));
+ break;
+ case 'd':
+ case 'D':
+ frame.args.push_back(static_cast<uint8_t>(arg >> 24));
+ frame.args.push_back(static_cast<uint8_t>(arg >> 16));
+ frame.args.push_back(static_cast<uint8_t>(arg >> 8));
+ frame.args.push_back(static_cast<uint8_t>(arg));
+ break;
+ }
+}
+
+/// Renvoie la taille necessaire du vecteur args pour un format donné
+int
+Proto::argsFrameSize(const char *format)
+{
+ int size = 0;
+ for(; *format != '\0'; format++)
+ switch(*format)
+ {
+ case 'b':
+ case 'B':
+ size += 1;
+ break;
+ case 'w':
+ case 'W':
+ size += 2;
+ break;
+ case 'd':
+ case 'D':
+ size += 4;
+ break;
+ default:
+ size += 0;
+ }
+ return size;
+}
+
+/// Décode un argument
+void
+Proto::decodeArg(const Frame & frame, const char *format, int &a0, int &a1, int &a2, int &a3, int &a4)
+{
+ int temp[5];
+ int pos = 0;
+
+ for(int i = 0; *format != '\0'; format++,i++)
+ {
+ switch(*format)
+ {
+ case 'b':
+ temp[i] = static_cast<int>(frame.args[pos]);
+ pos++;
+ break;
+ case 'B':
+ {
+ int8_t t = static_cast<int8_t>(frame.args[pos]);
+ temp[i] = static_cast<int>(t);
+ pos++;
+ break;
+ }
+ case 'w':
+ temp[i] = static_cast<int>(frame.args[pos]) << 8
+ |static_cast<int>(frame.args[pos + 1]);
+ pos += 2;
+ break;
+ case 'W':
+ {
+ int8_t t = static_cast<int8_t>(frame.args[pos]);
+ temp[i] = static_cast<int>(t) << 8
+ |static_cast<int>(frame.args[pos + 1]);
+ pos += 2;
+ break;
+ }
+ case 'd':
+ temp[i] = static_cast<int>(frame.args[pos]) << 24
+ |static_cast<int>(frame.args[pos + 1]) << 16
+ |static_cast<int>(frame.args[pos + 2]) << 8
+ |static_cast<int>(frame.args[pos + 3]);
+ pos += 4;
+ break;
+
+ case 'D':
+ {
+ int8_t t = static_cast<int8_t>(frame.args[pos]);
+ temp[i] = static_cast<int>(t) << 24
+ |static_cast<int>(frame.args[pos + 1]) << 16
+ |static_cast<int>(frame.args[pos + 2]) << 8
+ |static_cast<int>(frame.args[pos + 3]);
+ pos += 4;
+ break;
+ }
+ }
+ }
+ a0 = temp[0];
+ a1 = temp[1];
+ a2 = temp[2];
+ a3 = temp[3];
+ a4 = temp[4];
+}
+
+bool
+Proto::Frame::operator==(const Frame& frame)
+{
+ return this->command == frame.command && this->args == frame.args;
+}
+
+/// Affiche une frame.
+std::ostream &
+operator<< (std::ostream &os, const Proto::Frame &f)
+{
+ os << '<' << f.command << ' ';
+ std::copy (f.args.begin (), f.args.end (),
+ std::ostream_iterator<int> (os, " "));
+ os << '>';
+ return os;
+}
+
diff --git a/i/chuck/src/proto/proto.hh b/i/chuck/src/proto/proto.hh
new file mode 100644
index 0000000..a45db91
--- /dev/null
+++ b/i/chuck/src/proto/proto.hh
@@ -0,0 +1,140 @@
+#ifndef proto_hh
+#define proto_hh
+// proto.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include "utils/non_copyable.hh"
+#include "serial/serial.hh"
+#include "log/log.hh"
+
+#include <queue>
+#include <stdint.h>
+
+/// Classe de dialogue avec une carte électronique par le port série.
+class Proto : public NonCopyable
+{
+ public:
+ class Receiver;
+ /// Packet.
+ struct Frame
+ {
+ char command;
+ std::vector<uint8_t> args;
+ bool operator==(const Frame& frame);
+ };
+ private:
+ Log log_;
+ Serial serial_;
+ Receiver &receiver_;
+
+ /// File d'attente des messages à aquiter.
+ typedef std::queue<Frame> FrameQueue;
+ FrameQueue frameQueue_;
+ //Date du dernier envoie
+ int tLastSend_;
+ //Temps entre les ré-émission
+ static const int timeout_ = 100;
+
+ /// Frame en cours de réception
+ Frame currentFrame_;
+ int revState_;
+ // Etat de la réception de la frame
+ // 0 - Rien reçu
+ // 1 - Bang reçu
+ // 2 - Commande reçu & nouveau argument
+ // 3 - char 1 argument reçu
+
+ public:
+ /// Constructeur.
+ Proto (Receiver &receiver);
+ /// Ouvre le port série.
+ void open (const std::string &ttyname);
+ /// Ferme le port série.
+ void close (void);
+ /// Teste si tout les packets ont été envoyés et aquités, sinon, essaye de
+ /// le faire.
+ bool sync (void);
+ /// Envois un packet.
+ void send (const Frame &frame, bool reliable = true);
+ /// Envois un packet. COMMAND est la commande à envoyer, FORMAT, donne le
+ /// format et le nombre de paramètres ('b' : 8 bits, 'w' : 16 bits, 'd' :
+ /// 32 bits, majuscule pour signé).
+ void send (char command, const char *format = "", int a0 = 0, int a1 = 0,
+ int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, bool reliable = true);
+ /// Send a string of size number.
+ void sendStr (char command, const char *str, int size, bool reliable =
+ true);
+ /// permet d'envoyer un packet robert
+ void sendUnreliable (char command, const char *format, int a0,
+ int a1, int a2, int a3, int a4, int a5);
+ //@{
+ /// Teste si le packet correspond au format et décode les valeurs. Utilise
+ /// le même format que send.
+ static bool decode (const Frame &frame);
+ static bool decode (const Frame &frame, const char *format, int &a0);
+ static bool decode (const Frame &frame, const char *format, int &a0, int
+ &a1);
+ static bool decode (const Frame &frame, const char *format, int &a0, int
+ &a1, int &a2);
+ static bool decode (const Frame &frame, const char *format, int &a0, int
+ &a1, int &a2, int &a3);
+ static bool decode (const Frame &frame, const char *format, int &a0, int
+ &a1, int &a2, int &a3, int &a4);
+ //@}
+ /// Attend que des caractères soit disponible pendant un temps maximum en
+ /// milliseconde et les traite. Renvois le résultat de sync (). Attention,
+ /// fonction bloquante, n'utiliser que pour les tests.
+ bool wait (int timeout = -1);
+ /// Récupère le File Descriptor
+ int getFd(void) const;
+
+ public:
+ /// Les clients de Proto doivent dériver de Receiver.
+ class Receiver
+ {
+ public:
+ virtual ~Receiver(void) {};
+ /// Recoit un packet.
+ virtual void receive (char command, const Frame &frame) = 0;
+ };
+ private:
+ /// Récupère les infos de l'AVR pour construire une frame
+ bool getFrame(void);
+ /// Envoie la frame dans l'AVR
+ void sendFrame(const Frame & frame);
+ /// Remplie une frame avec un argument
+ void newArgFrame(Proto::Frame & frame, char format, int arg);
+ /// Renvoie la taille necessaire du vecteur args pour un format donné
+ static int argsFrameSize(const char *format);
+ /// Décode un argument
+ static void decodeArg(const Frame & frame, const char *format, int &a0,
+ int &a1, int &a2, int &a3, int &a4);
+};
+
+/// Affiche une frame.
+std::ostream &
+operator<< (std::ostream &os, const Proto::Frame &f);
+
+#endif // proto_hh
diff --git a/i/chuck/src/proto/test_proto.cc b/i/chuck/src/proto/test_proto.cc
new file mode 100644
index 0000000..01cac96
--- /dev/null
+++ b/i/chuck/src/proto/test_proto.cc
@@ -0,0 +1,96 @@
+// test_proto.cc
+// robert - programme du robot 2006. {{{
+//
+// Copyright (C) 2005 Nicolas Haller
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "proto.hh"
+#include "timer/timer.hh"
+#include "tester/tester.hh"
+#include "parser/parser.hh"
+
+#include <iostream>
+#include <stdexcept>
+
+class TestProto : public Tester, Proto::Receiver
+{
+ private:
+ Proto proto_;
+ public:
+ // Constructor
+ TestProto (int argc, char ** argv)
+ : Tester (argc, argv), proto_(*this){}
+ void preRun (void)
+ {
+ Interpreter &interpreter = getInterpreter ();
+ // Récupère le tty de config
+ proto_.open(config_.get<std::string>("testProto.tty"));
+ // Add functions.
+ interpreter.add ("s", Interpreter::memFunc ( *this, &TestProto::send ),
+ "Fonction send (string commande, string format, "
+ "int arg...)");
+ interpreter.add ("w", Interpreter::memFunc ( proto_, &Proto::wait ),
+ "Fonction wait ()");
+ }
+ void postRun(void)
+ {
+ proto_.close();
+ }
+ void receive (char command, const Proto::Frame &frame)
+ {
+ std::cout << "received " << frame << std::endl;
+ }
+ void send (const Parser::AnyList & al, bool dryrun)
+ {
+ Parser::AnyList::const_iterator it = al.begin();
+ // arguments envoyé à la fonctions Proto::send
+ int arg[6];
+ // command avr
+ char command = any_cast<char> (*it);
+ // format des arguments
+ std::string format = any_cast<std::string> (*++it);
+ // Récupération des arguments
+ for (unsigned i = 0; i < 6; ++i)
+ {
+ if(i < al.size() - 2)
+ arg[i] = any_cast<int> (*++it);
+ else
+ arg[i] = 0;
+ }
+ if (!dryrun)
+ proto_.send(command, format.c_str(), arg[0], arg[1], arg[2],
+ arg[3], arg[4], arg[5]);
+ }
+};
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ TestProto tp (argc, argv);
+ tp.run ();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ }
+}
diff --git a/i/chuck/src/scheduler/Makefile.defs b/i/chuck/src/scheduler/Makefile.defs
new file mode 100644
index 0000000..fc6c157
--- /dev/null
+++ b/i/chuck/src/scheduler/Makefile.defs
@@ -0,0 +1,7 @@
+PROGRAMS += test_scheduler
+
+scheduler_OBJECTS = scheduler.o schedulable_read_fd.o schedulable_alarm.o
+
+test_scheduler_OBJECTS = \
+ test_scheduler.o scheduler.o schedulable_read_fd.o schedulable_alarm.o \
+ $(timer_OBJECTS)
diff --git a/i/chuck/src/scheduler/schedulable.hh b/i/chuck/src/scheduler/schedulable.hh
new file mode 100644
index 0000000..d8869af
--- /dev/null
+++ b/i/chuck/src/scheduler/schedulable.hh
@@ -0,0 +1,50 @@
+#ifndef schedulable_hh
+#define schedulable_hh
+// schedulable.hh
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+
+class FdSet;
+
+namespace scheduler {
+
+class Scheduler;
+
+/// Classe abstraite pour un objet utilisable par le Scheduler.
+class Schedulable
+{
+ public:
+ /// Destructeur.
+ virtual ~Schedulable (void) {}
+ /// Paramètre le Scheduler.
+ virtual void setup (Scheduler &scheduler, int time, FdSet &readSet,
+ int &timeout) = 0;
+ /// Appelé aprés l'attente du Scheduler, renvois true si un événement a
+ /// été traité.
+ virtual bool run (Scheduler &scheduler, int time,
+ const FdSet &readSet) = 0;
+};
+
+} // namespace scheduler
+
+#endif // schedulable_hh
diff --git a/i/chuck/src/scheduler/schedulable_alarm.cc b/i/chuck/src/scheduler/schedulable_alarm.cc
new file mode 100644
index 0000000..b890350
--- /dev/null
+++ b/i/chuck/src/scheduler/schedulable_alarm.cc
@@ -0,0 +1,56 @@
+// schedulable_alarm.cc
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "schedulable_alarm.hh"
+
+namespace scheduler {
+
+/// Paramètre le Scheduler.
+void
+SchedulableAlarm::setup (Scheduler &scheduler, int time, FdSet &readSet, int
+ &timeout)
+{
+ if (start_ != -1)
+ {
+ int to = start_ + step_ - time;
+ timeout = to > 0 ? to : 0;
+ }
+}
+
+/// Appelé aprés l'attente du Scheduler, renvois true si un événement a
+/// été traité.
+bool
+SchedulableAlarm::run (Scheduler &scheduler, int time, const FdSet &readSet)
+{
+ if (time >= start_ + step_)
+ {
+ start_ = periodic_ ? start_ + step_ : -1;
+ callback_ ();
+ return true;
+ }
+ else
+ return false;
+}
+
+} // namespace scheduler
+
diff --git a/i/chuck/src/scheduler/schedulable_alarm.hh b/i/chuck/src/scheduler/schedulable_alarm.hh
new file mode 100644
index 0000000..1e008b6
--- /dev/null
+++ b/i/chuck/src/scheduler/schedulable_alarm.hh
@@ -0,0 +1,60 @@
+#ifndef schedulable_alarm_hh
+#define schedulable_alarm_hh
+// schedulable_alarm.hh
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "schedulable.hh"
+#include "utils/callback.hh"
+#include "timer/timer.hh"
+
+namespace scheduler {
+
+/// Execute un callback à un instant donné.
+class SchedulableAlarm : public Schedulable
+{
+ Callback<void> callback_;
+ int start_, step_;
+ bool periodic_;
+ public:
+ /// Construit une alarm dans step milliseconde, périodique si periodic est
+ /// vrai (vrai par defaut), à partir de start si donné, ou de maintenant
+ /// sinon.
+ template<typename T>
+ SchedulableAlarm (T callback, int step, bool periodic = true,
+ int start = -1)
+ : callback_ (callback),
+ start_ (start), step_ (step), periodic_ (periodic)
+ {
+ if (start_ == -1)
+ start_ = Timer::getProgramTime ();
+ }
+ /// Paramètre le Scheduler.
+ void setup (Scheduler &scheduler, int time, FdSet &readSet, int &timeout);
+ /// Appelé aprés l'attente du Scheduler, renvois true si un événement a
+ /// été traité.
+ bool run (Scheduler &scheduler, int time, const FdSet &readSet);
+};
+
+} // namespace scheduler
+
+#endif // schedulable_alarm_hh
diff --git a/i/chuck/src/scheduler/schedulable_read_fd.cc b/i/chuck/src/scheduler/schedulable_read_fd.cc
new file mode 100644
index 0000000..3c84c9b
--- /dev/null
+++ b/i/chuck/src/scheduler/schedulable_read_fd.cc
@@ -0,0 +1,51 @@
+// schedulable_read_fd.cc
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "schedulable_read_fd.hh"
+#include "utils/fd_set.hh"
+
+namespace scheduler {
+
+/// Paramètre le Scheduler.
+void
+SchedulableReadFd::setup (Scheduler &scheduler, int time, FdSet &readSet, int &timeout)
+{
+ readSet.set (fd_);
+}
+
+/// Appelé aprés l'attente du Scheduler, renvois true si un événement a
+/// été traité.
+bool
+SchedulableReadFd::run (Scheduler &scheduler, int time, const FdSet &readSet)
+{
+ if (readSet.isSet (fd_))
+ {
+ callback_ ();
+ return true;
+ }
+ else
+ return false;
+}
+
+} // namespace scheduler
+
diff --git a/i/chuck/src/scheduler/schedulable_read_fd.hh b/i/chuck/src/scheduler/schedulable_read_fd.hh
new file mode 100644
index 0000000..01d7b26
--- /dev/null
+++ b/i/chuck/src/scheduler/schedulable_read_fd.hh
@@ -0,0 +1,52 @@
+#ifndef schedulable_read_fd_hh
+#define schedulable_read_fd_hh
+// schedulable_read_fd.hh
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "schedulable.hh"
+#include "utils/callback.hh"
+
+namespace scheduler {
+
+/// Execute un callback sur une lecture possible sur un descripteur de
+/// fichier.
+class SchedulableReadFd : public Schedulable
+{
+ Callback<void> callback_;
+ int fd_;
+ public:
+ /// Constructeur.
+ template<typename T>
+ SchedulableReadFd (T callback, int fd)
+ : callback_ (callback), fd_ (fd)
+ { }
+ /// Paramètre le Scheduler.
+ void setup (Scheduler &scheduler, int time, FdSet &readSet, int &timeout);
+ /// Appelé aprés l'attente du Scheduler, renvois true si un événement a
+ /// été traité.
+ bool run (Scheduler &scheduler, int time, const FdSet &readSet);
+};
+
+} // namespace scheduler
+
+#endif // schedulable_read_fd_hh
diff --git a/i/chuck/src/scheduler/scheduler.cc b/i/chuck/src/scheduler/scheduler.cc
new file mode 100644
index 0000000..4ef3ade
--- /dev/null
+++ b/i/chuck/src/scheduler/scheduler.cc
@@ -0,0 +1,103 @@
+// scheduler.cc
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "scheduler.hh"
+#include "utils/fd_set.hh"
+#include "timer/timer.hh"
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+namespace scheduler {
+
+/// Destructeur.
+Scheduler::~Scheduler (void)
+{
+ // TODO: Test for schedulables_ empty ?
+}
+
+/// Ajoute un élément schedulable.
+void
+Scheduler::insert (Schedulable &schedulable)
+{
+ schedulables_.insert (&schedulable);
+}
+
+/// Enlève un élément schedulable.
+void
+Scheduler::erase (Schedulable &schedulable)
+{
+ schedulables_.erase (&schedulable);
+}
+
+/// Lance le scheduler. Si timeout est différent de -1, c'est le temps
+/// maximal que prend le scheduler avant de rendre la main. Si
+/// returnOnEvent est true, le premier évenement arrète le scheduler.
+/// Renvois true si au moins un événement a été traité.
+bool
+Scheduler::schedule (int timeout/*-1*/, bool returnOnEvent/*false*/)
+{
+ bool event = false;
+ int t = Timer::getProgramTime ();
+ int start = t;
+ do
+ {
+ // Prépare le select.
+ int to = timeout == -1 ? -1 : start + timeout - t;
+ FdSet readFds;
+ for (Schedulables::const_iterator i = schedulables_.begin ();
+ i != schedulables_.end ();
+ ++i)
+ {
+ int top = -1;
+ (*i)->setup (*this, t, readFds, top);
+ // Si le timeout est plus court, retient ce timeout.
+ if (to == -1 || top != -1 && top < to)
+ to = top;
+ }
+ // Select.
+ if (to != -1)
+ {
+ timeval tv;
+ tv.tv_sec = to / 1000;
+ tv.tv_usec = to % 1000 * 1000;
+ select (FD_SETSIZE, readFds.get (), 0, 0, &tv);
+ }
+ else
+ {
+ select (FD_SETSIZE, readFds.get (), 0, 0, 0);
+ }
+ // Run.
+ t = Timer::getProgramTime ();
+ for (Schedulables::const_iterator i = schedulables_.begin ();
+ i != schedulables_.end ();
+ ++i)
+ event = (*i)->run (*this, t, readFds) || event;
+ t = Timer::getProgramTime ();
+ } while (!(returnOnEvent && event)
+ && (timeout == -1 || start + timeout > t));
+ return event;
+}
+
+} // namespace scheduler
+
diff --git a/i/chuck/src/scheduler/scheduler.hh b/i/chuck/src/scheduler/scheduler.hh
new file mode 100644
index 0000000..3bd885b
--- /dev/null
+++ b/i/chuck/src/scheduler/scheduler.hh
@@ -0,0 +1,53 @@
+#ifndef scheduler_hh
+#define scheduler_hh
+// scheduler.hh
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "schedulable.hh"
+
+#include <set>
+
+namespace scheduler {
+
+/// Scheduler, répartie le travail en fonction des événements.
+class Scheduler
+{
+ typedef std::set<Schedulable *> Schedulables;
+ Schedulables schedulables_;
+ public:
+ /// Destructeur.
+ ~Scheduler (void);
+ /// Ajoute un élément schedulable.
+ void insert (Schedulable &schedulable);
+ /// Enlève un élément schedulable.
+ void erase (Schedulable &schedulable);
+ /// Lance le scheduler. Si timeout est différent de -1, c'est le temps
+ /// maximal que prend le scheduler avant de rendre la main. Si
+ /// returnOnEvent est true, le premier évenement arrète le scheduler.
+ /// Renvois true si au moins un événement a été traité.
+ bool schedule (int timeout = -1, bool returnOnEvent = false);
+};
+
+} // namespace scheduler
+
+#endif // scheduler_hh
diff --git a/i/chuck/src/scheduler/test_scheduler.cc b/i/chuck/src/scheduler/test_scheduler.cc
new file mode 100644
index 0000000..6cb88c0
--- /dev/null
+++ b/i/chuck/src/scheduler/test_scheduler.cc
@@ -0,0 +1,68 @@
+// test_scheduler.cc
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "scheduler.hh"
+#include "schedulable_read_fd.hh"
+#include "schedulable_alarm.hh"
+#include "utils/bind.hh"
+#include "timer/timer.hh"
+
+#include <iostream>
+#include <unistd.h>
+
+void
+ev (void)
+{
+ std::cout << "event received" << std::endl;
+ char buf[1024];
+ read (0, buf, 1024);
+}
+
+void
+to (const char *msg)
+{
+ std::cout << "timeout received \"" << msg << "\" at "
+ << Timer::getProgramTime () << std::endl;
+}
+
+int
+main (void)
+{
+ using namespace scheduler;
+ try
+ {
+ Scheduler s;
+ SchedulableReadFd srf (ev, 0);
+ s.insert (srf);
+ std::cout << "start at " << Timer::getProgramTime () << std::endl;
+ SchedulableAlarm sa1 (bind<void> (to, "1s"), 1000);
+ s.insert (sa1);
+ s.schedule (10000);
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/i/chuck/src/serial/Makefile.defs b/i/chuck/src/serial/Makefile.defs
new file mode 100644
index 0000000..fcf71f9
--- /dev/null
+++ b/i/chuck/src/serial/Makefile.defs
@@ -0,0 +1,5 @@
+PROGRAMS += test_serial
+
+serial_OBJECTS = serial.o serial_base.o serial_dev.o serial_stdio.o
+
+test_serial_OBJECTS = test_serial.o $(serial_OBJECTS) $(utils_OBJECTS)
diff --git a/i/chuck/src/serial/serial.cc b/i/chuck/src/serial/serial.cc
new file mode 100644
index 0000000..db2a6d2
--- /dev/null
+++ b/i/chuck/src/serial/serial.cc
@@ -0,0 +1,66 @@
+// serial.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "serial.hh"
+#include "serial_dev.hh"
+#include "serial_stdio.hh"
+
+/// Constructeur.
+Serial::Serial (bool blocking)
+ : blocking_ (blocking), sb_ (0)
+{
+}
+
+/// Destructeur.
+Serial::~Serial (void)
+{
+ close ();
+}
+
+/// Ouvre et paramètre le port série. \a ttyname peut être un device
+/// ("/dev/tty00,115200", voir SerialDev), un programme précédé d'un tube
+/// ("|simul_asserv", voir SerialPipe) ou l'entrée/sortie standard ("-").
+void
+Serial::open (const std::string &ttyname)
+{
+ close ();
+ if (ttyname == "-")
+ sb_ = new SerialStdio (blocking_);
+ else if (ttyname[0] == '|')
+ {
+ // TODO
+ }
+ else
+ sb_ = new SerialDev (blocking_);
+ sb_->open (ttyname);
+}
+
+/// Ferme le port série, appellé automatiquement dans le destructeur.
+void
+Serial::close (void)
+{
+ delete sb_;
+ sb_ = 0;
+}
+
diff --git a/i/chuck/src/serial/serial.hh b/i/chuck/src/serial/serial.hh
new file mode 100644
index 0000000..d66971e
--- /dev/null
+++ b/i/chuck/src/serial/serial.hh
@@ -0,0 +1,64 @@
+#ifndef serial_hh
+#define serial_hh
+// serial.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "serial_base.hh"
+
+/// Classe générique qui utilise la sous-classe apropriée de SerialBase en
+/// fonction du paramètre de Serial::open().
+class Serial
+{
+ bool blocking_;
+ SerialBase *sb_;
+ public:
+ /// Constructeur.
+ Serial (bool blocking = false);
+ /// Destructeur.
+ ~Serial (void);
+ /// Ouvre et paramètre le port série. \a ttyname peut être un device
+ /// ("/dev/tty00,115200", voir SerialDev), un programme précédé d'un tube
+ /// ("|simul_asserv", voir SerialPipe) ou l'entrée/sortie standard ("-").
+ void open (const std::string &ttyname);
+ /// Ferme le port série, appellé automatiquement dans le destructeur.
+ void close (void);
+ /// Lit un bloc, retourne le nombre d'octets lus ou <= 0 en cas d'erreur
+ /// ou si aucun caractère n'est disponible. Pour le robot, préferer en
+ /// général getchar() pour du non-bloquant.
+ ssize_t read (void *buf, size_t size) { return sb_->read (buf, size); }
+ /// Lit un caractère, ou -1 en cas d'erreur ou si aucun caractère n'est
+ /// disponible.
+ int getchar (void) { return sb_->getchar (); }
+ /// Ecrit un bloc.
+ void write (const void *buf, size_t size) { sb_->write (buf, size); }
+ /// Ecrit un caractère.
+ void putchar (int c) { sb_->putchar (c); }
+ /// Attend que des caractères soient disponibles pendant un delay en
+ /// millisecondes.
+ bool wait (int timeout = -1) { return sb_->wait (timeout); }
+ /// Récupère le descripteur.
+ int getFd (void) const { return sb_->getFd (); }
+};
+
+#endif // serial_hh
diff --git a/i/chuck/src/serial/serial_base.cc b/i/chuck/src/serial/serial_base.cc
new file mode 100644
index 0000000..b92a6b0
--- /dev/null
+++ b/i/chuck/src/serial/serial_base.cc
@@ -0,0 +1,84 @@
+// serial_base.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "serial_base.hh"
+#include "utils/fd_set.hh"
+
+/// Constructeur.
+SerialBase::SerialBase (void)
+ : fdIn_ (-1), fdOut_ (-1)
+{
+}
+
+/// Destructeur.
+SerialBase::~SerialBase (void)
+{
+}
+
+/// Lit un bloc, retourne le nombre d'octets lus ou <= 0 en cas d'erreur
+/// ou si aucun caractère n'est disponible. Pour le robot, préferer en
+/// général getchar() pour du non-bloquant.
+ssize_t
+SerialBase::read (void *buf, size_t size)
+{
+ return ::read (fdIn_, buf, size);
+}
+
+/// Lit un caractère, ou -1 en cas d'erreur ou si aucun caractère n'est
+/// disponible.
+int
+SerialBase::getchar (void)
+{
+ char c;
+ if (read (&c, 1) == 1)
+ return c & 0xff;
+ else
+ return -1;
+}
+
+/// Ecrit un bloc.
+void
+SerialBase::write (const void *buf, size_t size)
+{
+ ::write (fdOut_, buf, size);
+}
+
+/// Ecrit un caractère.
+void
+SerialBase::putchar (int c)
+{
+ char cc = c;
+ write (&cc, 1);
+}
+
+/// Attend que des caractères soient disponibles pendant un delay en
+/// millisecondes.
+bool
+SerialBase::wait (int timeout/*-1*/)
+{
+ FdSet fds;
+ fds.set (fdIn_);
+ return fds.wait (timeout);
+}
+
diff --git a/i/chuck/src/serial/serial_base.hh b/i/chuck/src/serial/serial_base.hh
new file mode 100644
index 0000000..9caf27d
--- /dev/null
+++ b/i/chuck/src/serial/serial_base.hh
@@ -0,0 +1,68 @@
+#ifndef serial_base_hh
+#define serial_base_hh
+// serial_base.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <unistd.h>
+#include <string>
+
+/// Classe de base pour un port série.
+class SerialBase
+{
+ protected:
+ /// Descripteur de fichier utilisé par les fonctions de lecture.
+ int fdIn_;
+ /// Descripteur de fichier utilisé par les fonctions d'écriture.
+ int fdOut_;
+ public:
+ /// Constructeur.
+ SerialBase (void);
+ /// Destructeur.
+ virtual ~SerialBase (void);
+ /// Ouvre et paramètre le port série. \a ttyname peut être un device
+ /// ("/dev/tty00,115200", voir SerialDev), un programme précédé d'un tube
+ /// ("|simul_asserv", voir SerialPipe) ou l'entrée/sortie standard ("-").
+ virtual void open (const std::string &ttyname) = 0;
+ /// Ferme le port série, appellé automatiquement dans le destructeur.
+ virtual void close (void) = 0;
+ /// Lit un bloc, retourne le nombre d'octets lus ou <= 0 en cas d'erreur
+ /// ou si aucun caractère n'est disponible. Pour le robot, préferer en
+ /// général getchar() pour du non-bloquant.
+ ssize_t read (void *buf, size_t size);
+ /// Lit un caractère, ou -1 en cas d'erreur ou si aucun caractère n'est
+ /// disponible.
+ int getchar (void);
+ /// Ecrit un bloc.
+ void write (const void *buf, size_t size);
+ /// Ecrit un caractère.
+ void putchar (int c);
+ /// Attend que des caractères soient disponibles pendant un delay en
+ /// millisecondes.
+ bool wait (int timeout = -1);
+ /// Récupère le descripteur.
+ int getFd (void) { return fdIn_; }
+};
+
+#endif // serial_base_hh
diff --git a/i/chuck/src/serial/serial_dev.cc b/i/chuck/src/serial/serial_dev.cc
new file mode 100644
index 0000000..a1824a2
--- /dev/null
+++ b/i/chuck/src/serial/serial_dev.cc
@@ -0,0 +1,168 @@
+// serial_dev.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "serial_dev.hh"
+#include "utils/errno_exception.hh"
+
+#include <stdexcept>
+#include <fcntl.h>
+#include <cstdlib>
+
+/// Constructeur.
+SerialDev::SerialDev (bool blocking/*false*/)
+ : blocking_ (blocking)
+{
+}
+
+/// Destructeur.
+SerialDev::~SerialDev (void)
+{
+ close ();
+}
+
+/// Ouvre et paramètre le port série, accepte plusieurs paramètres séparés par
+/// des virgules : tty, vitesse, parité (none, odd, even). Par exemple :
+/// "/dev/ttyS00,115200,even" (par defaut).
+void
+SerialDev::open (const std::string &ttyname)
+{
+ struct termios tios;
+ std::string tty;
+ int speed = 115200;
+ char par = 'e';
+ // Décode le ttyname.
+ decode (ttyname, tty, speed, par);
+ // Ouvre le port série.
+ fdIn_ = ::open (tty.c_str (), O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (fdIn_ < 0)
+ throw errno_exception (ttyname, errno);
+ // Rendre le port série asynchrone.
+ //fcntl (fd_, F_SETFL, FASYNC);
+ // Sauver la configuration courante du port série.
+ tcgetattr (fdIn_, &old_);
+ tcgetattr (fdIn_, &tios);
+ // Paramètrer les options du port série.
+ // Vérification de la parité en entrée, remplace toute erreur de
+ // transmission par un caractère nul. Pas de Xon Xoff. Entrée crue.
+ tios.c_iflag &= ~(IGNPAR | PARMRK | ISTRIP | BRKINT | IGNCR | ICRNL |
+ INLCR | IXON | IXOFF | IXANY | IMAXBEL);
+ tios.c_iflag |= INPCK | IGNBRK;
+ // Sortie crue.
+ tios.c_oflag &= ~(OPOST);
+ // Pas de status line, 1 bit de stop, 8 bits de données, règle la parité.
+ tios.c_cflag &= ~(HUPCL | CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
+ tios.c_cflag |= CS8 | CLOCAL | CREAD;
+ if (par != 'n') tios.c_cflag |= PARENB;
+ if (par == 'o') tios.c_cflag |= PARODD;
+ // Cru.
+ tios.c_lflag &= ~(ICANON | ECHO | ISIG | NOFLSH | TOSTOP);
+ // On n'attend jamais si on est en non-block. On attend sinon.
+ tios.c_cc[VTIME] = 0;
+ if (blocking_)
+ tios.c_cc[VMIN] = 1;
+ else
+ tios.c_cc[VMIN] = 0;
+ switch (speed)
+ {
+ case 1200:
+ cfsetspeed (&tios, B1200);
+ break;
+ case 9600:
+ cfsetspeed (&tios, B9600);
+ break;
+ case 19200:
+ cfsetspeed (&tios, B19200);
+ break;
+ case 38400:
+ cfsetspeed (&tios, B38400);
+ break;
+ case 57600:
+ cfsetspeed (&tios, B57600);
+ break;
+ case 115200:
+ cfsetspeed (&tios, B115200);
+ break;
+ case 230400:
+ cfsetspeed (&tios, B230400);
+ break;
+ case 460800:
+ cfsetspeed (&tios, B460800);
+ break;
+ default:
+ throw std::runtime_error ("Vitesse de port série non supportée\n");
+ }
+ // Vider et configurer le port série.
+ tcflush (fdIn_, TCIFLUSH);
+ tcsetattr (fdIn_, TCSANOW, &tios);
+ fdOut_ = fdIn_;
+}
+
+/// Ferme le port série, appellé automatiquement dans le destructeur de la
+/// classe SerialBase.
+void
+SerialDev::close (void)
+{
+ if (fdIn_ != -1)
+ {
+ tcsetattr (fdIn_, TCSANOW, &old_);
+ ::close (fdIn_);
+ fdIn_ = -1;
+ fdOut_ = -1;
+ }
+}
+
+/// Décode le ttyname, voir open.
+void
+SerialDev::decode (const std::string &ttyname, std::string &tty, int &speed,
+ char &par) const
+{
+ std::string::size_type a, b, d;
+ int i;
+ a = 0;
+ b = ttyname.find (',');
+ while (a != std::string::npos)
+ {
+ d = b == std::string::npos ? std::string::npos : b - a;
+ std::string s (ttyname, a, d);
+ i = atoi (s.c_str ());
+ if (i)
+ speed = i;
+ else
+ {
+ if (s == "e" || s == "even")
+ par = 'e';
+ else if (s == "o" || s == "odd")
+ par = 'o';
+ else if (s == "n" || s == "none")
+ par = 'n';
+ else if (tty.empty ())
+ tty = s;
+ else
+ throw std::runtime_error ("error in ttyname: " + s);
+ }
+ a = b == std::string::npos ? b : b + 1;
+ b = ttyname.find (',', a);
+ }
+}
+
diff --git a/i/chuck/src/serial/serial_dev.hh b/i/chuck/src/serial/serial_dev.hh
new file mode 100644
index 0000000..31e98b6
--- /dev/null
+++ b/i/chuck/src/serial/serial_dev.hh
@@ -0,0 +1,54 @@
+#ifndef serial_dev_hh
+#define serial_dev_hh
+// serial_dev.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "serial_base.hh"
+
+#include <termios.h>
+
+/// Classe de contrôle du port serie /dev/tty*.
+class SerialDev : public SerialBase
+{
+ bool blocking_;
+ struct termios old_;
+ public:
+ /// Constructeur.
+ SerialDev (bool blocking = false);
+ /// Destructeur.
+ ~SerialDev (void);
+ /// Ouvre et paramètre le port série, accepte plusieurs paramètres séparés
+ /// par des virgules : tty, vitesse, parité (none, odd, even). Par
+ /// exemple : "/dev/ttyS00,115200,even" (par defaut).
+ void open (const std::string &ttyname);
+ /// Ferme le port série, appellé automatiquement dans le destructeur de la
+ /// classe SerialBase.
+ void close (void);
+ private:
+ /// Décode le ttyname, voir open.
+ void decode (const std::string &ttyname, std::string &tty, int &speed,
+ char &par) const;
+};
+
+#endif // serial_dev_hh
diff --git a/i/chuck/src/serial/serial_stdio.cc b/i/chuck/src/serial/serial_stdio.cc
new file mode 100644
index 0000000..ff652a2
--- /dev/null
+++ b/i/chuck/src/serial/serial_stdio.cc
@@ -0,0 +1,81 @@
+// serial_stdio.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "serial_stdio.hh"
+#include "utils/errno_exception.hh"
+
+#include <fcntl.h>
+
+/// Constructeur.
+SerialStdio::SerialStdio (bool blocking/*false*/)
+ : blocking_ (blocking)
+{
+}
+
+/// Destructeur.
+SerialStdio::~SerialStdio (void)
+{
+ close ();
+}
+
+/// Ouvre et paramètre le port série.
+void
+SerialStdio::open (const std::string &ttyname)
+{
+ struct termios tios;
+ fdIn_ = 0;
+ fdOut_ = 1;
+ // Sauver la configuration courante du port série.
+ tcgetattr (fdIn_, &old_);
+ // Paramètrer les options du port série.
+ // Attention, affecter des valeurs directement est une mauvaise pratique,
+ // regarder SerialDev pour un bon exemple.
+ tios.c_cflag = CS8 | CLOCAL | CREAD;
+ tios.c_iflag = IGNBRK | IGNPAR;
+ tios.c_oflag = 0;
+ tios.c_lflag = 0;
+ // On n'attend jamais si on est en non-block. On attend sinon.
+ tios.c_cc[VTIME] = 0;
+ if (blocking_)
+ tios.c_cc[VMIN] = 1;
+ else
+ tios.c_cc[VMIN] = 0;
+ // Vider et configurer le port série.
+ tcflush (fdIn_, TCIFLUSH);
+ tcsetattr (fdIn_, TCSANOW, &tios);
+}
+
+/// Ferme le port série, appellé automatiquement dans le destructeur de la
+/// classe SerialBase.
+void
+SerialStdio::close (void)
+{
+ if (fdIn_ != -1)
+ {
+ tcsetattr (fdIn_, TCSANOW, &old_);
+ fdIn_ = -1;
+ fdOut_ = -1;
+ }
+}
+
diff --git a/i/chuck/src/serial/serial_stdio.hh b/i/chuck/src/serial/serial_stdio.hh
new file mode 100644
index 0000000..ea10eff
--- /dev/null
+++ b/i/chuck/src/serial/serial_stdio.hh
@@ -0,0 +1,48 @@
+#ifndef serial_stdio_hh
+#define serial_stdio_hh
+// serial_stdio.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "serial_base.hh"
+
+#include <termios.h>
+
+/// Classe de contrôle du port serie factice sur l'entrée/sortie standart.
+class SerialStdio : public SerialBase
+{
+ bool blocking_;
+ struct termios old_;
+ public:
+ /// Constructeur.
+ SerialStdio (bool blocking = false);
+ /// Destructeur.
+ ~SerialStdio (void);
+ /// Ouvre et paramètre le port série.
+ void open (const std::string &ttyname);
+ /// Ferme le port série, appellé automatiquement dans le destructeur de la
+ /// classe SerialBase.
+ void close (void);
+};
+
+#endif // serial_stdio_hh
diff --git a/i/chuck/src/serial/test_serial.cc b/i/chuck/src/serial/test_serial.cc
new file mode 100644
index 0000000..6c0b771
--- /dev/null
+++ b/i/chuck/src/serial/test_serial.cc
@@ -0,0 +1,88 @@
+// test_serial.cc - Programme de test pour le port série.
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "serial.hh"
+//#include "date/date.hh"
+
+#include <iostream>
+
+void
+syntax (void)
+{
+ std::cout << "test_serial ttyname commandes... - Test la classe Serial.\n"
+ " a carte d'asservissement.\n"
+ " e échèle de 0 à 255 puis 0...\n"
+ " <val> envois une valeur." << std::endl;
+}
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ if (argc < 3)
+ {
+ syntax ();
+ return 1;
+ }
+ Serial s;
+ s.open (argv[1]);
+ switch (argv[2][0])
+ {
+ case 'a':
+ s.write ("!g1\r", 3);
+ //Date::getInstance ().wait (1000);
+ s.write ("!v0303\r", 7);
+ //Date::getInstance ().wait (5000);
+ s.write ("!s\r", 3);
+ break;
+ case 'e':
+ while (1)
+ {
+ for (int i = 0; i < 256; ++i)
+ {
+ std::cout << i << std::endl;
+ s.putchar (i);
+ //Date::getInstance ().wait (100);
+ }
+ for (int i = 255; i >= 0; --i)
+ {
+ std::cout << i << std::endl;
+ s.putchar (i);
+ //Date::getInstance ().wait (100);
+ }
+ }
+ break;
+ default:
+ int i = atoi (argv[2]);
+ std::cout << i << std::endl;
+ s.putchar (i);
+ break;
+ }
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ return 1;
+ }
+}
diff --git a/i/chuck/src/socket/Makefile.defs b/i/chuck/src/socket/Makefile.defs
new file mode 100644
index 0000000..1ff9efc
--- /dev/null
+++ b/i/chuck/src/socket/Makefile.defs
@@ -0,0 +1,12 @@
+PROGRAMS += test_socket test_socket_databuffer #test_server
+
+socket_basic_OBJECTS = address.o socket_server.o socket_client.o
+socket_databuffer_OBJECTS = socket_databuffer.o $(socket_basic_OBJECTS) \
+ $(data_OBJECTS)
+
+test_socket_OBJECTS = test_socket.o $(socket_basic_OBJECTS) $(data_OBJECTS)
+test_socket_databuffer_OBJECTS = test_socket_databuffer.o \
+ $(socket_databuffer_OBJECTS) $(data_OBJECTS) \
+ $(socket_basic_OBJECTS)
+#test_server_OBJECTS = test_server.o $(net_OBJECTS) $(data_OBJECTS) \
+ $(image_OBJECTS)
diff --git a/i/chuck/src/socket/address.cc b/i/chuck/src/socket/address.cc
new file mode 100644
index 0000000..4567e2e
--- /dev/null
+++ b/i/chuck/src/socket/address.cc
@@ -0,0 +1,93 @@
+// address.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+#include "address.hh"
+
+#include <netdb.h>
+#include <stdexcept>
+
+/// Constructeur par défaut.
+Address::Address (void)
+ : port_ (0)
+{
+ resolv ();
+}
+
+/// Constructeur avec le port (serveur)
+Address::Address (const int port)
+ : port_ (port)
+{
+ resolv ();
+}
+/// Constructeur avec hôte et port.
+Address::Address (const std::string &host, const int port)
+ : host_ (host), port_ (port)
+{
+ resolv ();
+}
+
+/// Constructeur à partir de la strcuture d'adresse.
+Address::Address (const sockaddr *sa, socklen_t sl)
+{
+ // On vérifie que c'est vraiment un struct sockaddr_in
+ if (sl != sizeof (sockaddr_in))
+ throw std::invalid_argument ("Invalide Adresse");
+ sa_ = * reinterpret_cast<const sockaddr_in*> (sa);
+}
+
+/// Résolution de la structure d'adresse depuis l'hôte/port
+void
+Address::resolv (void)
+{
+ // Cas du serveur, pas d'hôte
+ if (host_.empty ())
+ sa_.sin_addr.s_addr = htonl (INADDR_ANY);
+ else
+ {
+ // Convertion de l'hôte en structure adresse
+ if (!inet_pton (AF_INET, host_.c_str (), &sa_.sin_addr))
+ {
+ hostent *host_info = gethostbyname (host_.c_str ());
+ if (!host_info)
+ throw std::runtime_error (host_ + " : Hôte inconnue");
+ }
+ }
+ sa_.sin_family = AF_INET;
+ // Convertion pour le passage sur le réseau
+ sa_.sin_port = htons (port_);
+}
+
+/// Résolution de l'hôte/port depuis la structure d'adresse
+void
+Address::unresolv (void)
+{
+ hostent *host_info;
+ // Recherche de l'hôte
+ host_info = gethostbyaddr (reinterpret_cast<char *> (&(sa_.sin_addr)), sizeof sa_.sin_addr, AF_INET);
+ if (!host_info)
+ host_ = inet_ntoa (sa_.sin_addr);
+ else
+ host_ = host_info->h_name;
+ // Recherche du port
+ port_ = ntohs (sa_.sin_port);
+}
diff --git a/i/chuck/src/socket/address.hh b/i/chuck/src/socket/address.hh
new file mode 100644
index 0000000..53fca07
--- /dev/null
+++ b/i/chuck/src/socket/address.hh
@@ -0,0 +1,76 @@
+#ifndef address_hh
+#define address_hh
+// address.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <string>
+#include <ostream>
+
+/// S'occupe de gérer les adresses.
+class Address {
+ /// La structure sockaddr_in de type réseau/AF_INET.
+ sockaddr_in sa_;
+ /// Le nom d'hôte de l'adresse.
+ std::string host_;
+ /// Le numéro de port de l'adresse.
+ int port_;
+
+ public:
+ /// Constructeur par défaut.
+ Address (void);
+ /// Constructeur pour le serveur. (port seulement)
+ Address (const int port);
+ /// Constructeur avec hôte et port.
+ Address (const std::string &host, const int port);
+ /// Constructeur à partir de la structure d'adresse.
+ Address (const sockaddr *sa, socklen_t sl);
+ /// Geter sockaddr.
+ const sockaddr *getSockaddr (void) const { return
+ reinterpret_cast<const sockaddr *> (&sa_); }
+ /// Geter hôte.
+ const std::string &getHost (void) const { return host_; }
+ /// Geter port.
+ const int getPort (void) const { return port_; }
+
+ private:
+ /// Résolution adresse vers hôte/port
+ void resolv (void);
+ /// Résolution hôte/port vers adresse
+ void unresolv (void);
+
+};
+
+/// Surcharge de l'opérateur << pour l'affichage.
+inline std::ostream &
+operator<< (std::ostream &s, const Address &a)
+{
+ return s << a.getHost () << ':' << a.getPort ();
+}
+
+#endif // address_hh
diff --git a/i/chuck/src/socket/server_socket.cc b/i/chuck/src/socket/server_socket.cc
new file mode 100644
index 0000000..539b94e
--- /dev/null
+++ b/i/chuck/src/socket/server_socket.cc
@@ -0,0 +1,86 @@
+// server_socket.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+#include "server_socket.hh"
+
+#include "address.hh"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdexcept>
+
+/// Constructeur par défaut.
+ServerSocket::ServerSocket (int port)
+{
+ bind (port);
+}
+
+/// Bind le serveur sur un port d'écoute.
+void
+ServerSocket::bind (int port)
+{
+ static const int reuse_s = 1;
+ // Adresse sur un port (pas d'hote, écoutera de partout)
+ Address a (port);
+ // Création du socket IPv4 - TCP
+ socket_ = socket (PF_INET, SOCK_STREAM, 0);
+ if (socket_ == -1)
+ throw std::runtime_error ("Erreur de création du socket");
+ // Socket réutilisable en cas d'arret "brutale"
+ if (setsockopt (socket_, SOL_SOCKET, SO_REUSEADDR,
+ &reuse_s, sizeof (int)) == -1)
+ throw std::runtime_error ("Erreur setsockopt : reusable");
+ // Bindage du socket sur le port et l'adresse
+ if (::bind (socket_, a.getSockaddr (), sizeof (struct sockaddr_in)) == -1)
+ throw std::runtime_error ("Erreur de bind du socket");
+ // On met le socket en attente de connexion
+ if (listen (socket_, 0) == -1)
+ throw std::runtime_error ("Erreur de listen");
+}
+
+// Accepte une nouvelle connexion.
+int
+ServerSocket::accept (void) const
+{
+ int s = ::accept (socket_, 0, 0);
+ if (s == -1)
+ throw std::runtime_error ("Erreur d'accept de nouvelles connexions");
+ return s;
+}
+
+// Accepte une nouvelle connexion et remplie Address.
+int
+ServerSocket::accept (Address &a) const
+{
+ sockaddr_in sa;
+ socklen_t sl = sizeof sa;
+ int s = ::accept (socket_, reinterpret_cast<sockaddr *> (&sa),
+ &sl);
+ if (s == -1)
+ {
+ throw std::runtime_error ("Erreur d'accept nouvelle connexion");
+ }
+ // Récupération de l'adresse
+ a = Address (reinterpret_cast<const sockaddr *> (&sa), sl);
+ return s;
+}
diff --git a/i/chuck/src/socket/server_socket.hh b/i/chuck/src/socket/server_socket.hh
new file mode 100644
index 0000000..159aa65
--- /dev/null
+++ b/i/chuck/src/socket/server_socket.hh
@@ -0,0 +1,48 @@
+#ifndef server_socket_hh
+#define server_socket_hh
+// server_socket.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+#include <unistd.h>
+class Address;
+
+/// Créer un server TCP pour le transfert des données.
+class ServerSocket {
+ private:
+ /// L'identificateur du socket.
+ int socket_;
+ public:
+ /// Constructeur par défaut.
+ ServerSocket (int port);
+ /// Destructeur.
+ ~ServerSocket () { close (socket_); }
+ /// Accepte une nouvelle connexion et remplie Address.
+ int accept (Address &a) const;
+ /// Accepte une nouvelle connexion.
+ int accept (void) const;
+ private:
+ /// Bind le serveur sur un port d'écoute.
+ void bind (int port);
+};
+#endif // server_socket_hh
diff --git a/i/chuck/src/socket/socket_client.cc b/i/chuck/src/socket/socket_client.cc
new file mode 100644
index 0000000..951ea6a
--- /dev/null
+++ b/i/chuck/src/socket/socket_client.cc
@@ -0,0 +1,115 @@
+/* socket_client.cc - Définition de la classe des sockets client */
+/* Simulotron - Programme de simulation de robot {{{
+ *
+ * Copyright (C) 2005 Nicolas Haller
+ *
+ * Robot APB Team/Efrei 2005.
+ * Web: http://assos.efrei.fr/robot/
+ * Email: robot AT efrei DOT fr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+#include "socket/socket_client.hh"
+#include "socket/socket_server.hh"
+#include "socket/address.hh"
+#include "utils/errno_exception.hh"
+
+#include <sys/socket.h>
+#include <cerrno>
+
+SocketClient::SocketClient (void)
+{
+ // Crée le file descriptor du socket
+ socket_ = socket (PF_INET, SOCK_STREAM, 0);
+ if (socket_ < 0)
+ throw errno_exception ("Socket: La chaussette n'a pas pu être tricoté", errno);
+}
+
+SocketClient::SocketClient (SocketServer & socketServer)
+{
+ socket_ = socketServer.accept ();
+ if (socket_ < 0)
+ throw errno_exception ("Socket: Problème lors de la construction d'une chaussette cliente par accept", errno);
+}
+
+SocketClient::~SocketClient (void)
+{
+ if (socket_ >= 0)
+ ::close (socket_);
+}
+
+void
+SocketClient::connect (const Address & address)
+{
+ if (::connect (socket_, address.getSockaddr (), sizeof (sockaddr_in)) < 0)
+ throw errno_exception ("Socket: Impossible de mettre la chaussette", errno);
+}
+
+void
+SocketClient::connect (const std::string & address, int port)
+{
+ connect (Address(address, port));
+}
+
+bool
+SocketClient::read (std::string & strReaded, bool bloquant)
+{
+ int charReaded;
+ char buffer[BUFFER_SIZE];
+ // Vérifie si il y a quelque chose à lire et retourne si non
+ if (!bloquant)
+ {
+ fd_set fds;
+ timeval tv = {0, 0};
+ FD_ZERO(&fds);
+ FD_SET(socket_, &fds);
+ if(select(socket_ + 1, &fds, NULL, NULL, &tv) == 0)
+ return false;
+ }
+ strReaded.clear();
+ do
+ {
+ charReaded = ::read (socket_, buffer, BUFFER_SIZE - 1);
+ if (charReaded < 0)
+ throw errno_exception ("SocketClient: problème de lecture", errno);
+ //buffer[charReaded] = 0;
+ //str += buffer;
+ strReaded.append(buffer, charReaded);
+ }while (charReaded == BUFFER_SIZE - 1);
+ return true;
+}
+
+void
+SocketClient::write (const std::string & str)
+{
+ write(reinterpret_cast<const uint8_t *>(str.data()), str.size());
+}
+
+void
+SocketClient::write (const uint8_t * buffer, unsigned size)
+{
+ int retval;
+
+ retval = ::write (socket_, buffer, size);
+ if (retval < 0)
+ throw errno_exception ("SocketClient: erreur d'écriture (write()) ", errno);
+}
+
+//int
+//SocketClient::getFD(void)
+//{
+// return socket_;
+//}
diff --git a/i/chuck/src/socket/socket_client.hh b/i/chuck/src/socket/socket_client.hh
new file mode 100644
index 0000000..ad8d1ea
--- /dev/null
+++ b/i/chuck/src/socket/socket_client.hh
@@ -0,0 +1,63 @@
+#ifndef socket_client_hh
+#define socket_client_hh
+/* socket_client.hh - Classe des socket client */
+/* Simulotron - Programme de simulation de robot {{{
+ *
+ * Copyright (C) 2005 Nicolas Haller
+ *
+ * Robot APB Team/Efrei 2005.
+ * Web: http://assos.efrei.fr/robot/
+ * Email: robot AT efrei DOT fr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+
+#include "utils/non_copyable.hh"
+
+#include <string>
+#include <stdint.h>
+
+class Address;
+class SocketServer;
+
+class SocketClient :public NonCopyable
+{
+ private:
+ /// Ze socket
+ int socket_;
+ /// constantes
+ /// Taille max du buffer de lecture/ecriture
+ static const int BUFFER_SIZE = 256;
+ public:
+ /// Constructeur
+ SocketClient (void);
+ /// Constructeur accept
+ SocketClient (SocketServer & socketServer);
+ /// Destructeur
+ ~SocketClient (void);
+ /// Connect le client au serveur
+ void connect (const Address & address);
+ /// Connect le client au serveur en se chargeant de créer Address
+ void connect (const std::string & address, int port);
+ /// lit du socket
+ bool read (std::string & strReaded, bool bloquant);
+ /// écrit dans le socket
+ void write (const std::string & str);
+ /// écrit dans le socket
+ void write (const uint8_t * buffer, unsigned size);
+};
+
+#endif //socket_client_hh
diff --git a/i/chuck/src/socket/socket_databuffer.cc b/i/chuck/src/socket/socket_databuffer.cc
new file mode 100644
index 0000000..1b4258c
--- /dev/null
+++ b/i/chuck/src/socket/socket_databuffer.cc
@@ -0,0 +1,97 @@
+// socket_databuffer.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Haller
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~haller/
+// Email: <nicolas@boiteameuh.org>
+// }}}
+#include "socket_databuffer.hh"
+
+#include <stdexcept>
+#include <iostream>
+
+// Constructeur
+SocketDataBuffer::SocketDataBuffer(void)
+ :SocketClient(), dbSize_(0) // TODO Ça sert à quelque chose où il le fait implicitement?
+{
+}
+
+// Constructeur accept
+SocketDataBuffer::SocketDataBuffer(SocketServer & socketServer)
+ :SocketClient(socketServer), dbSize_(0)
+{
+}
+
+// Récupère un DataBuffer
+// false en valeur de retour avec bloquant = true est un motif de licenciement
+bool
+SocketDataBuffer::read(DataBuffer & dbReaded, bool bloquant)
+{
+ std::string strReceive;
+ do
+ {
+ SocketClient::read(strReceive, bloquant);
+ strBuffer_.append(strReceive);
+ // On regarde si on a assez de donnée pour regarder si on a une en-tête
+ if(strBuffer_.size() > sizeof(unsigned))
+ {
+ dbSize_ = 0;
+ dbSize_ = static_cast<unsigned>(strBuffer_[0]) << 24
+ | static_cast<unsigned>(strBuffer_[1]) << 16
+ | static_cast<unsigned>(strBuffer_[2]) << 8
+ | static_cast<unsigned>(strBuffer_[3]);
+ // On regarde si on a suffisemment de données pour constituer le DB
+ if(dbSize_ <= strBuffer_.size() - 4)
+ {
+ dbBuffer_.write(reinterpret_cast<const uint8_t *>(strBuffer_.c_str() + 4)
+ , dbSize_);
+ dbReaded.swap(dbBuffer_);
+ dbBuffer_.clear();
+ strBuffer_.erase(0, dbSize_ + 4);
+ return true;
+ }
+ }
+ }while(bloquant);
+ return false;
+}
+
+// Ecrit un DB dans le socket
+void
+SocketDataBuffer::write(DataBuffer & db)
+{
+ // On met une en-tête de 4 octects déterminant la taille de la DB
+ unsigned dbSize = db.size();
+ char entete[4];
+ entete[0] = static_cast<char> (dbSize >> 24);
+ entete[1] = static_cast<char> (dbSize >> 16);
+ entete[2] = static_cast<char> (dbSize >> 8);
+ entete[3] = static_cast<char> (dbSize);
+
+ SocketClient::write(std::string(entete,4));
+ // On récupère les données de la dataBuffer
+ uint8_t * donnees = new uint8_t[dbSize];
+ db.read(donnees, dbSize);
+ if (db.size() != 0)
+ throw std::runtime_error("ERREUR DE CODAGE dans SocketDataBuffer"
+ "::Write");
+ // On envoie le tout et on nettoie l'allocation
+ SocketClient::write(std::string(reinterpret_cast<const char *>(donnees),
+ dbSize));
+ delete [] donnees;
+}
diff --git a/i/chuck/src/socket/socket_databuffer.hh b/i/chuck/src/socket/socket_databuffer.hh
new file mode 100644
index 0000000..c385db5
--- /dev/null
+++ b/i/chuck/src/socket/socket_databuffer.hh
@@ -0,0 +1,52 @@
+#ifndef socket_databuffer_hh
+#define socket_databuffer_hh
+// socket_databuffer.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Haller
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~haller/
+// Email: <nicolas@boiteameuh.org>
+// }}}
+
+#include "socket_client.hh"
+#include "data/data_buffer.hh"
+
+/// Class s'occupant en particulier de récupérer les DataBuffer via le réseau
+/// TCP/IP
+class SocketDataBuffer : public SocketClient
+{
+ private:
+ /// Taille de la DB à recevoir
+ unsigned dbSize_;
+ /// Tampon provisoire
+ std::string strBuffer_;
+ /// DataBuffer Provisoire
+ DataBuffer dbBuffer_;
+ public:
+ /// Constructeur
+ SocketDataBuffer(void);
+ /// Constructeur accept
+ SocketDataBuffer(SocketServer & socketServer);
+ /// Récupère un DataBuffer
+ bool read (DataBuffer & dbReaded, bool bloquant);
+ /// Ecrit un DB dans le socket
+ void write (DataBuffer & db);
+};
+
+#endif // socket_databuffer_hh
diff --git a/i/chuck/src/socket/socket_server.cc b/i/chuck/src/socket/socket_server.cc
new file mode 100644
index 0000000..1a9cdb9
--- /dev/null
+++ b/i/chuck/src/socket/socket_server.cc
@@ -0,0 +1,90 @@
+/* socket_serveur.cc - Définition de la classe des sockets client */
+/* Simulotron - Programme de simulation de robot {{{
+ *
+ * Copyright (C) 2005 Nicolas Haller
+ *
+ * Robot APB Team/Efrei 2005.
+ * Web: http://assos.efrei.fr/robot/
+ * Email: robot AT efrei DOT fr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+
+#include "socket_server.hh"
+#include "utils/errno_exception.hh"
+#include "address.hh"
+
+#include <sys/socket.h>
+#include <cerrno>
+
+SocketServer::SocketServer (const Address & address)
+{
+ initSocket(address);
+}
+
+SocketServer::SocketServer (const std::string & address, int port)
+{
+ if(address.empty())
+ initSocket(Address(port));
+ else
+ initSocket(Address(address, port));
+}
+
+SocketServer::~SocketServer (void)
+{
+ if (socket_ >= 0)
+ ::close (socket_);
+}
+
+ void
+SocketServer::listen (int maxQueue)
+{
+ if (::listen (socket_, maxQueue) < 0 )
+ throw errno_exception ("Socket: Impossible d'écouter la mer dans la chaussette", errno);
+}
+
+ int
+SocketServer::accept (void)
+{
+ int socket = ::accept (socket_, 0, 0);
+ if (socket < 0)
+ throw errno_exception ("Socket: Chaussette bloqué à la douane", errno);
+
+ return socket;
+}
+
+int
+SocketServer::getFD (void) const
+{
+ return socket_;
+}
+
+void
+SocketServer::initSocket(const Address & address)
+{
+ static const int reuse_s = 1;
+ // Crée le file descriptor du socket
+ socket_ = socket (PF_INET, SOCK_STREAM, 0);
+ if (socket_ < 0)
+ throw errno_exception ("Socket: La chaussette n'a pas pu être tricoté", errno);
+ // On règle la réusabilité du socket
+ if (setsockopt (socket_, SOL_SOCKET, SO_REUSEADDR,
+ &reuse_s, sizeof (int)) == -1)
+ throw errno_exception ("Socket: Erreur setsockopt : reusable", errno);
+ // On bind le socket
+ if (::bind (socket_, address.getSockaddr (), sizeof (*address.getSockaddr ())) < 0)
+ throw errno_exception ("Socket: Impossible d'assigner la chausette", errno);
+}
diff --git a/i/chuck/src/socket/socket_server.hh b/i/chuck/src/socket/socket_server.hh
new file mode 100644
index 0000000..f2a022e
--- /dev/null
+++ b/i/chuck/src/socket/socket_server.hh
@@ -0,0 +1,56 @@
+#ifndef socket_server_hh
+#define socket_server_hh
+/* socket_server.hh - Classe des sockets serveur */
+/* Simulotron - Programme de simulation de robot {{{
+ *
+ * Copyright (C) 2005 Nicolas Haller
+ *
+ * Robot APB Team/Efrei 2005.
+ * Web: http://assos.efrei.fr/robot/
+ * Email: robot AT efrei DOT fr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+
+#include "utils/non_copyable.hh"
+
+#include <string>
+class Address;
+
+class SocketServer : public NonCopyable
+{
+ private:
+ /// Ze socket
+ int socket_;
+ public:
+ /// Constructeur
+ SocketServer (const Address & address);
+ /// Constructeur s'occupant de Address
+ SocketServer (const std::string & address, int port);
+ /// Destructeur
+ ~SocketServer (void);
+ /// Ecoute le port
+ void listen (int maxQueue);
+ /// accepte une connection et renvoie le fd
+ int accept (void);
+ /// récupère le FD du socket
+ int getFD (void) const;
+ private:
+ /// Initialise le socket
+ void initSocket(const Address & address);
+};
+
+#endif //socket_server_hh
diff --git a/i/chuck/src/socket/socket_text.cc b/i/chuck/src/socket/socket_text.cc
new file mode 100644
index 0000000..da8a23b
--- /dev/null
+++ b/i/chuck/src/socket/socket_text.cc
@@ -0,0 +1,236 @@
+// socket_text.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+#include "socket_text.hh"
+
+#include "server_socket.hh"
+#include "address.hh"
+
+#include <sstream>
+#include <stdexcept>
+#include <iterator>
+#include <fcntl.h>
+
+/// Taille maximum du header
+static const unsigned max_header_size = 10;
+
+/// Constructeur du serveur
+SocketText::SocketText (ServerSocket &ss)
+: recvBufPos_ (0), numMessageBuffer_ (0)
+{
+ headBuf_.resize (max_header_size);
+ socket_ = ss.accept ();
+}
+
+/// Constructeur du serveur avec addresse
+SocketText::SocketText (ServerSocket &ss, Address &a)
+: recvBufPos_ (0), numMessageBuffer_ (0)
+{
+ headBuf_.resize (max_header_size);
+ socket_ = ss.accept (a);
+}
+
+/// Constructeur du client
+SocketText::SocketText (const Address &a)
+: recvBufPos_ (0), numMessageBuffer_ (0)
+{
+ headBuf_.resize (max_header_size);
+ // Création du socket
+ socket_ = socket (AF_INET, SOCK_STREAM, 0);
+ if (socket_ == -1)
+ throw std::runtime_error ("Erreur de création de socket");
+ // Connexion au serveur
+ if (connect (socket_, a.getSockaddr (), sizeof (sockaddr_in)) == -1)
+ throw std::runtime_error ("Erreur de connexion au serveur");
+}
+
+/// Envoie d'un buffer de données.
+SocketText &
+SocketText::operator<< (const DataBuffer &d)
+{
+ // Copie du buffer
+ DataBuffer db (d);
+ // Récupération de la taille du message
+ unsigned size = db.size ();
+ // Données du buffer
+ std::vector<char> data (size);
+ // On y place les données dedans
+ db.read ((uint8_t*) &data[0], size);
+ // Encode les données et le places dans le buffer d'envoie
+ encode (&data[0], size, db.type ());
+ return *this;
+}
+
+/// Reception d'un buffer de données.
+SocketText &
+SocketText::operator>> (DataBuffer &d)
+{
+ if (numMessageBuffer_ > 0)
+ {
+ // Récupération des informations du message qu'on veut retirer
+ unsigned int size = messList_.begin ()->size;
+ d.setType (messList_.begin ()->type);
+ // Récupération du message depuis le buffer
+ std::vector <char> v (size);
+ std::memcpy (&v[0], &recvBuf_[0], size);
+ // Ecriture des données dans le buffer
+ d.write ((uint8_t*) &v[0], v.size ());
+ // Suppression du message du buffer
+ recvBuf_.erase (recvBuf_.begin (), recvBuf_.begin () + size);
+ messList_.erase (messList_.begin ());
+ bufferOldSize_ -= size;
+ bufferCurSize_ -= size;
+ recvBufPos_ -= size;
+ numMessageBuffer_--;
+ }
+ return *this;
+}
+
+/// Envoie des données du buffer.
+int
+SocketText::send (void)
+{
+ int status;
+ status = ::send (socket_, &sendBuf_[0], sendBuf_.size (), MSG_NOSIGNAL);
+ if (status == -1 && errno != EWOULDBLOCK)
+ {
+ throw std::runtime_error ("Erreur de send de socket");
+ }
+ if (status >= 0)
+ {
+ if (status != 0)
+ sendBuf_.erase (sendBuf_.begin (), sendBuf_.begin () + status);
+ return status;
+ }
+ return -1;
+}
+
+/// Encodage du message (rajout du header)
+void
+SocketText::encode (const char *data, const int size,
+ const DataBuffer::dataType_e type)
+{
+ // Création du header (1H4242H)
+ std::ostringstream o;
+ // Rajout du type
+ if (!(o << type))
+ throw std::runtime_error ("Erreur de convertion int -> string");
+ o << "H";
+ if (!(o << size ))
+ throw std::runtime_error ("Erreur de convertion int -> string");
+ o << "H";
+ // Recopie du header dans le buffer
+ std::string s = o.str ();
+ std::string::const_iterator sEnd = s.end ();
+ unsigned int compt = 0;
+ std::string::const_iterator i = s.begin ();
+ // Ecriture d'un header de taille fixe
+ while (compt < max_header_size)
+ {
+ if (i != sEnd)
+ {
+ sendBuf_.push_back (*i);
+ i++;
+ }
+ else
+ sendBuf_.push_back ('H');
+ compt++;
+ }
+ // Rajout des données dans le buffer
+ for (int i = 0; i < size; i++)
+ sendBuf_.push_back (data[i]);
+}
+
+/// Décodage du header.
+int
+SocketText::decode (void)
+{
+ mess_t header;
+ header.type = (DataBuffer::dataType_e) std::atoi (&headBuf_[0]);
+ header.size = std::atoi (&headBuf_[2]);
+ messList_.push_back (header);
+ return header.size;
+}
+
+/// Reception de données dans un vecteur.
+bool
+SocketText::recv ()
+{
+ // FIXME C'est KK
+ int status;
+ static unsigned int headerPos = 0;
+
+ // On n'a pas reçu encore de quoi faire un header
+ if (headerPos < max_header_size)
+ {
+ status = ::recv (socket_, &headBuf_[headerPos],
+ max_header_size - headerPos, MSG_NOSIGNAL);
+ if (status == -1 && errno != EWOULDBLOCK)
+ throw std::runtime_error ("Erreur de send de socket");
+ if (status > 0)
+ headerPos += status;
+ }
+ // Décodage du header
+ if (headerPos == max_header_size)
+ {
+ bufferOldSize_ = recvBuf_.size ();
+ bufferCurSize_ = bufferOldSize_ + decode ();
+ recvBuf_.resize (bufferCurSize_);
+ headerPos ++;
+ }
+ // Récupération du message lui-même
+ if (headerPos > max_header_size)
+ {
+ status = ::recv (socket_, &recvBuf_[recvBufPos_],
+ bufferCurSize_ - recvBufPos_, MSG_NOSIGNAL);
+ if (status == -1 && errno != EWOULDBLOCK)
+ throw std::runtime_error ("Erreur de send de socket");
+ if (status > 0)
+ recvBufPos_ += status;
+ if (recvBufPos_ == bufferCurSize_)
+ {
+ headerPos = 0;
+ numMessageBuffer_++;
+ }
+ }
+ return numMessageBuffer_ > 0;
+}
+
+/// Changement du bloquant non/bloquant.
+void
+SocketText::nonblock (bool flag)
+{
+ // Récupération de l'ancien flag.
+ int old = fcntl (socket_, F_GETFL, 0);
+ if (old == -1)
+ throw std::runtime_error ("Erreur de fcntl");
+ // Change le flag.
+ if (flag)
+ old |= O_NONBLOCK;
+ else
+ old &= ~O_NONBLOCK;
+ // Ecrit le nouveau flag.
+ if (fcntl (socket_, F_SETFL, old) == -1)
+ throw std::runtime_error ("Erreur de fcntl");
+}
diff --git a/i/chuck/src/socket/socket_text.hh b/i/chuck/src/socket/socket_text.hh
new file mode 100644
index 0000000..b734753
--- /dev/null
+++ b/i/chuck/src/socket/socket_text.hh
@@ -0,0 +1,80 @@
+#ifndef socket_text_hh
+#define socket_text_hh
+// socket_text.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+class ServerSocket;
+class Address;
+#include "data/data_buffer.hh"
+
+#include <vector>
+
+class SocketText {
+ /// Structure pour stocker les informations d'un message.
+ typedef struct {
+ unsigned int size;
+ DataBuffer::dataType_e type;
+ } mess_t;
+ std::vector <mess_t> messList_;
+ /// L'identificateur du socket.
+ int socket_;
+ /// Buffer pour le header.
+ std::vector<char> headBuf_;
+ /// Buffer de reception de données.
+ std::vector<char> recvBuf_;
+ /// Buffer d'émission de données.
+ std::vector<char> sendBuf_;
+ /// Taille des buffers d'E/S XXX
+ unsigned int recvBufPos_;
+ unsigned int bufferOldSize_;
+ unsigned int bufferCurSize_;
+ /// Nombre de message dans le buffer
+ int numMessageBuffer_;
+ DataBuffer::dataType_e type_;
+ /// Encodage du message (rajout du header)
+ void encode (const char *data, const int size,
+ const DataBuffer::dataType_e type);
+ /// Décodage du header.
+ int decode (void);
+
+ public:
+ /// Constructeur du serveur.
+ SocketText (ServerSocket &ss);
+ /// Constructeur du serveur avec addresse.
+ SocketText (ServerSocket &ss, Address &a);
+ /// Constructeur du client.
+ SocketText (const Address &a);
+ /// Envoie d'un buffer de données.
+ SocketText &operator<< (const DataBuffer &d);
+ /// Reception d'un buffer de données.
+ SocketText &operator>> (DataBuffer &d);
+ /// Envoie des données du buffer.
+ int send (void);
+ /// Reception de données dans un vecteur.
+ bool recv (void);
+ /// Changement du bloquant non/bloquant.
+ void nonblock (bool flag = true);
+};
+
+#endif // socket_text_hh
diff --git a/i/chuck/src/socket/test_server.cc b/i/chuck/src/socket/test_server.cc
new file mode 100644
index 0000000..81399ec
--- /dev/null
+++ b/i/chuck/src/socket/test_server.cc
@@ -0,0 +1,91 @@
+// test_socket.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+#include "server_socket.hh"
+#include "address.hh"
+#include "socket_text.hh"
+#include "data/data_input_file.hh"
+#include "data/data_buffer.hh"
+#include "image/raw_reader.hh"
+#include "image/image.hh"
+
+#include <iostream>
+#include <fstream>
+#include <stdexcept>
+
+int
+main (int argc, char **argv)
+{
+ if (argc == 3)
+ {
+ try
+ {
+ // Serveur
+ ServerSocket ss (atoi (argv[1]));
+ Address a;
+ SocketText st (ss, a);
+ st.nonblock ();
+ // DataBuffer de reception
+ DataBuffer db;
+ uint8_t c = 'a';
+ DataBuffer dbAskImg (&c, 1, 1, DataBuffer::AskImage);
+ st << dbAskImg;
+ st.send ();
+ // Reception des données
+ while (!st.recv ());
+ st >> db;
+ if (db.type () != DataBuffer::Image)
+ throw std::runtime_error ("Echec de la transmission");
+ RawReader reader (db, 360, 296, Image::rgb);
+ Image img (360, 296, Image::rgb);
+ img.read (reader);
+ std::ofstream file (argv[2]);
+ file.write ((char*) img.getBuf (), img.getBufSize ());
+
+// // Récupération des données du DataBuffer
+// std::vector <char> v (db.size ());
+// db.read ((uint8_t*) &v[0], db.size ());
+// // Ecriture dans le fichier
+// std::ofstream file (argv[2]);
+// file.write (&v[0], v.size ());
+// DataBuffer db1;
+// // Reception des données
+// while (!st.recv ());
+// st >> db1;
+// std::cout << ">> Reçu " << db1.size () << " bits." << std::endl;
+// if (db1.type () != DataBuffer::Image)
+// throw std::runtime_error ("Echec de la transmission");
+ }
+ catch (const std::runtime_error &r)
+ {
+ std::cerr << argv[0] << ": " << r.what () << std::endl;
+ return 1;
+ }
+ }
+ else
+ {
+ std::cerr << "Syntaxe: " << argv[0] << " port out_file" << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/i/chuck/src/socket/test_socket.cc b/i/chuck/src/socket/test_socket.cc
new file mode 100644
index 0000000..81b39a0
--- /dev/null
+++ b/i/chuck/src/socket/test_socket.cc
@@ -0,0 +1,156 @@
+/* test_socket.cc - Programme de test des sockets. */
+/* Simulotron - Programme de simulation de robot {{{
+ *
+ * Copyright (C) 2005 Nicolas Haller
+ *
+ * Robot APB Team/Efrei 2005.
+ * Web: http://assos.efrei.fr/robot/
+ * Email: robot AT efrei DOT fr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+#include "socket_server.hh"
+#include "socket_client.hh"
+#include "utils/errno_exception.hh"
+
+#include <iostream>
+#include <string>
+#include <sys/wait.h>
+
+//Chaine et char de test
+const std::string strDepart = "J'aime la prog système.";
+std::string strDest;
+const char a = 'f';
+char b;
+
+int testSockServ(SocketServer & sockServ);
+int testSockClient(int pauseMode);
+
+int main(void)
+{
+ pid_t pid;
+ int resultServer = 0, resultClient;
+ // Pause mode pour débugger le fork
+ int pauseMode = 0;
+
+ // Création de la socket serveur;
+ SocketServer sockServ("",4242);
+ // Mise en écoute du socket serveur
+ sockServ.listen(12);
+
+ // on fork pour traiter le client et le serveur
+ pid = fork();
+ if(pid == 0) //Processus fils
+ testSockClient(pauseMode);
+ else //Processus parent
+ resultServer = testSockServ(sockServ);
+
+ // On analyse les résultats
+ wait(&resultClient);
+ if (!(WIFEXITED(resultClient) && WEXITSTATUS(resultClient) == 0))
+ {
+ std::cerr << "ECHEC: Problème coté client" << std::endl;
+ exit (-1);
+ }
+ if (resultServer != 0)
+ {
+ std::cerr << "ECHEC: Problème coté serveur" << std::endl;
+ exit (-1);
+ }
+
+ return 0;
+}
+
+int testSockServ(SocketServer & sockServ)
+{
+ try
+ {
+ // Acceptation d'une connection
+ SocketClient sockFork(sockServ);
+ // Reception d'un message
+ sockFork.read(strDest, true);
+ if(strDepart != strDest)
+ {
+ std::cout << "CHIER!! Le message d'origine est altéré en ecrivant du client au serveur!!" << std::endl;
+ std::cout << "Le message d'origine: " << strDepart << std::endl;
+ std::cout << "Message reçu: " << std::endl;
+ return 1;
+ }
+ // Ecriture du serveur au client
+ sockFork.write(strDepart);
+ // Reception d'un char
+ //b = sockFork.getChar();
+ //if(a != b)
+ //{
+ // std::cout << "CHIER!! Le char d'origine est altéré en ecrivant du client au serveur!!" << std::endl;
+ // std::cout << "Le char d'origine: " << a << std::endl;
+ // std::cout << "Le char d'arrivé: " << b << std::endl;
+ // return 1;
+ //}
+ // Ecriture du serveur vers le client
+ //sockFork.putChar(a);
+ }
+ catch(errno_exception & chier)
+ {
+ std::cout << "CHIER !! Une exception a été lancé coté serveur!!" << std::endl;
+ std::cout << chier.what() << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+int testSockClient(int pauseMode)
+{
+ // Chance pour debbuger le fork
+ while(pauseMode)
+ sleep(10);
+ try
+ {
+ // Création de la socket client
+ SocketClient sockClient;
+ // Demande de connection
+ sockClient.connect(std::string("127.0.0.1"), 4242);
+ // Ecriture du client dans le serveur
+ sockClient.write(strDepart);
+ // Reception du message serveur
+ sockClient.read(strDest, true);
+ if(strDepart != strDest)
+ {
+ std::cout << "CHIER!! Le message d'origine est altéré en ecrivant du serveur au client!!" << std::endl;
+ std::cout << "Le message d'origine: " << strDepart << std::endl;
+ std::cout << "Message reçu: " << std::endl;
+ exit (1);
+ }
+ // Ecriture d'un char du client au serveur
+ //sockClient.putChar(a);
+ // Reception d'un char
+ //b = sockClient.getChar();
+ //if(a != b)
+ //{
+ // std::cout << "CHIER!! Le char d'origine est altéré en ecrivant du serveur au client!!" << std::endl;
+ // std::cout << "Le char d'origine: " << a << std::endl;
+ // std::cout << "Le char d'arrivé: " << b << std::endl;
+ // exit (1);
+ //}
+ }
+ catch(errno_exception & chier)
+ {
+ std::cout << "CHIER !! Une exception a été lancé coté client!!" << std::endl;
+ std::cout << chier.what() << std::endl;
+ exit (1);
+ }
+ exit (0);
+}
diff --git a/i/chuck/src/socket/test_socket_databuffer.cc b/i/chuck/src/socket/test_socket_databuffer.cc
new file mode 100644
index 0000000..fb220a8
--- /dev/null
+++ b/i/chuck/src/socket/test_socket_databuffer.cc
@@ -0,0 +1,125 @@
+/* test_socket.cc - Programme de test des sockets. */
+/* Simulotron - Programme de simulation de robot {{{
+ *
+ * Copyright (C) 2005 Nicolas Haller
+ *
+ * Robot APB Team/Efrei 2005.
+ * Web: http://assos.efrei.fr/robot/
+ * Email: robot AT efrei DOT fr
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+#include "socket_server.hh"
+#include "socket_databuffer.hh"
+#include "data/data_buffer.hh"
+#include "utils/errno_exception.hh"
+
+#include <iostream>
+#include <sys/wait.h>
+
+//Chaine et char de test
+const std::string strDepart = "J'aime la prog système.";
+const char a = 'f';
+DataBuffer db1, db2;
+
+int testSockServ(SocketServer & sockServ);
+int testSockClient(int pauseMode);
+
+int main(void)
+{
+ pid_t pid;
+ int resultServer = 0, resultClient;
+ // Pause mode pour débugger le fork
+ int pauseMode = 0;
+
+ // Création de la socket serveur;
+ SocketServer sockServ("",4242);
+ // Mise en écoute du socket serveur
+ sockServ.listen(12);
+
+ // on fork pour traiter le client et le serveur
+ pid = fork();
+ if(pid == 0) //Processus fils
+ testSockClient(pauseMode);
+ else //Processus parent
+ resultServer = testSockServ(sockServ);
+
+ // On analyse les résultats
+ wait(&resultClient);
+ if (!(WIFEXITED(resultClient) && WEXITSTATUS(resultClient) == 0))
+ {
+ std::cerr << "ECHEC: Problème coté client" << std::endl;
+ exit (-1);
+ }
+ if (resultServer != 0)
+ {
+ std::cerr << "ECHEC: Problème coté serveur" << std::endl;
+ exit (-1);
+ }
+
+ return 0;
+}
+
+int testSockServ(SocketServer & sockServ)
+{
+ try
+ {
+ // On crée le DataBuffer
+ db1.write(reinterpret_cast<const uint8_t *>(strDepart.c_str()),
+ strDepart.size());
+ db1.write(reinterpret_cast<const uint8_t *>(&a), sizeof(const char));
+ // Acceptation d'une connection
+ SocketDataBuffer sockFork(sockServ);
+ // On écrit la DataBuffer dans la socket
+ sockFork.write(db1);
+ }
+ catch(errno_exception & chier)
+ {
+ std::cout << "CHIER !! Une exception a été lancé coté serveur!!" << std::endl;
+ std::cout << chier.what() << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+int testSockClient(int pauseMode)
+{
+ // Chance pour debbuger le fork
+ while(pauseMode)
+ sleep(10);
+ try
+ {
+ // Création de la socket client
+ SocketDataBuffer sockDataBuffer;
+ // Demande de connection
+ sockDataBuffer.connect(std::string("127.0.0.1"), 4242);
+ // Reception du message serveur
+ sockDataBuffer.read(db2, true);
+ // Paye ta comparaison de DataBuffer
+ if(db1.size() != db2.size())
+ {
+ std::cout << "CHIER!! Les DB ne font pas la même size" << std::endl;
+ exit (1);
+ }
+ }
+ catch(errno_exception & chier)
+ {
+ std::cout << "CHIER !! Une exception a été lancé coté client!!" << std::endl;
+ std::cout << chier.what() << std::endl;
+ exit (1);
+ }
+ exit (0);
+}
diff --git a/i/chuck/src/socket/test_socket_old.cc b/i/chuck/src/socket/test_socket_old.cc
new file mode 100644
index 0000000..f2beb51
--- /dev/null
+++ b/i/chuck/src/socket/test_socket_old.cc
@@ -0,0 +1,76 @@
+// test_socket.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: %WEB%
+// Email: <dufourj@efrei.fr>
+// }}}
+
+#include "server_socket.hh"
+#include "address.hh"
+#include "socket_text.hh"
+#include "data/data_input_file.hh"
+#include "data/data_buffer.hh"
+
+#include <iostream>
+#include <cstdlib>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+int
+main (int argc, char **argv)
+{
+ if (argc == 4)
+ {
+ try
+ {
+ // Récupération des données du fichier
+ DataInputFile df (argv[3]);
+ std::vector <unsigned char> img (319680);
+ df.read (&img[0], 319680);
+ // Ecriture des données du fichier dans le buffer
+ DataBuffer db (&img[0], img.size (), img.size (),
+ DataBuffer::Image);
+ DataBuffer dbAnswer;
+ // Création du socket
+ char *h = argv[1];
+ SocketText st (Address (h, atoi (argv[2])));
+ st.nonblock ();
+ st >> dbAnswer;
+ if (dbAnswer.type () == DataBuffer::AskImage)
+ {
+ // Envoie des données
+ st << db;
+ while (st.send () != 0);
+ }
+ }
+ catch (const std::runtime_error &r)
+ {
+ std::cerr << argv[0] << ": " << r.what () << std::endl;
+ return 1;
+ }
+ }
+ else
+ {
+ std::cerr << "Syntaxe: " << argv[0] << " host port in_file" <<
+ std::endl;
+ return 1;
+ }
+}
diff --git a/i/chuck/src/tester/Makefile.defs b/i/chuck/src/tester/Makefile.defs
new file mode 100644
index 0000000..eeff4ab
--- /dev/null
+++ b/i/chuck/src/tester/Makefile.defs
@@ -0,0 +1,5 @@
+PROGRAMS += test_tester
+
+tester_OBJECTS = tester.o $(config_OBJECTS) $(interpreter_OBJECTS) $(log_OBJECTS)
+
+test_tester_OBJECTS = test_tester.o $(tester_OBJECTS)
diff --git a/i/chuck/src/tester/test_tester.cc b/i/chuck/src/tester/test_tester.cc
new file mode 100644
index 0000000..d292c7f
--- /dev/null
+++ b/i/chuck/src/tester/test_tester.cc
@@ -0,0 +1,78 @@
+// test_tester.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "tester.hh"
+
+class TestTester : public Tester
+{
+ public:
+ // Constructor
+ TestTester (int argc, char ** argv)
+ : Tester (argc, argv) { }
+ void funcA (const Interpreter::Args &a, bool dryrun)
+ {
+ if (!dryrun)
+ std::cout << " a " << a << std::endl;
+ }
+ void funcB (void)
+ {
+ std::cout << " b ( )" << std::endl;
+ }
+ void funcC (int i)
+ {
+ std::cout << " c ( " << i << " )" << std::endl;
+ }
+ void funcD (const std::string &s)
+ {
+ std::cout << " d ( " << s << " )" << std::endl;
+ }
+ void funcE (int i, const std::string &s, double d)
+ {
+ std::cout << " e ( " << i << ' ' << s << ' ' << d << " )" << std::endl;
+ }
+ void preRun (void)
+ {
+ Interpreter &interpreter = getInterpreter ();
+ // Add functions.
+ interpreter.add ("a", Interpreter::memFunc (*this, &TestTester::funcA), "Function a (any)");
+ interpreter.add ("b", Interpreter::memFunc (*this, &TestTester::funcB), "Function b ()");
+ interpreter.add ("c", Interpreter::memFunc (*this, &TestTester::funcC), "Function c (int)");
+ interpreter.add ("d", Interpreter::memFunc (*this, &TestTester::funcD), "Function d (string)");
+ interpreter.add ("e", Interpreter::memFunc (*this, &TestTester::funcE), "Function e (int, string, double)");
+ }
+};
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ TestTester tt (argc, argv);
+ tt.run ();
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ }
+}
diff --git a/i/chuck/src/tester/tester.cc b/i/chuck/src/tester/tester.cc
new file mode 100644
index 0000000..61f577e
--- /dev/null
+++ b/i/chuck/src/tester/tester.cc
@@ -0,0 +1,141 @@
+// tester.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "tester.hh"
+
+#include <unistd.h> // getopt
+#include <exception> // std::exception
+#include <cstdlib> // std::exit
+#include <sstream> // std::ostringstream
+
+/// Constructor.
+Tester::Tester (int argc, char **argv, const std::string &description)
+ : program_(argv[0]), description_ (description),
+ showCmd_ (false), config_ (argc, argv)
+{
+ // Parse command line
+ getOpt (argc, argv);
+}
+
+/// Getopt command line.
+/// Supported arguemnts :
+/// - -c 'commands list'
+/// - -f <file>
+/// - -h : help
+/// - -l : list commands suppoted
+void
+Tester::getOpt (int argc, char **argv)
+{
+ char *optstring = "hlc:f:";
+ int option;
+ std::string strTmp;
+
+ // Check number of args
+ if (argc < 2)
+ {
+ std::cerr << "Argument missing." << std::endl;
+ usage ();
+ std::exit (1);
+ }
+
+ // Automatic error message
+ opterr = 1;
+
+ while ((option = getopt (argc, argv, optstring)) != EOF)
+ {
+ switch (option)
+ {
+ case 'c':
+ // Check commands
+ commands_ += optarg;
+ break;
+ case 'f':
+ commands_ += ";include \"";
+ commands_ += optarg;
+ commands_ += "\";";
+ break;
+ case 'h':
+ usage ();
+ std::exit (0);
+ break;
+ case 'l':
+ showCmd_ = true;
+ break;
+ case '?':
+ default:
+ usage ();
+ std::exit (2);
+ break;
+ }
+ }
+ if (commands_.empty () && !showCmd_)
+ {
+ usage ();
+ std::exit (2);
+ }
+}
+
+/// Print usage to stdout.
+void
+Tester::usage (void) const
+{
+ std::cout << "Usage: " << program_
+ << " [-c <commands>]"
+ << " [-f <file>]"
+ << std::endl;
+ if (!description_.empty ())
+ std::cout << description_ << std::endl;
+ std::cout << " -c <commands> Commands to run" << std::endl;
+ std::cout << " -f <file> File with commands" << std::endl;
+ std::cout << " -l List all known commands by "
+ << program_ << std::endl;
+}
+
+/// Print all knwon function and role to stdout.
+void
+Tester::listCmd (void) const
+{
+ std::cout << "Commands known by " << program_ << " :" << std::endl;
+ std::cout << interpreter_.help ();
+}
+
+/// Run commands.
+void
+Tester::run (void)
+{
+ // Pre-run
+ preRun ();
+ if (showCmd_)
+ {
+ listCmd ();
+ std::exit (0);
+ }
+ // Check
+ interpreter_.interpretString (commands_, true);
+ // Run !
+ interpreter_.interpretString (commands_, false);
+ // Post-run
+ postRun ();
+}
+
diff --git a/i/chuck/src/tester/tester.hh b/i/chuck/src/tester/tester.hh
new file mode 100644
index 0000000..b9aa312
--- /dev/null
+++ b/i/chuck/src/tester/tester.hh
@@ -0,0 +1,77 @@
+#ifndef tester_hh
+#define tester_hh
+// tester.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "config/config.hh"
+#include "interpreter/interpreter.hh"
+#include "log/data_circular_buffer_factory.hh"
+
+#include <string>
+#include <list>
+#include <map>
+
+class Tester
+{
+ private:
+ /// DataCircularBufferFactory for beeing destruct at the end of the program.
+ /// Note : it must stay at the begining of the class !
+ DataCircularBufferFactory dbc;
+ /// The interperter.
+ Interpreter interpreter_;
+ /// Program name.
+ std::string program_;
+ /// Description of the program.
+ std::string description_;
+ /// Commands to run.
+ std::string commands_;
+ /// Getopt command line.
+ void getOpt (int argc, char **argv);
+ /// Print usage to stdout.
+ void usage (void) const;
+ /// Print all knwon function and role to stdout.
+ void listCmd (void) const;
+ /// Show commands instead of run them.
+ bool showCmd_;
+ protected:
+ /// The config.
+ Config config_;
+ public:
+ /// Constructor.
+ Tester (int argc, char ** argv, const std::string &description = "");
+ /// Destructor.
+ virtual ~Tester (void) { }
+ /// Get a reference to the interpreter.
+ Interpreter &getInterpreter (void) { return interpreter_; }
+ /// Run commands.
+ /// Call preRun, check command, run them, call postRun.
+ void run (void);
+ /// Executed before checking/running commands. Good place to add command
+ /// to the interpreter.
+ virtual void preRun (void) { }
+ /// Executed after running commands.
+ virtual void postRun (void) { }
+};
+
+#endif // tester_hh
diff --git a/i/chuck/src/timer/Makefile.defs b/i/chuck/src/timer/Makefile.defs
new file mode 100644
index 0000000..81a57e2
--- /dev/null
+++ b/i/chuck/src/timer/Makefile.defs
@@ -0,0 +1,5 @@
+PROGRAMS += test_timer
+
+timer_OBJECTS = timer.o
+
+test_timer_OBJECTS = test_timer.o $(timer_OBJECTS)
diff --git a/i/chuck/src/timer/test_timer.cc b/i/chuck/src/timer/test_timer.cc
new file mode 100644
index 0000000..2e8c502
--- /dev/null
+++ b/i/chuck/src/timer/test_timer.cc
@@ -0,0 +1,47 @@
+// test_timer.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "timer.hh"
+
+#include <iostream>
+#include <unistd.h>
+
+int
+main (void)
+{
+ using namespace std;
+ cout << "timer 0 " << Timer::getProgramTime () << ' ' <<
+ Timer::getRoundTime () << endl;
+ sleep (1);
+ cout << "timer 1 " << Timer::getProgramTime () << ' ' <<
+ Timer::getRoundTime () << endl;
+ Timer::startRound ();
+ sleep (2);
+ cout << "timer 3 " << Timer::getProgramTime () << ' ' <<
+ Timer::getRoundTime () << endl;
+ Timer::wait (1500);
+ cout << "timer 4.5 " << Timer::getProgramTime () << ' ' <<
+ Timer::getRoundTime () << endl;
+ return 0;
+}
diff --git a/i/chuck/src/timer/timer.cc b/i/chuck/src/timer/timer.cc
new file mode 100644
index 0000000..662e6de
--- /dev/null
+++ b/i/chuck/src/timer/timer.cc
@@ -0,0 +1,89 @@
+// timer.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "timer.hh"
+
+#include <sys/time.h>
+#include <time.h>
+
+/// Retourne le temps depuis le début du programme en millisecondes.
+int
+Timer::getProgramTime (void)
+{
+ Timer &timer = getInstance ();
+ return getSystemTime () - timer.programStart_;
+}
+
+/// Retourne le temps depuis le début du match en millisecondes.
+int
+Timer::getRoundTime (void)
+{
+ Timer &timer = getInstance ();
+ return timer.roundStart_ != -1 ? getSystemTime () - timer.roundStart_ : 0;
+}
+
+/// Démare le match et enregistre le temps de départ.
+void
+Timer::startRound (void)
+{
+ Timer &timer = getInstance ();
+ timer.roundStart_ = getSystemTime ();
+}
+
+/// Attend un nombre de millisecondes. Attention, le robot ne fait absolument
+/// rien pendant cette periode !
+void
+Timer::wait (int t)
+{
+ timespec ts, r;
+ ts.tv_sec = t / 1000;
+ ts.tv_nsec = (t % 1000) * 1000000;
+ nanosleep (&ts, &r);
+}
+
+/// Retourne une référence vers l'instance unique.
+Timer &
+Timer::getInstance (void)
+{
+ static Timer instance;
+ return instance;
+}
+
+/// Retourne la date système.
+long long
+Timer::getSystemTime (void)
+{
+ timeval tv;
+ gettimeofday (&tv, 0);
+ return ((long long) tv.tv_sec % 1000000) * 1000
+ + (long long) tv.tv_usec / 1000;
+}
+
+/// Constructeur.
+Timer::Timer (void)
+{
+ programStart_ = getSystemTime ();
+ roundStart_ = -1;
+}
+
diff --git a/i/chuck/src/timer/timer.hh b/i/chuck/src/timer/timer.hh
new file mode 100644
index 0000000..341f1da
--- /dev/null
+++ b/i/chuck/src/timer/timer.hh
@@ -0,0 +1,51 @@
+#ifndef timer_hh
+#define timer_hh
+// timer.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+/// Classe de chronométrage.
+class Timer
+{
+ long long programStart_, roundStart_;
+ public:
+ /// Retourne le temps depuis le début du programme en millisecondes.
+ static int getProgramTime (void);
+ /// Retourne le temps depuis le début du match en millisecondes.
+ static int getRoundTime (void);
+ /// Démare le match et enregistre le temps de départ.
+ static void startRound (void);
+ /// Attend un nombre de millisecondes. Attention, le robot ne fait
+ /// absolument rien pendant cette periode !
+ static void wait (int t);
+ private:
+ /// Retourne une référence vers l'instance unique.
+ static Timer &getInstance (void);
+ /// Retourne la date système.
+ static long long getSystemTime (void);
+ /// Constructeur.
+ Timer (void);
+};
+
+#endif // timer_hh
diff --git a/i/chuck/src/utils/Makefile.defs b/i/chuck/src/utils/Makefile.defs
new file mode 100644
index 0000000..8eb0711
--- /dev/null
+++ b/i/chuck/src/utils/Makefile.defs
@@ -0,0 +1,11 @@
+PROGRAMS += test_any test_callback test_bind test_signalhandler
+
+utils_OBJECTS = fd_set.o hexa.o
+
+test_any_OBJECTS = test_any.o
+
+test_callback_OBJECTS = test_callback.o
+
+test_bind_OBJECTS = test_bind.o
+
+test_signalhandler_OBJECTS = test_signalhandler.o
diff --git a/i/chuck/src/utils/any.hh b/i/chuck/src/utils/any.hh
new file mode 100644
index 0000000..dc6204e
--- /dev/null
+++ b/i/chuck/src/utils/any.hh
@@ -0,0 +1,125 @@
+#ifndef any_hh
+#define any_hh
+// any.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2003-2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <typeinfo>
+#include <exception>
+#include <iostream>
+
+/// This class can contain a data of almost any type. This very type must be
+/// CopyConstructible and OutputStreamable. The OutputStreamable restriction
+/// could be removed, but it is so convenient to output an any...
+class any
+{
+ class AbstractHolder;
+ AbstractHolder *holder_;
+ public:
+ /// Default constructor.
+ any (void);
+ /// Constructor.
+ template<typename T>
+ any (const T &value);
+ /// Copy constructor.
+ any (const any &other);
+ /// Destructor.
+ ~any (void);
+ /// Swap content between two any objects.
+ any &swap (any &other);
+ /// Copy another any object.
+ any &operator= (const any &other);
+ /// Copy another object into this any.
+ template<typename T>
+ any &operator= (const T &value);
+ /// Test if the any object is empty.
+ bool empty (void) const;
+ /// Return the std::type_info of the contained object.
+ const std::type_info &type (void) const;
+ private:
+ template<typename T>
+ friend T *any_cast (any *rhs);
+ friend std::ostream &operator<< (std::ostream &os, const any &rhs);
+ /// Abstract holder class.
+ class AbstractHolder
+ {
+ public:
+ /// Destructor.
+ virtual ~AbstractHolder (void);
+ virtual const std::type_info &type (void) const = 0;
+ virtual AbstractHolder *clone (void) const = 0;
+ virtual std::ostream &print (std::ostream &os) const = 0;
+ };
+ /// Holder class, templated.
+ template<typename T>
+ class Holder : public AbstractHolder
+ {
+ public:
+ T value_;
+ public:
+ Holder (const T &value);
+ virtual const std::type_info &type (void) const;
+ virtual AbstractHolder *clone (void) const;
+ virtual std::ostream &print (std::ostream &os) const;
+ };
+};
+
+/// Return a pointer to the contained object or 0 on faillure.
+template<typename T>
+T *
+any_cast (any *rhs);
+
+/// Return a const pointer to the contained object or 0 on faillure.
+template<typename T>
+const T *
+any_cast (const any *rhs);
+
+/// Return a const reference to the contained object or throw a bad_any_cast
+/// on faillure.
+template<typename T>
+const T &
+any_cast (const any &rhs);
+
+/// Object throw if a any_cast returning a reference fail.
+class bad_any_cast : public std::bad_cast
+{
+ std::string what_;
+ public:
+ /// Constructor.
+ bad_any_cast (const std::type_info &to, const std::type_info &from);
+ /// Destructor which should throw nothing.
+ virtual ~bad_any_cast() throw()
+ { }
+ /// Get the error text.
+ virtual const char *what() const throw()
+ { return what_.c_str (); }
+};
+
+/// Print the contained object.
+std::ostream &
+operator<< (std::ostream &os, const any &rhs);
+
+#include "any.tcc"
+
+#endif // any_hh
diff --git a/i/chuck/src/utils/any.tcc b/i/chuck/src/utils/any.tcc
new file mode 100644
index 0000000..70d1084
--- /dev/null
+++ b/i/chuck/src/utils/any.tcc
@@ -0,0 +1,185 @@
+#ifndef any_tcc
+#define any_tcc
+// any.tcc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2003-2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "list_ostream_output.hh"
+
+#include <algorithm>
+
+/// Default constructor.
+inline
+any::any (void)
+ : holder_ (0)
+{
+}
+
+/// Constructor.
+template<typename T>
+any::any (const T &value)
+ : holder_ (new Holder<T> (value))
+{
+}
+
+/// Copy constructor.
+inline
+any::any (const any &other)
+ : holder_ (other.holder_ ? other.holder_->clone () : 0)
+{
+}
+
+/// Destructor.
+inline
+any::~any (void)
+{
+ delete holder_;
+}
+
+/// Swap content between two any objects.
+inline
+any &
+any::swap (any &other)
+{
+ std::swap (holder_, other.holder_);
+ return *this;
+}
+
+/// Copy another any object.
+inline
+any &
+any::operator= (const any &other)
+{
+ any (other).swap (*this);
+ return *this;
+}
+
+/// Copy another object into this any.
+template<typename T>
+any &
+any::operator= (const T &value)
+{
+ any (value).swap (*this);
+ return *this;
+}
+
+/// Test if the any object is empty.
+inline
+bool
+any::empty (void) const
+{
+ return !holder_;
+}
+
+/// Return the std::type_info of the contained object.
+inline
+const std::type_info &
+any::type (void) const
+{
+ return holder_ ? holder_->type () : typeid (void);
+}
+
+/// Destructor.
+inline
+any::AbstractHolder::~AbstractHolder (void)
+{
+}
+
+template<typename T>
+any::Holder<T>::Holder (const T &value)
+ : value_ (value)
+{
+}
+
+template<typename T>
+const std::type_info &
+any::Holder<T>::type (void) const
+{
+ return typeid (T);
+}
+
+template<typename T>
+any::AbstractHolder *
+any::Holder<T>::clone (void) const
+{
+ return new Holder (value_);
+}
+
+template<typename T>
+std::ostream &
+any::Holder<T>::print (std::ostream &os) const
+{
+ return os << value_;
+}
+
+/// Return a pointer to the contained object or 0 on faillure.
+template<typename T>
+T *
+any_cast (any *rhs)
+{
+ return rhs && rhs->type () == typeid (T)
+ ? &static_cast<any::Holder<T> *> (rhs->holder_)->value_
+ : 0;
+}
+
+/// Return a const pointer to the contained object or 0 on faillure.
+template<typename T>
+const T *
+any_cast (const any *rhs)
+{
+ return any_cast<T> (const_cast<any *> (rhs));
+}
+
+/// Return a const reference to the contained object or throw a bad_any_cast
+/// on faillure.
+template<typename T>
+const T &
+any_cast (const any &rhs)
+{
+ const T *value = any_cast<T> (&rhs);
+ if (!value)
+ throw bad_any_cast (typeid (T), rhs.type ());
+ return *value;
+}
+
+/// Constructor.
+inline
+bad_any_cast::bad_any_cast (const std::type_info &to,
+ const std::type_info &from)
+{
+ what_ = "illegal conversion from \'";
+ what_ += from.name ();
+ what_ += "\' to \'";
+ what_ += to.name ();
+ what_ += "\'";
+}
+
+/// Print the contained object.
+inline
+std::ostream &
+operator<< (std::ostream &os, const any &rhs)
+{
+ return rhs.holder_->print (os);
+}
+
+#endif // any_tcc
diff --git a/i/chuck/src/utils/bind.hh b/i/chuck/src/utils/bind.hh
new file mode 100644
index 0000000..a5630fe
--- /dev/null
+++ b/i/chuck/src/utils/bind.hh
@@ -0,0 +1,91 @@
+#ifndef bind_hh
+#define bind_hh
+// bind.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+
+/// Class used to bind a function taking an argument to a functor taking no
+/// argument. This is not supposed to be used directly, but using the bind
+/// template function.
+template<typename R, typename F, typename A>
+class ArgBinder
+{
+ /// Original function.
+ F func_;
+ /// Stored argument reference.
+ const A &arg_;
+ public:
+ /// Return value.
+ typedef R result_type;
+ public:
+ ArgBinder (F func, const A &arg)
+ : func_ (func), arg_ (arg)
+ { }
+ result_type operator () (void)
+ {
+ return func_ (arg_);
+ }
+};
+
+/// Bind a function taking an argument to a functor taking no argument.
+/// Return value must be specified, other template arguments can be implied.
+template<typename R, typename F, typename A>
+ArgBinder<R, F, A>
+bind (F func, const A &arg)
+{
+ return ArgBinder<R, F, A> (func, arg);
+}
+
+/// Class used to bind a member function to a functor taking no argument.
+/// This is not supposed to be used directly, but using the bind template
+/// function.
+template<typename R, typename C>
+class ObjBinder
+{
+ /// Original member function.
+ R (C::*func_) (void);
+ /// Object pointer stored.
+ C *obj_;
+ public:
+ /// Return value.
+ typedef R result_type;
+ public:
+ ObjBinder (R (C::*func) (void), C *obj)
+ : func_ (func), obj_ (obj)
+ { }
+ result_type operator () (void)
+ {
+ (obj_->*func_) ();
+ }
+};
+
+/// Bind a member function to a functor taking no argument. All template
+/// parameters must be specified.
+template<typename R, typename C>
+ObjBinder<R, C>
+bind (R (C::*func) (void), C *obj)
+{
+ return ObjBinder<R, C> (func, obj);
+}
+
+#endif // bind_hh
diff --git a/i/chuck/src/utils/callback.hh b/i/chuck/src/utils/callback.hh
new file mode 100644
index 0000000..ab1311c
--- /dev/null
+++ b/i/chuck/src/utils/callback.hh
@@ -0,0 +1,96 @@
+#ifndef callback_hh
+#define callback_hh
+// callback.hh
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2003-2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <stdexcept>
+
+/// Class to store a callback. This callback can be of any type (function or
+/// fonctor).
+template<typename R>
+class Callback
+{
+ class AbstractHolder;
+ AbstractHolder *holder_;
+ public:
+ /// Return value.
+ typedef R result_type;
+ public:
+ /// Default constructor. Make an empty callback.
+ Callback (void);
+ /// Constructor.
+ template<typename T>
+ Callback (T callback);
+ /// Copy constructor.
+ Callback (const Callback &other);
+ /// Destructor.
+ ~Callback (void);
+ /// Assignement operator.
+ Callback &operator= (const Callback &rhs);
+ /// Call the contained callback.
+ R operator () (void);
+ /// Swap the callback content with another callback.
+ void swap (Callback &rhs);
+ /// Change the contained callback.
+ template<typename T>
+ Callback &operator= (T rhs);
+ /// Test if empty.
+ bool empty (void) const;
+ /// Test if not empty.
+ operator bool (void) const;
+ private:
+ /// Abstract container.
+ class AbstractHolder
+ {
+ public:
+ virtual ~AbstractHolder (void);
+ virtual R operator () (void) = 0;
+ virtual AbstractHolder *clone (void) = 0;
+ };
+ /// Templated container.
+ template<typename T>
+ class Holder : public AbstractHolder
+ {
+ private:
+ T callback_;
+ public:
+ Holder (T callback);
+ virtual R operator () (void);
+ virtual AbstractHolder *clone (void);
+ };
+};
+
+/// Exception thrown on call of an empty callback.
+class bad_callback : public std::runtime_error
+{
+ public:
+ bad_callback (void) : std::runtime_error ("bad_callback: empty callback call")
+ {
+ }
+};
+
+#include "callback.tcc"
+
+#endif // callback_hh
diff --git a/i/chuck/src/utils/callback.tcc b/i/chuck/src/utils/callback.tcc
new file mode 100644
index 0000000..4e8bdd4
--- /dev/null
+++ b/i/chuck/src/utils/callback.tcc
@@ -0,0 +1,140 @@
+#ifndef callback_tcc
+#define callback_tcc
+// callback.tcc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2003-2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <algorithm>
+
+/// Default constructor. Make an empty callback.
+template<typename R>
+Callback<R>::Callback (void)
+ : holder_ (0)
+{
+}
+
+/// Constructor.
+template<typename R>
+template<typename T>
+Callback<R>::Callback (T callback)
+ : holder_ (new Holder<T> (callback))
+{
+}
+
+/// Copy constructor.
+template<typename R>
+Callback<R>::Callback (const Callback<R> &other)
+ : holder_ (other.holder_ ? other.holder_->clone () : 0)
+{
+}
+
+/// Destructor.
+template<typename R>
+Callback<R>::~Callback (void)
+{
+ delete holder_;
+}
+
+/// Assignement operator.
+template<typename R>
+Callback<R> &
+Callback<R>::operator= (const Callback<R> &rhs)
+{
+ Callback<R> (rhs).swap (*this);
+ return *this;
+}
+
+/// Call the contained callback.
+template<typename R>
+R
+Callback<R>::operator () (void)
+{
+ if (!holder_)
+ throw bad_callback ();
+ else
+ return (*holder_) ();
+}
+
+/// Swap the callback content with another callback.
+template<typename R>
+void
+Callback<R>::swap (Callback<R> &rhs)
+{
+ std::swap (holder_, rhs.holder_);
+}
+
+/// Change the contained callback.
+template<typename R>
+template<typename T>
+Callback<R> &
+Callback<R>::operator= (T rhs)
+{
+ Callback<R> (rhs).swap (*this);
+ return *this;
+}
+
+/// Test if empty.
+template<typename R>
+bool
+Callback<R>::empty (void) const
+{
+ return !holder_;
+}
+
+/// Test if not empty.
+template<typename R>
+Callback<R>::operator bool (void) const
+{
+ return !empty ();
+}
+
+template<typename R>
+Callback<R>::AbstractHolder::~AbstractHolder (void)
+{
+}
+
+template<typename R>
+template<typename T>
+Callback<R>::Holder<T>::Holder (T callback)
+ : callback_ (callback)
+{
+}
+
+template<typename R>
+template<typename T>
+R
+Callback<R>::Holder<T>::operator () (void)
+{
+ return callback_ ();
+}
+
+template<typename R>
+template<typename T>
+typename Callback<R>::AbstractHolder *
+Callback<R>::Holder<T>::clone (void)
+{
+ return new Holder<T> (callback_);
+}
+
+#endif // callback_tcc
diff --git a/i/chuck/src/utils/errno_exception.hh b/i/chuck/src/utils/errno_exception.hh
new file mode 100644
index 0000000..58a636e
--- /dev/null
+++ b/i/chuck/src/utils/errno_exception.hh
@@ -0,0 +1,48 @@
+#ifndef errno_exception_hh
+#define errno_exception_hh
+// errno_exception.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <string>
+#include <exception>
+#include <cstring>
+#include <errno.h>
+
+/// Exception lancé lorsqu'une erreur est retournée par la libc.
+class errno_exception : public std::exception
+{
+ int errno_;
+ std::string what_;
+ public:
+ errno_exception (const std::string &desc, int errno__)
+ : errno_ (errno__), what_ (desc + ": " + strerror (errno__)) { }
+ errno_exception (int errno__)
+ : errno_ (errno__), what_ (strerror (errno__)) { }
+ ~errno_exception (void) throw () { }
+ virtual const char* what () const throw () { return what_.c_str (); }
+ int getErrno (void) const { return errno_; }
+};
+
+#endif // errno_exception_hh
diff --git a/i/chuck/src/utils/fd_set.cc b/i/chuck/src/utils/fd_set.cc
new file mode 100644
index 0000000..998f3f5
--- /dev/null
+++ b/i/chuck/src/utils/fd_set.cc
@@ -0,0 +1,53 @@
+// fd_set.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "fd_set.hh"
+#include "utils/errno_exception.hh"
+
+/// Wait for an read event or timeout in milliseconds, return true on read
+/// event.
+bool
+FdSet::wait (int timeout/*-1*/)
+{
+ int r;
+ if (timeout == -1)
+ {
+ // Without timeout.
+ r = select (FD_SETSIZE, get (), 0, 0, 0);
+ }
+ else
+ {
+ // With timeout.
+ struct timeval tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ r = select (FD_SETSIZE, get (), 0, 0, &tv);
+ }
+ if (r == -1)
+ // Error.
+ throw errno_exception (errno);
+ else
+ return r != 0;
+}
+
diff --git a/i/chuck/src/utils/fd_set.hh b/i/chuck/src/utils/fd_set.hh
new file mode 100644
index 0000000..3d6d44c
--- /dev/null
+++ b/i/chuck/src/utils/fd_set.hh
@@ -0,0 +1,54 @@
+#ifndef fd_set_hh
+#define fd_set_hh
+// fd_set.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+
+#include <sys/types.h>
+
+/// Wrapper over libc fd_set.
+class FdSet
+{
+ fd_set set_;
+ public:
+ /// Default constructor.
+ FdSet (void)
+ { FD_ZERO (&set_); }
+ /// Set a fd.
+ void set (int fd)
+ { FD_SET (fd, &set_); }
+ /// Clear a fd.
+ void clear (int fd)
+ { FD_CLR (fd, &set_); }
+ /// Test if a fd is set.
+ bool isSet (int fd) const
+ { return FD_ISSET (fd, &set_); }
+ /// Get pointer to internal fd_set.
+ fd_set *get (void)
+ { return &set_; }
+ /// Wait for an read event or timeout in milliseconds, return true on read
+ /// event.
+ bool wait (int timeout = -1);
+};
+
+#endif // fd_set_hh
diff --git a/i/chuck/src/utils/hexa.cc b/i/chuck/src/utils/hexa.cc
new file mode 100644
index 0000000..102458e
--- /dev/null
+++ b/i/chuck/src/utils/hexa.cc
@@ -0,0 +1,113 @@
+// hexa.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "hexa.hh"
+
+// Table de conversion en hexa.
+static const char *digit2hexTbl_ = "0123456789abcdef";
+
+// Table de conversion depuis l'hexa.
+#define hI hexInvalid
+static const int hex2digitTbl_[] =
+{
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 0-15 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 16-31 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 32-47 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,hI,hI,hI,hI,hI,hI, /* 48-63 */
+ hI,10,11,12,13,14,15,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 64-79 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 80-95 */
+ hI,10,11,12,13,14,15,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 96-111 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 112-127 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 128-143 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 144-159 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 160-175 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 176-191 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 192-207 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 208-223 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 224-239 */
+ hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI,hI, /* 240-255 */
+};
+
+/// Converti un caractère hexa (0-9a-f) en chiffre (0-15).
+int
+hex2digit (char c)
+{
+ return hex2digitTbl_[static_cast<int> (c)];
+}
+
+/// Converti un chiffre (0-15) en hexa (0-9a-f).
+char
+digit2hex (int d)
+{
+ return digit2hexTbl_[d];
+}
+
+/// Décode un mot non-signé (1 octets).
+unsigned int
+hexUnsignedChar2int (const char *s)
+{
+ int h1 = hex2digit (s[0]);
+ int h0 = hex2digit (s[1]);
+ if (h1 == hexInvalid || h0 == hexInvalid)
+ return hexInvalid;
+ return (unsigned char) (h1 << 4 | h0);
+}
+
+/// Décode un mot signé (1 octets).
+int
+hexSignedChar2int (const char *s)
+{
+ int h1 = hex2digit (s[0]);
+ int h0 = hex2digit (s[1]);
+ if (h1 == hexInvalid || h0 == hexInvalid)
+ return hexInvalid;
+ return (signed char) (h1 << 4 | h0);
+}
+
+/// Décode un mot non-signé (2 octets).
+int
+hexUnsignedShort2int (const char *s)
+{
+ int h3 = hex2digit (s[0]);
+ int h2 = hex2digit (s[1]);
+ int h1 = hex2digit (s[2]);
+ int h0 = hex2digit (s[3]);
+ if (h3 == hexInvalid || h2 == hexInvalid || h1 == hexInvalid || h0 == hexInvalid)
+ return hexInvalid;
+ return (unsigned short) (h3 << 12 | h2 << 8 | h1 << 4 | h0);
+}
+
+/// Décode un mot signé (2 octets).
+int
+hexSignedShort2int (const char *s)
+{
+ int h3 = hex2digit (s[0]);
+ int h2 = hex2digit (s[1]);
+ int h1 = hex2digit (s[2]);
+ int h0 = hex2digit (s[3]);
+ if (h3 == hexInvalid || h2 == hexInvalid || h1 == hexInvalid || h0 == hexInvalid)
+ return hexInvalid;
+ return (short) (h3 << 12 | h2 << 8 | h1 << 4 | h0);
+}
+
diff --git a/i/chuck/src/utils/hexa.hh b/i/chuck/src/utils/hexa.hh
new file mode 100644
index 0000000..f7d3399
--- /dev/null
+++ b/i/chuck/src/utils/hexa.hh
@@ -0,0 +1,49 @@
+#ifndef hexa_hh
+#define hexa_hh
+// hexa.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+/// Constante retournée pour une valeur invalide.
+const int hexInvalid = 1 << 24;
+
+/// Converti un caractère hexa (0-9a-f) en chiffre (0-15).
+int hex2digit (char c);
+
+/// Converti un chiffre (0-15) en hexa (0-9a-f).
+char digit2hex (int d);
+
+/// Décode un mot non-signé (1 octets).
+unsigned int hexUnsignedChar2int (const char *s);
+
+/// Décode un mot signé (1 octets).
+int hexSignedChar2int (const char *s);
+
+/// Décode un mot non-signé (2 octets).
+int hexUnsignedShort2int (const char *s);
+
+/// Décode un mot signé (2 octets).
+int hexSignedShort2int (const char *s);
+
+#endif // hexa_hh
diff --git a/i/chuck/src/utils/list_ostream_output.hh b/i/chuck/src/utils/list_ostream_output.hh
new file mode 100644
index 0000000..3863a39
--- /dev/null
+++ b/i/chuck/src/utils/list_ostream_output.hh
@@ -0,0 +1,62 @@
+#ifndef list_ostream_output_hh
+#define list_ostream_output_hh
+// list_ostream_output.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <iostream>
+#include <list>
+#include <vector>
+#include <algorithm>
+#include <iterator>
+
+/// Output any list.
+template<typename T>
+std::ostream &
+output_list (std::ostream &os, const T &list)
+{
+ os << "( ";
+ std::copy (list.begin (), list.end (),
+ std::ostream_iterator<typename T::value_type> (os, " "));
+ os << ')';
+ return os;
+}
+
+/// Output a list.
+template<typename T>
+std::ostream &
+operator<< (std::ostream &os, const std::list<T> &list)
+{
+ return output_list (os, list);
+}
+
+/// Output a vector.
+template<typename T>
+std::ostream &
+operator<< (std::ostream &os, const std::vector<T> &list)
+{
+ return output_list (os, list);
+}
+
+#endif // list_ostream_output_hh
diff --git a/i/chuck/src/utils/mathutil.hh b/i/chuck/src/utils/mathutil.hh
new file mode 100644
index 0000000..d58cec3
--- /dev/null
+++ b/i/chuck/src/utils/mathutil.hh
@@ -0,0 +1,57 @@
+#ifndef mathutil_hh
+#define mathutil_hh
+// mathutil.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include <cmath>
+
+/// Normalise l'angle entre -pi et +pi.
+double
+angleNorm (double a);
+
+/// Converti en coordonnées polaires.
+void
+toPolar (double x, double y, double &r, double &a);
+
+/// Normalise l'angle en [-pi..+pi).
+inline double
+angleNorm (double a)
+{
+ while (a >= M_PI)
+ a -= 2.0 * M_PI;
+ while (a < -M_PI)
+ a += 2.0 * M_PI;
+ return a;
+}
+
+/// Converti en coordonnées polaires.
+inline void
+toPolar (double x, double y, double &r, double &a)
+{
+ // Rayon.
+ r = sqrt (x * x + y * y);
+ a = y > 0 ? acos (x / r) : -acos (x / r);
+}
+
+#endif // mathutil_hh
diff --git a/i/chuck/src/utils/meta/Makefile.defs b/i/chuck/src/utils/meta/Makefile.defs
new file mode 100644
index 0000000..8fa3a10
--- /dev/null
+++ b/i/chuck/src/utils/meta/Makefile.defs
@@ -0,0 +1,3 @@
+PROGRAMS += test_meta
+
+test_meta_OBJECTS = test_meta.o
diff --git a/i/chuck/src/utils/meta/is_equal.hh b/i/chuck/src/utils/meta/is_equal.hh
new file mode 100644
index 0000000..a67e8a6
--- /dev/null
+++ b/i/chuck/src/utils/meta/is_equal.hh
@@ -0,0 +1,44 @@
+#ifndef is_equal_hh
+#define is_equal_hh
+// is_equal.hh - test if two types equals.
+// {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+namespace meta {
+
+template<typename T1, typename T2>
+struct isEqual
+{
+ static const bool value = false;
+};
+
+template<typename T>
+struct isEqual<T, T>
+{
+ static const bool value = true;
+};
+
+} // namespace meta
+
+#endif // is_equal_hh
diff --git a/i/chuck/src/utils/meta/is_string.hh b/i/chuck/src/utils/meta/is_string.hh
new file mode 100644
index 0000000..99782d2
--- /dev/null
+++ b/i/chuck/src/utils/meta/is_string.hh
@@ -0,0 +1,45 @@
+#ifndef is_string_hh
+#define is_string_hh
+// is_string.hh
+// {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+
+#include <string>
+
+namespace meta {
+
+template<typename T>
+struct isString
+{
+ static const bool value = false;
+};
+
+template<>
+struct isString<std::string>
+{
+ static const bool value = true;
+};
+
+} // namespace meta
+
+#endif // is_string_hh
diff --git a/i/chuck/src/utils/meta/remove_reference.hh b/i/chuck/src/utils/meta/remove_reference.hh
new file mode 100644
index 0000000..f12422d
--- /dev/null
+++ b/i/chuck/src/utils/meta/remove_reference.hh
@@ -0,0 +1,44 @@
+#ifndef remove_reference_hh
+#define remove_reference_hh
+// remove_reference.hh - Remove reference from a type.
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+namespace meta {
+
+template<typename T>
+struct removeReference
+{
+ typedef T type;
+};
+
+template<typename T>
+struct removeReference<T &>
+{
+ typedef T type;
+};
+
+} // namespace meta
+
+#endif // remove_reference_hh
diff --git a/i/chuck/src/utils/meta/test_meta.cc b/i/chuck/src/utils/meta/test_meta.cc
new file mode 100644
index 0000000..7c973d2
--- /dev/null
+++ b/i/chuck/src/utils/meta/test_meta.cc
@@ -0,0 +1,57 @@
+// test_meta.cc
+// marvin - programme du robot 2006. {{{
+//
+// Copyright (C) 2003-2006 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2006.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "is_string.hh"
+#include "is_equal.hh"
+#include "remove_reference.hh"
+
+#include <iostream>
+
+int
+main (void)
+{
+ // Test isString.
+ std::cout << "isString" << std::endl;
+ std::cout << " std::string " << meta::isString<std::string>::value << std::endl;
+ std::cout << " int " << meta::isString<int>::value << std::endl;
+ std::cout << " char* " << meta::isString<char *>::value << std::endl;
+ // Test isEqual.
+ std::cout << "isEqual" << std::endl;
+ std::cout << " int int " << meta::isEqual<int, int>::value << std::endl;
+ std::cout << " int& int " << meta::isEqual<int&, int>::value << std::endl;
+ std::cout << " int& int& " << meta::isEqual<int&, int&>::value << std::endl;
+ std::cout << " int double " << meta::isEqual<int, double>::value << std::endl;
+ // Test removeReference.
+ std::cout << "removeReference" << std::endl;
+ std::cout << " int "
+ << meta::isEqual<int, meta::removeReference<int>::type>::value
+ << std::endl;
+ std::cout << " int& "
+ << meta::isEqual<int, meta::removeReference<int &>::type>::value
+ << std::endl;
+ std::cout << " const int& "
+ << meta::isEqual<const int, meta::removeReference<const int &>::type>::value
+ << std::endl;
+ return 0;
+}
diff --git a/i/chuck/src/utils/non_copyable.hh b/i/chuck/src/utils/non_copyable.hh
new file mode 100644
index 0000000..e788365
--- /dev/null
+++ b/i/chuck/src/utils/non_copyable.hh
@@ -0,0 +1,41 @@
+#ifndef non_copyable_hh
+#define non_copyable_hh
+// non_copyable.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+/// Toute classe qui hérite de NonCopyable ne peut pas être copiée. Cela est
+/// assuré par le fait que l'operator= et le constructeur de recopie sont
+/// privé.
+/// Idée originale : Boost.org.
+class NonCopyable
+{
+ public:
+ NonCopyable (void) { }
+ private:
+ NonCopyable (const NonCopyable &);
+ const NonCopyable &operator= (const NonCopyable &);
+};
+
+#endif // non_copyable_hh
diff --git a/i/chuck/src/utils/signalhandler.hh b/i/chuck/src/utils/signalhandler.hh
new file mode 100644
index 0000000..43e0f89
--- /dev/null
+++ b/i/chuck/src/utils/signalhandler.hh
@@ -0,0 +1,52 @@
+#ifndef signalhandler_hh
+#define signalhandler_hh
+// signalhandler.hh
+// // marvin - programme du robot 2006. {{{
+// //
+// // Copyright (C) 2003-2006 Sebastien beaufour
+// //
+// // Robot APB Team/Efrei 2006.
+// // Web: http://assos.efrei.fr/robot/
+// // Email: robot AT efrei DOT fr
+// //
+// // This program is free software; you can redistribute it and/or modify
+// // it under the terms of the GNU General Public License as published by
+// // the Free Software Foundation; either version 2 of the License, or
+// // (at your option) any later version.
+// //
+// // This program is distributed in the hope that it will be useful,
+// // but WITHOUT ANY WARRANTY; without even the implied warranty of
+// // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// // GNU General Public License for more details.
+// //
+// // You should have received a copy of the GNU General Public License
+// // along with this program; if not, write to the Free Software
+// // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// //
+// // }}}
+//
+//
+
+#include <stdio.h>
+#include <signal.h>
+#include <iostream>
+#include "callback.hh"
+
+template<int sig>
+class SignalHandler
+{
+ private:
+ struct sigaction action;
+ struct sigaction old;
+ static Callback<void> reset;
+ static void DefaultReset();
+ public:
+ static void trapsigint(int a);
+ void bind(Callback<void> r);
+ SignalHandler();
+ ~SignalHandler();
+};
+#include "signalhandler.tcc"
+
+#endif // end of signalhandler_hh
+
diff --git a/i/chuck/src/utils/signalhandler.tcc b/i/chuck/src/utils/signalhandler.tcc
new file mode 100644
index 0000000..04a1660
--- /dev/null
+++ b/i/chuck/src/utils/signalhandler.tcc
@@ -0,0 +1,66 @@
+// signalhandler.cc
+// // // marvin - programme du robot 2006. {{{
+// // //
+// // // Copyright (C) 2003-2006 Sebastien Beaufour
+// // //
+// // // Robot APB Team/Efrei 2006.
+// // // Web: http://assos.efrei.fr/robot/
+// // // Email: robot AT efrei DOT fr
+// // //
+// // // This program is free software; you can redistribute it and/or modify
+// // // it under the terms of the GNU General Public License as published by
+// // // the Free Software Foundation; either version 2 of the License, or
+// // // (at your option) any later version.
+// // //
+// // // This program is distributed in the hope that it will be useful,
+// // // but WITHOUT ANY WARRANTY; without even the implied warranty of
+// // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// // // GNU General Public License for more details.
+// // //
+// // // You should have received a copy of the GNU General Public License
+// // // along with this program; if not, write to the Free Software
+// // // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// // //
+// // // }}}
+// //
+// //
+//
+
+#include "signalhandler.hh"
+
+/// reset NEED a default reset, so here is a default reset with nothing inside
+template<int sig> void SignalHandler<sig>::DefaultReset (void)
+{
+ // Nothing
+}
+
+// Now we can set the default value to reset
+template<int sig> Callback<void> SignalHandler<sig>::reset=SignalHandler::DefaultReset;
+
+///Static member which will be use by sigaction
+template<int sig> void SignalHandler<sig>::trapsigint(int a)
+{
+ std::cout << "Trap du crtl+c "<< std::endl;
+ reset();
+}
+
+///Function to bind to the function to be called when signal il caught
+template<int sig> void SignalHandler<sig>::bind(Callback<void> r)
+{
+ reset=r;
+ action.sa_handler = trapsigint;
+ action.sa_flags = SA_ONESHOT;
+ sigaction(sig,&action,NULL);
+}
+
+/// Constructor, nothing to do
+template<int sig> SignalHandler<sig>::SignalHandler()
+{
+ //nada
+}
+
+///Destructor, put the old sig handler back
+template<int sig> SignalHandler<sig>::~SignalHandler()
+{
+ sigaction(sig,&old,NULL);
+}
diff --git a/i/chuck/src/utils/test_any.cc b/i/chuck/src/utils/test_any.cc
new file mode 100644
index 0000000..85d2319
--- /dev/null
+++ b/i/chuck/src/utils/test_any.cc
@@ -0,0 +1,50 @@
+// test_any.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "any.hh"
+
+#include <exception>
+#include <iostream>
+#include <string>
+
+int
+main (int argc, char **argv)
+{
+ any a (45), b (std::string ("toto")), c (5.4), d (std::string ("5"));
+ try
+ {
+ // Direct call to output operator.
+ std::cout << a << ' ' << b << ' ' << c << ' ' << d << std::endl;
+ // Here, it tries to extract the contained data.
+ std::cout << any_cast<int> (a) << std::endl;
+ std::cout << any_cast<std::string> (b) << std::endl;
+ std::cout << any_cast<double> (c) << std::endl;
+ std::cout << any_cast<int> (d) << std::endl;
+ }
+ catch (const std::exception &e)
+ {
+ std::cout << e.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/i/chuck/src/utils/test_bind.cc b/i/chuck/src/utils/test_bind.cc
new file mode 100644
index 0000000..b883cbe
--- /dev/null
+++ b/i/chuck/src/utils/test_bind.cc
@@ -0,0 +1,57 @@
+// test_bind.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "bind.hh"
+
+#include <iostream>
+
+void
+f (int i)
+{
+ std::cout << "f " << i << std::endl;
+}
+
+void
+g (const char *s)
+{
+ std::cout << "g " << s << std::endl;
+}
+
+class H
+{
+ public:
+ void f (void)
+ {
+ std::cout << "h" << std::endl;
+ }
+};
+
+int
+main (void)
+{
+ // Create the callback and execute it.
+ bind<void> (&f, 42) ();
+ bind<void> (&g, "hello world !") ();
+ H h;
+ bind<void, H> (&H::f, &h) ();
+}
diff --git a/i/chuck/src/utils/test_callback.cc b/i/chuck/src/utils/test_callback.cc
new file mode 100644
index 0000000..2a5b6f0
--- /dev/null
+++ b/i/chuck/src/utils/test_callback.cc
@@ -0,0 +1,84 @@
+// test_callback.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2004 Nicolas Schodet
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Contact :
+// Web: http://perso.efrei.fr/~schodet/
+// Email: <contact@ni.fr.eu.org>
+// }}}
+#include "callback.hh"
+
+#include <iostream>
+
+void
+f (void)
+{
+ std::cout << " f ()" << std::endl;
+}
+
+int
+i (void)
+{
+ static int v = 42;
+ std::cout << " i () = " << v << std::endl;
+ return v++;
+}
+
+struct G
+{
+ void operator () (void)
+ {
+ std::cout << " g ()" << std::endl;
+ }
+};
+
+int
+main (void)
+{
+ G g;
+ Callback<void> cf (f);
+ Callback<void> cg (g);
+ Callback<void> ch;
+ Callback<int> ci (i);
+ try
+ {
+ std::cout << "cf" << std::endl;
+ cf ();
+ std::cout << "cg" << std::endl;
+ cg ();
+ cf = cg;
+ cg = f;
+ std::cout << "cf" << std::endl;
+ cf ();
+ std::cout << "cg" << std::endl;
+ cg ();
+ std::cout << "cf " << (cf ? "not " : "") << "empty" << std::endl;
+ std::cout << "ch " << (ch ? "not " : "") << "empty" << std::endl;
+ std::cout << "ci" << std::endl;
+ int r = ci ();
+ std::cout << "ci = " << r << std::endl;
+ std::cout << "ch" << std::endl;
+ ch ();
+ }
+ catch (const std::exception &e)
+ {
+ std::cout << e.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/i/chuck/src/utils/test_signalhandler.cc b/i/chuck/src/utils/test_signalhandler.cc
new file mode 100644
index 0000000..e25b1d2
--- /dev/null
+++ b/i/chuck/src/utils/test_signalhandler.cc
@@ -0,0 +1,15 @@
+#include <iostream>
+#include "signalhandler.hh"
+
+void res()
+{
+ std::cout << "RESET" << std::endl;
+}
+
+int main()
+{
+ SignalHandler<SIGINT> test;
+ test.bind(res);
+ while(1);
+ return 0;
+}