to_topic_test.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, Ivor Wanders
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution.
11  * * Neither the name of the copyright holder nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
28 
29 #include <can_msgs/Frame.h>
33 
34 #include <gtest/gtest.h>
35 #include <ros/ros.h>
36 #include <list>
37 
39 {
40  public:
41  std::list<can_msgs::Frame> messages;
42 
44 
45  void msgCallback(const can_msgs::Frame& f)
46  {
47  messages.push_back(f);
48  }
49 };
50 
51 std::string convertMessageToString(const can_msgs::Frame &msg, bool lc=true) {
52  can::Frame f;
54  return can::tostring(f, lc);
55 }
56 
57 TEST(SocketCANToTopicTest, checkCorrectData)
58 {
59  ros::NodeHandle nh(""), nh_param("~");
60 
61  // create the dummy interface
62  can::DummyInterfaceSharedPtr driver_ = boost::make_shared<can::DummyInterface>(true);
63 
64  // start the to topic bridge.
65  socketcan_bridge::SocketCANToTopic to_topic_bridge(&nh, &nh_param, driver_);
66  to_topic_bridge.setup(); // initiate the message callbacks
67 
68  // init the driver to test stateListener (not checked automatically).
69  driver_->init("string_not_used", true);
70 
71  // create a frame collector.
72  msgCollector message_collector_;
73 
74  // register for messages on received_messages.
75  ros::Subscriber subscriber_ = nh.subscribe("received_messages", 1, &msgCollector::msgCallback, &message_collector_);
76 
77  // create a can frame
78  can::Frame f;
79  f.is_extended = true;
80  f.is_rtr = false;
81  f.is_error = false;
82  f.id = 0x1337;
83  f.dlc = 8;
84  for (uint8_t i=0; i < f.dlc; i++)
85  {
86  f.data[i] = i;
87  }
88 
89  // send the can frame to the driver
90  driver_->send(f);
91 
92  // give some time for the interface some time to process the message
93  ros::WallDuration(1.0).sleep();
94  ros::spinOnce();
95 
96  ASSERT_EQ(1, message_collector_.messages.size());
97 
98  // compare the received can_msgs::Frame message to the sent can::Frame.
99  can::Frame received;
100  can_msgs::Frame msg = message_collector_.messages.back();
102 
103  EXPECT_EQ(received.id, f.id);
104  EXPECT_EQ(received.dlc, f.dlc);
105  EXPECT_EQ(received.is_extended, f.is_extended);
106  EXPECT_EQ(received.is_rtr, f.is_rtr);
107  EXPECT_EQ(received.is_error, f.is_error);
108  EXPECT_EQ(received.data, f.data);
109 }
110 
111 TEST(SocketCANToTopicTest, checkInvalidFrameHandling)
112 {
113  // - tries to send a non-extended frame with an id larger than 11 bits.
114  // that should not be sent.
115  // - verifies that sending one larger than 11 bits actually works.
116 
117  // sending a message with a dlc > 8 is not possible as the DummyInterface
118  // causes a crash then.
119 
120  ros::NodeHandle nh(""), nh_param("~");
121 
122  // create the dummy interface
123  can::DummyInterfaceSharedPtr driver_ = boost::make_shared<can::DummyInterface>(true);
124 
125  // start the to topic bridge.
126  socketcan_bridge::SocketCANToTopic to_topic_bridge(&nh, &nh_param, driver_);
127  to_topic_bridge.setup(); // initiate the message callbacks
128 
129  // create a frame collector.
130  msgCollector message_collector_;
131 
132  // register for messages on received_messages.
133  ros::Subscriber subscriber_ = nh.subscribe("received_messages", 1, &msgCollector::msgCallback, &message_collector_);
134 
135  // create a message
136  can::Frame f;
137  f.is_extended = false;
138  f.id = (1<<11)+1; // this is an illegal CAN packet... should not be sent.
139 
140  // send the can::Frame over the driver.
141  // driver_->send(f);
142 
143  // give some time for the interface some time to process the message
144  ros::WallDuration(1.0).sleep();
145  ros::spinOnce();
146  EXPECT_EQ(message_collector_.messages.size(), 0);
147 
148  f.is_extended = true;
149  f.id = (1<<11)+1; // now it should be alright.
150 
151  driver_->send(f);
152  ros::WallDuration(1.0).sleep();
153  ros::spinOnce();
154  EXPECT_EQ(message_collector_.messages.size(), 1);
155 }
156 
157 TEST(SocketCANToTopicTest, checkCorrectCanIdFilter)
158 {
159  ros::NodeHandle nh(""), nh_param("~");
160 
161  // create the dummy interface
162  can::DummyInterfaceSharedPtr driver_ = boost::make_shared<can::DummyInterface>(true);
163 
164  //create can_id vector with id that should be passed and published to ros
165  std::vector<unsigned int> pass_can_ids;
166  pass_can_ids.push_back(0x1337);
167 
168  // start the to topic bridge.
169  socketcan_bridge::SocketCANToTopic to_topic_bridge(&nh, &nh_param, driver_);
170  to_topic_bridge.setup(can::tofilters(pass_can_ids)); // initiate the message callbacks
171 
172  // init the driver to test stateListener (not checked automatically).
173  driver_->init("string_not_used", true);
174 
175  // create a frame collector.
176  msgCollector message_collector_;
177 
178  // register for messages on received_messages.
179  ros::Subscriber subscriber_ = nh.subscribe("received_messages", 1, &msgCollector::msgCallback, &message_collector_);
180 
181  // create a can frame
182  can::Frame f;
183  f.is_extended = true;
184  f.is_rtr = false;
185  f.is_error = false;
186  f.id = 0x1337;
187  f.dlc = 8;
188  for (uint8_t i=0; i < f.dlc; i++)
189  {
190  f.data[i] = i;
191  }
192 
193  // send the can frame to the driver
194  driver_->send(f);
195 
196  // give some time for the interface some time to process the message
197  ros::WallDuration(1.0).sleep();
198  ros::spinOnce();
199 
200  ASSERT_EQ(1, message_collector_.messages.size());
201 
202  // compare the received can_msgs::Frame message to the sent can::Frame.
203  can::Frame received;
204  can_msgs::Frame msg = message_collector_.messages.back();
206 
207  EXPECT_EQ(received.id, f.id);
208  EXPECT_EQ(received.dlc, f.dlc);
209  EXPECT_EQ(received.is_extended, f.is_extended);
210  EXPECT_EQ(received.is_rtr, f.is_rtr);
211  EXPECT_EQ(received.is_error, f.is_error);
212  EXPECT_EQ(received.data, f.data);
213 }
214 
215 TEST(SocketCANToTopicTest, checkInvalidCanIdFilter)
216 {
217  ros::NodeHandle nh(""), nh_param("~");
218 
219  // create the dummy interface
220  can::DummyInterfaceSharedPtr driver_ = boost::make_shared<can::DummyInterface>(true);
221 
222  //create can_id vector with id that should not be received on can bus
223  std::vector<unsigned int> pass_can_ids;
224  pass_can_ids.push_back(0x300);
225 
226  // start the to topic bridge.
227  socketcan_bridge::SocketCANToTopic to_topic_bridge(&nh, &nh_param, driver_);
228  to_topic_bridge.setup(can::tofilters(pass_can_ids)); // initiate the message callbacks
229 
230  // init the driver to test stateListener (not checked automatically).
231  driver_->init("string_not_used", true);
232 
233  // create a frame collector.
234  msgCollector message_collector_;
235 
236  // register for messages on received_messages.
237  ros::Subscriber subscriber_ = nh.subscribe("received_messages", 1, &msgCollector::msgCallback, &message_collector_);
238 
239  // create a can frame
240  can::Frame f;
241  f.is_extended = true;
242  f.is_rtr = false;
243  f.is_error = false;
244  f.id = 0x1337;
245  f.dlc = 8;
246  for (uint8_t i=0; i < f.dlc; i++)
247  {
248  f.data[i] = i;
249  }
250 
251  // send the can frame to the driver
252  driver_->send(f);
253 
254  // give some time for the interface some time to process the message
255  ros::WallDuration(1.0).sleep();
256  ros::spinOnce();
257 
258  EXPECT_EQ(0, message_collector_.messages.size());
259 }
260 
261 TEST(SocketCANToTopicTest, checkMaskFilter)
262 {
263  ros::NodeHandle nh(""), nh_param("~");
264 
265  // create the dummy interface
266  can::DummyInterfaceSharedPtr driver_ = boost::make_shared<can::DummyInterface>(true);
267 
268  // setup filter
270  filters.push_back(can::tofilter("300:ffe"));
271 
272  // start the to topic bridge.
273  socketcan_bridge::SocketCANToTopic to_topic_bridge(&nh, &nh_param, driver_);
274  to_topic_bridge.setup(filters); // initiate the message callbacks
275 
276  // init the driver to test stateListener (not checked automatically).
277  driver_->init("string_not_used", true);
278 
279  // create a frame collector.
280  msgCollector message_collector_;
281 
282  // register for messages on received_messages.
283  ros::Subscriber subscriber_ = nh.subscribe("received_messages", 10, &msgCollector::msgCallback, &message_collector_);
284 
285  const std::string pass1("300#1234"), nopass1("302#9999"), pass2("301#5678");
286 
287  // send the can framew to the driver
288  driver_->send(can::toframe(pass1));
289  driver_->send(can::toframe(nopass1));
290  driver_->send(can::toframe(pass2));
291 
292  // give some time for the interface some time to process the message
293  ros::WallDuration(1.0).sleep();
294  ros::spinOnce();
295 
296  // compare the received can_msgs::Frame message to the sent can::Frame.
297  ASSERT_EQ(2, message_collector_.messages.size());
298  EXPECT_EQ(pass1, convertMessageToString(message_collector_.messages.front()));
299  EXPECT_EQ(pass2, convertMessageToString(message_collector_.messages.back()));
300 }
301 
302 int main(int argc, char **argv)
303 {
304  ros::init(argc, argv, "test_to_topic");
305  ros::NodeHandle nh;
306  ros::WallDuration(1.0).sleep();
307  testing::InitGoogleTest(&argc, argv);
308  return RUN_ALL_TESTS();
309 }
FilteredFrameListener::FilterVector tofilters(const T &v)
TEST(SocketCANToTopicTest, checkCorrectData)
std::string tostring(const Header &h, bool lc)
unsigned int is_error
f
FrameFilterSharedPtr tofilter(const T &ct)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::list< can_msgs::Frame > messages
boost::array< value_type, 8 > data
Frame toframe(const std::string &s)
void convertMessageToSocketCAN(const can_msgs::Frame &m, can::Frame &f)
std::vector< FrameFilterSharedPtr > FilterVector
unsigned int is_extended
bool sleep() const
void msgCallback(const can_msgs::Frame &f)
unsigned char dlc
ROSCPP_DECL void spinOnce()
unsigned int id
std::string convertMessageToString(const can_msgs::Frame &msg, bool lc=true)
unsigned int is_rtr
int main(int argc, char **argv)


socketcan_bridge
Author(s): Ivor Wanders
autogenerated on Fri May 14 2021 02:59:47