KaCanOpen
 All Classes Functions Variables Typedefs Enumerations Pages
entry_subscriber.cpp
1 /*
2  * Copyright (c) 2015-2016, Thomas Keh
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "entry_subscriber.h"
33 #include "utils.h"
34 #include "logger.h"
35 #include "ros/ros.h"
36 #include "sdo_error.h"
37 
38 #include <string>
39 
40 namespace kaco {
41 
42 EntrySubscriber::EntrySubscriber(Device& device, const std::string& entry_name, const WriteAccessMethod access_method)
43  : m_device(device), m_entry_name(entry_name), m_access_method(access_method)
44 {
45 
46  uint8_t node_id = device.get_node_id();
47  m_device_prefix = "device" + std::to_string(node_id) + "/";
48  // no spaces and '-' allowed in ros names
49  m_name = Utils::escape(entry_name);
50  m_type = device.get_entry_type(entry_name);
51 
52 }
53 
55 
56  std::string topic = m_device_prefix+"set_"+m_name;
57  DEBUG_LOG("Advertising "<<topic);
58  ros::NodeHandle nh;
59 
60  switch(m_type) {
61  case Type::uint8:
62  m_subscriber = nh.subscribe(topic, queue_size, &EntrySubscriber::receive_uint8, this);
63  break;
64  case Type::uint16:
65  m_subscriber = nh.subscribe(topic, queue_size, &EntrySubscriber::receive_uint16, this);
66  break;
67  case Type::uint32:
68  m_subscriber = nh.subscribe(topic, queue_size, &EntrySubscriber::receive_uint32, this);
69  break;
70  case Type::int8:
71  m_subscriber = nh.subscribe(topic, queue_size, &EntrySubscriber::receive_int8, this);
72  break;
73  case Type::int16:
74  m_subscriber = nh.subscribe(topic, queue_size, &EntrySubscriber::receive_int16, this);
75  break;
76  case Type::int32:
77  m_subscriber = nh.subscribe(topic, queue_size, &EntrySubscriber::receive_int32, this);
78  break;
79  case Type::boolean:
80  m_subscriber = nh.subscribe(topic, queue_size, &EntrySubscriber::receive_boolean, this);
81  break;
82  case Type::string:
83  m_subscriber = nh.subscribe(topic, queue_size, &EntrySubscriber::receive_string, this);
84  break;
85  default:
86  ERROR("[EntryPublisher::advertise] Invalid entry type.")
87  }
88 
89 }
90 
91 void EntrySubscriber::receive_uint8(const std_msgs::UInt8& msg) {
92  try {
93  DEBUG_LOG("Recieved msg: "<<msg.data);
94  m_device.set_entry(m_entry_name, msg.data, m_access_method); // auto cast to Value!
95  } catch (const sdo_error& error) {
96  // TODO: only catch timeouts?
97  ERROR("Exception in EntrySubscriber::receive_uint8(): "<<error.what());
98  }
99 }
100 
101 void EntrySubscriber::receive_uint16(const std_msgs::UInt16& msg) {
102  try {
103  DEBUG_LOG("Recieved msg: "<<msg.data);
104  m_device.set_entry(m_entry_name, msg.data, m_access_method); // auto cast to Value!
105  } catch (const sdo_error& error) {
106  // TODO: only catch timeouts?
107  ERROR("Exception in EntrySubscriber::receive_uint16(): "<<error.what());
108  }
109 }
110 
111 void EntrySubscriber::receive_uint32(const std_msgs::UInt32& msg) {
112  try {
113  DEBUG_LOG("Recieved msg: "<<msg.data);
114  m_device.set_entry(m_entry_name, msg.data, m_access_method); // auto cast to Value!
115  } catch (const sdo_error& error) {
116  // TODO: only catch timeouts?
117  ERROR("Exception in EntrySubscriber::receive_uint32(): "<<error.what());
118  }
119 }
120 
121 void EntrySubscriber::receive_int8(const std_msgs::Int8& msg) {
122  try {
123  DEBUG_LOG("Recieved msg: "<<msg.data);
124  m_device.set_entry(m_entry_name, msg.data, m_access_method); // auto cast to Value!
125  } catch (const sdo_error& error) {
126  // TODO: only catch timeouts?
127  ERROR("Exception in EntrySubscriber::receive_int8(): "<<error.what());
128  }
129 }
130 
131 void EntrySubscriber::receive_int16(const std_msgs::Int16& msg) {
132  try {
133  DEBUG_LOG("Recieved msg: "<<msg.data);
134  m_device.set_entry(m_entry_name, msg.data, m_access_method); // auto cast to Value!
135  } catch (const sdo_error& error) {
136  // TODO: only catch timeouts?
137  ERROR("Exception in EntrySubscriber::receive_int16(): "<<error.what());
138  }
139 }
140 
141 void EntrySubscriber::receive_int32(const std_msgs::Int32& msg) {
142  try {
143  DEBUG_LOG("Recieved msg: "<<msg.data);
144  m_device.set_entry(m_entry_name, msg.data, m_access_method); // auto cast to Value!
145  } catch (const sdo_error& error) {
146  // TODO: only catch timeouts?
147  ERROR("Exception in EntrySubscriber::receive_int32(): "<<error.what());
148  }
149 }
150 
151 void EntrySubscriber::receive_boolean(const std_msgs::Bool& msg) {
152  try {
153  DEBUG_LOG("Recieved msg: "<<msg.data);
154  m_device.set_entry(m_entry_name, msg.data, m_access_method); // auto cast to Value!
155  } catch (const sdo_error& error) {
156  // TODO: only catch timeouts?
157  ERROR("Exception in EntrySubscriber::receive_boolean(): "<<error.what());
158  }
159 }
160 
161 void EntrySubscriber::receive_string(const std_msgs::String& msg) {
162  try {
163  DEBUG_LOG("Recieved msg: "<<msg.data);
164  m_device.set_entry(m_entry_name, msg.data, m_access_method); // auto cast to Value!
165  } catch (const sdo_error& error) {
166  // TODO: only catch timeouts?
167  ERROR("Exception in EntrySubscriber::receive_string(): "<<error.what());
168  }
169 }
170 
171 } // end namespace kaco
EntrySubscriber(Device &device, const std::string &entry_name, const WriteAccessMethod access_method=WriteAccessMethod::use_default)
Constructor.
static std::string escape(const std::string &str)
Converts entry names to lower case and replaces all spaces and '-' by underscores.
Definition: utils.cpp:166
uint8_t get_node_id() const
Returns the node ID of the device.
Definition: device.cpp:74
void advertise() override
This class represents a CanOpen slave device in the network.
Definition: device.h:83
void set_entry(const std::string &entry_name, const Value &value, const WriteAccessMethod access_method=WriteAccessMethod::use_default)
Sets the value of a dictionary entry by name internally. If the entry is configured to send an SDO on...
Definition: device.cpp:123
Type get_entry_type(const std::string &entry_name)
Returns the type of a dictionary entry identified by name as it is defined in the local dictionary...
Definition: device.cpp:87