KaCanOpen
 All Classes Functions Variables Typedefs Enumerations Pages
joint_state_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 "joint_state_subscriber.h"
33 #include "utils.h"
34 #include "logger.h"
35 #include "profiles.h"
36 #include "sdo_error.h"
37 
38 #include "ros/ros.h"
39 
40 #include <string>
41 
42 namespace kaco {
43 
44 JointStateSubscriber::JointStateSubscriber(Device& device, int32_t position_0_degree,
45  int32_t position_360_degree, std::string topic_name)
46  : m_device(device), m_position_0_degree(position_0_degree),
47  m_position_360_degree(position_360_degree), m_topic_name(topic_name),
48  m_initialized(false)
49 {
50 
51  const uint16_t profile = device.get_device_profile_number();
52 
53  if (profile != 402) {
54  throw std::runtime_error("JointStatePublisher can only be used with a CiA 402 device."
55  " You passed a device with profile number "+std::to_string(profile));
56  }
57 
58  const Value operation_mode = device.get_entry("Modes of operation display");
59 
60  // TODO: look into INTERPOLATED_POSITION_MODE
61  if (operation_mode != Profiles::constants.at(402).at("profile_position_mode")
62  && operation_mode != Profiles::constants.at(402).at("interpolated_position_mode")) {
63  throw std::runtime_error("[JointStatePublisher] Only position mode supported yet."
64  " Try device.set_entry(\"modes_of_operation\", device.get_constant(\"profile_position_mode\"));");
65  }
66 
67  if (m_topic_name.empty()) {
68  uint8_t node_id = device.get_node_id();
69  m_topic_name = "device" + std::to_string(node_id) + "/set_joint_state";
70  }
71 
72 }
73 
75 
76  assert(!m_topic_name.empty());
77  DEBUG_LOG("Advertising "<<m_topic_name);
78  ros::NodeHandle nh;
79  m_subscriber = nh.subscribe(m_topic_name, queue_size, &JointStateSubscriber::receive, this);
80  m_initialized = true;
81 
82 }
83 
84 void JointStateSubscriber::receive(const sensor_msgs::JointState& msg) {
85 
86  try {
87 
88  assert(msg.position.size()>0);
89  const int32_t pos = rad_to_pos(msg.position[0]);
90 
91  DEBUG_LOG("Received JointState message");
92  DEBUG_DUMP(pos);
93  DEBUG_DUMP(msg.position[0]);
94 
95  m_device.execute("set_target_position",pos);
96 
97  } catch (const sdo_error& error) {
98  // TODO: only catch timeouts?
99  ERROR("Exception in JointStateSubscriber::receive(): "<<error.what());
100  }
101 
102 }
103 
104 int32_t JointStateSubscriber::rad_to_pos(double rad) const {
105 
106  const double p = rad;
107  const double min = m_position_0_degree;
108  const double max = m_position_360_degree;
109  const double dist = max - min;
110  const double result = ((p/(2*pi()))*dist)+min;
111  return (int32_t) result;
112 
113 }
114 
115 } // end namespace kaco
const Value & get_entry(const std::string &entry_name, const ReadAccessMethod access_method=ReadAccessMethod::use_default)
Gets the value of a dictionary entry by name internally. If there is no cached value or the entry is ...
Definition: device.cpp:102
uint16_t get_device_profile_number()
Returns the CiA profile number.
Definition: device.cpp:274
uint8_t get_node_id() const
Returns the node ID of the device.
Definition: device.cpp:74
Value execute(const std::string &operation_name, const Value &argument=m_dummy_value)
Executes a convenience operation. It must exist due to a previous load_operations() or add_operation(...
Definition: device.cpp:428
This class represents a CanOpen slave device in the network.
Definition: device.h:83
JointStateSubscriber(Device &device, int32_t position_0_degree, int32_t position_360_degree, std::string topic_name="")
Constructor.
This class contains a value to be stored in the object dictionary. The value can have one of the type...
Definition: value.h:53
static const std::map< uint16_t, std::map< std::string, const Value > > constants
Constants for CiA profiles. Type: map < profile number , map < operation name , constant value > > ...
Definition: profiles.h:60