mirror of https://github.com/ArduPilot/ardupilot
310 lines
9.8 KiB
Plaintext
310 lines
9.8 KiB
Plaintext
@###############################################
|
|
@#
|
|
@# ROS message source code generation for C++
|
|
@#
|
|
@# EmPy template for generating <msg>.h files
|
|
@#
|
|
@###############################################
|
|
@# Start of Template
|
|
@#
|
|
@# Context:
|
|
@# - file_name_in (String) Source file
|
|
@# - spec (msggen.MsgSpec) Parsed specification of the .msg file
|
|
@# - md5sum (String) MD5Sum of the .msg specification
|
|
@###############################################
|
|
/* Software License Agreement (BSD License)
|
|
*
|
|
* Copyright (c) 2011, Willow Garage, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
* * Neither the name of Willow Garage, Inc. nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* Auto-generated by genmsg_cpp from file @file_name_in
|
|
*
|
|
*/
|
|
|
|
@{
|
|
import genmsg.msgs
|
|
import gencpp
|
|
|
|
cpp_namespace = '::%s::'%(spec.package) # TODO handle nested namespace
|
|
cpp_class = '%s_'%spec.short_name
|
|
cpp_full_name = '%s%s'%(cpp_namespace,cpp_class)
|
|
cpp_full_name_with_alloc = '%s<ContainerAllocator>'%(cpp_full_name)
|
|
cpp_msg_definition = gencpp.escape_message_definition(msg_definition)
|
|
}@
|
|
|
|
#ifndef @(spec.package.upper())_MESSAGE_@(spec.short_name.upper())_H
|
|
#define @(spec.package.upper())_MESSAGE_@(spec.short_name.upper())_H
|
|
|
|
@##############################
|
|
@# Generic Includes
|
|
@##############################
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
#include <ros/types.h>
|
|
#include <ros/serialization.h>
|
|
#include <ros/builtin_message_traits.h>
|
|
#include <ros/message_operations.h>
|
|
|
|
@##############################
|
|
@# Includes for dependencies
|
|
@##############################
|
|
@{
|
|
for field in spec.parsed_fields():
|
|
if (not field.is_builtin):
|
|
if (field.is_header):
|
|
print('#include <std_msgs/Header.h>')
|
|
else:
|
|
(package, name) = genmsg.names.package_resource_name(field.base_type)
|
|
package = package or spec.package # convert '' to package
|
|
print('#include <%s/%s.h>'%(package, name))
|
|
}@
|
|
|
|
namespace @(spec.package)
|
|
{
|
|
template <class ContainerAllocator>
|
|
struct @(spec.short_name)_
|
|
{
|
|
typedef @(spec.short_name)_<ContainerAllocator> Type;
|
|
|
|
@# constructors (with and without allocator)
|
|
@[for (alloc_type,alloc_name) in [['',''],['const ContainerAllocator& ','_alloc']]]@
|
|
@(spec.short_name)_(@(alloc_type+alloc_name))
|
|
@# Write initializer list
|
|
@('\n '.join(gencpp.generate_initializer_list(spec, alloc_name != '' )))@
|
|
{
|
|
@# Fixed length arrays
|
|
@('\n '.join(gencpp.generate_fixed_length_assigns(spec, alloc_name != '', '%s::'%(spec.package))))@
|
|
}
|
|
@[end for]
|
|
|
|
@[for field in spec.parsed_fields()]
|
|
@{cpp_type = gencpp.msg_type_to_cpp(field.type)}@
|
|
typedef @(cpp_type) _@(field.name)_type;
|
|
_@(field.name)_type @(field.name);
|
|
@[end for]
|
|
|
|
@# Constants
|
|
@[for constant in spec.constants]@
|
|
@[if (constant.type in ['byte', 'int8', 'int16', 'int32', 'int64', 'char'])]@
|
|
enum { @(constant.name) = @(int(constant.val)) };
|
|
@[elif (constant.type in ['uint8', 'uint16', 'uint32', 'uint64'])]@
|
|
enum { @(constant.name) = @(int(constant.val))u };
|
|
@[else]@
|
|
static const @(gencpp.msg_type_to_cpp(constant.type)) @(constant.name);
|
|
@[end if]@
|
|
@[end for]
|
|
|
|
@# Shared pointer typedefs
|
|
typedef boost::shared_ptr< @(cpp_full_name)<ContainerAllocator> > Ptr;
|
|
typedef boost::shared_ptr< @(cpp_full_name)<ContainerAllocator> const> ConstPtr;
|
|
|
|
}; // struct @(cpp_class)
|
|
|
|
@# Typedef of template instance using std::allocator
|
|
typedef @(cpp_full_name)<std::allocator<void> > @(spec.short_name);
|
|
|
|
@# Shared pointer typedefs
|
|
typedef boost::shared_ptr< @(cpp_namespace+spec.short_name) > @(spec.short_name)Ptr;
|
|
typedef boost::shared_ptr< @(cpp_namespace+spec.short_name) const> @(spec.short_name)ConstPtr;
|
|
|
|
// constants requiring out of line definition
|
|
@[for c in spec.constants]
|
|
@[if c.type not in ['byte', 'int8', 'int16', 'int32', 'int64', 'char', 'uint8', 'uint16', 'uint32', 'uint64']]
|
|
template<typename ContainerAllocator> const @(gencpp.msg_type_to_cpp(c.type))
|
|
@(spec.short_name)_<ContainerAllocator>::@(c.name) =
|
|
@[if c.type == 'string']
|
|
"@(gencpp.escape_string(c.val))"
|
|
@[elif c.type == 'bool']
|
|
@(int(c.val))
|
|
@[else]
|
|
@c.val
|
|
@[end if]
|
|
;
|
|
@[end if]
|
|
@[end for]
|
|
|
|
|
|
@# Printer
|
|
template<typename ContainerAllocator>
|
|
std::ostream& operator<<(std::ostream& s, const @(cpp_full_name_with_alloc) & v)
|
|
{
|
|
ros::message_operations::Printer< @(cpp_full_name_with_alloc) >::stream(s, "", v);
|
|
return s;
|
|
}
|
|
|
|
@# End of namespace
|
|
} // namespace @(spec.package)
|
|
|
|
@# Message Traits
|
|
namespace ros
|
|
{
|
|
namespace message_traits
|
|
{
|
|
|
|
@{
|
|
bool_traits = dict(IsMessage=True,
|
|
IsFixedSize=gencpp.is_fixed_length(spec, msg_context, search_path),
|
|
HasHeader=spec.has_header(),
|
|
)
|
|
def booltotype(b):
|
|
return "TrueType" if b else "FalseType"
|
|
}
|
|
|
|
// BOOLTRAITS @bool_traits
|
|
// @search_path
|
|
|
|
@# TODO
|
|
// !!!!!!!!!!! @(dir(spec))
|
|
@#if spec.is_fixed_length():
|
|
@# traits = traits.append('IsFixedSize')
|
|
|
|
@#template <class ContainerAllocator>
|
|
@#struct IsFixedSize<@(cpp_full_name_with_alloc) >:: @(dir(spec)) ? "TrueType" ! "FalseType") { };
|
|
@#template <class ContainerAllocator>
|
|
@#struct IsFixedSize<@(cpp_full_name_with_alloc) const >:: @(dir(spec)) ? "TrueType" ! "FalseType") { };
|
|
|
|
@# Binary traits
|
|
|
|
@[for k, v in bool_traits.items()]@
|
|
|
|
template <class ContainerAllocator>
|
|
struct @(k)< @(cpp_full_name_with_alloc) >
|
|
: @(booltotype(v))
|
|
{ };
|
|
|
|
template <class ContainerAllocator>
|
|
struct @(k)< @(cpp_full_name_with_alloc) const>
|
|
: @(booltotype(v))
|
|
{ };
|
|
@[end for]@
|
|
|
|
@# String traits
|
|
@[for trait_class,trait_value in [['MD5Sum', md5sum], ['DataType', spec.full_name], ['Definition', cpp_msg_definition]]]@
|
|
|
|
template<class ContainerAllocator>
|
|
struct @(trait_class)< @(cpp_full_name_with_alloc) >
|
|
{
|
|
static const char* value()
|
|
{
|
|
return "@(trait_value)";
|
|
}
|
|
|
|
static const char* value(const @(cpp_full_name_with_alloc)&) { return value(); }
|
|
@{
|
|
if trait_class == 'MD5Sum':
|
|
iter_count = int(len(trait_value) / 16)
|
|
for i in range(0, iter_count):
|
|
start = i*16
|
|
print(' static const uint64_t static_value%s = 0x%sULL;'%((i+1), trait_value[start:start+16]))
|
|
}@
|
|
};
|
|
@[end for]@
|
|
|
|
@# End of traits
|
|
} // namespace message_traits
|
|
} // namespace ros
|
|
|
|
@# Serialization
|
|
namespace ros
|
|
{
|
|
namespace serialization
|
|
{
|
|
|
|
template<class ContainerAllocator> struct Serializer< @(cpp_full_name_with_alloc) >
|
|
{
|
|
@[if spec.parsed_fields()]@
|
|
template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m)
|
|
{
|
|
@[for field in spec.parsed_fields()]@
|
|
stream.next(m.@(field.name));
|
|
@[end for]@
|
|
}
|
|
@[else]@
|
|
template<typename Stream, typename T> inline static void allInOne(Stream&, T)
|
|
{}
|
|
@[end if]@
|
|
|
|
ROS_DECLARE_ALLINONE_SERIALIZER;
|
|
}; // struct @(cpp_class)
|
|
|
|
} // namespace serialization
|
|
} // namespace ros
|
|
|
|
@# Message Operations
|
|
namespace ros
|
|
{
|
|
namespace message_operations
|
|
{
|
|
|
|
@# Printer operation
|
|
template<class ContainerAllocator>
|
|
struct Printer< @(cpp_full_name_with_alloc) >
|
|
{
|
|
@[if spec.parsed_fields()]@
|
|
template<typename Stream> static void stream(Stream& s, const std::string& indent, const @(cpp_full_name_with_alloc)& v)
|
|
{
|
|
@# todo, change this stuff below into proper EmPy syntax
|
|
@{
|
|
for field in spec.parsed_fields():
|
|
cpp_type = gencpp.msg_type_to_cpp(field.base_type)
|
|
if (field.is_array):
|
|
print(' s << indent << "%s[]" << std::endl;'%(field.name))
|
|
print(' for (size_t i = 0; i < v.%s.size(); ++i)'%(field.name))
|
|
print(' {')
|
|
print(' s << indent << " %s[" << i << "]: ";'%(field.name))
|
|
indent_increment = ' '
|
|
if (not field.is_builtin):
|
|
print(' s << std::endl;')
|
|
print(' s << indent;')
|
|
indent_increment = ' ';
|
|
print(' Printer<%s>::stream(s, indent + "%s", v.%s[i]);'%(cpp_type, indent_increment, field.name))
|
|
print(' }')
|
|
else:
|
|
print(' s << indent << "%s: ";'%(field.name))
|
|
indent_increment = ' '
|
|
if (not field.is_builtin or field.is_array):
|
|
print(' s << std::endl;')
|
|
print(' Printer<%s>::stream(s, indent + "%s", v.%s);'%(cpp_type, indent_increment, field.name))
|
|
}@
|
|
}
|
|
@[else]@
|
|
template<typename Stream> static void stream(Stream&, const std::string&, const @(cpp_full_name_with_alloc)&)
|
|
{}
|
|
@[end if]@
|
|
};
|
|
|
|
} // namespace message_operations
|
|
} // namespace ros
|
|
|
|
#endif // @(spec.package.upper())_MESSAGE_@(spec.short_name.upper())_H
|