• 使用rosserial实现ROS与Windows的service服务通信


    小结

    使用rosserial window来实现ROS与Windows的service服务通信,测试了add_two_ints的服务,并使用rosserial window在windows端创建Visual Studio C++连接使用创建的add_two_ints服务,并测试成功。

    回顾:rosserial windows实现rostopic的发布和订阅

    使用rosserial windows实现rostopic的发布和订阅的资料容易得到,网上有现成的,参见 https://github.com/Waywrong/ros_win_msg/tree/master/RosserialWin

    http://wiki.ros.org/rosserial_windows

    Rosserial Windows Client C++代码经过测试如下:

    int main()
    {
        std::cout << "Hello World!\n";
    	ros::NodeHandle nh;
    
    	char *ros_master = "192.168.86.28";// 运行rosseial服务器节点的主机IP
    
    	printf("Connecting to server at %s\n", ros_master);
    	nh.initNode(ros_master);
    
    	printf("Advertising cmd_vel message\n");
    
    	geometry_msgs::Twist twist_msg;
    
    	ros::Publisher cmd_vel_pub("/turtle1/cmd_vel", &twist_msg);
    	nh.advertise(cmd_vel_pub);
    
    	printf("Go robot go!\n");
    
    	while (1)
    	{
    		twist_msg.linear.x = 5.1;
    		twist_msg.linear.y = 0;
    		twist_msg.linear.z = 0;
    		twist_msg.angular.x = 0;
    		twist_msg.angular.y = 0;
    		twist_msg.angular.z = -1.8;
    		cmd_vel_pub.publish(&twist_msg);
    		nh.spinOnce();
    		Sleep(100);
    	}
    
    	printf("All done!\n");
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    正题: 使用rosserial实现ROS与Windows的service服务通信

    启动roscore

    john@ubuntu:~$ roscore
    ... logging to /home/john/.ros/log/8ba9ec9a-10da-11ed-ad09-9d6885123387/roslaunch-ubuntu-6888.log
    Checking log directory for disk usage. This may take a while.
    Press Ctrl-C to interrupt
    Done checking log file disk usage. Usage is <1GB.
    
    started roslaunch server http://ubuntu:33213/
    ros_comm version 1.15.14
    
    
    SUMMARY
    ========
    
    PARAMETERS
     * /rosdistro: noetic
     * /rosversion: 1.15.14
    
    NODES
    
    auto-starting new master
    process[master]: started with pid [6900]
    ROS_MASTER_URI=http://ubuntu:11311/
    
    setting /run_id to 8ba9ec9a-10da-11ed-ad09-9d6885123387
    process[rosout-1]: started with pid [6911]
    started core service [/rosout]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    启动add_two_ints的服务并测试

    启动add_two_ints的服务:

    john@ubuntu:~$ rosrun ros_cpp add_two_ints_server.py 
    Ready to add two ints.
    
    
    • 1
    • 2
    • 3

    有以下服务:

    john@ubuntu:~$ rosservice list
    /add_two_ints
    /add_two_ints_server/get_loggers
    /add_two_ints_server/set_logger_level
    /rosout/get_loggers
    /rosout/set_logger_level
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在本机测试,返回成功的结果:

    john@ubuntu:~$ rosrun ros_cpp add_two_ints_client.py 6 4
    Requesting 6+4
    6 + 4 = 10
    
    • 1
    • 2
    • 3

    服务端结果:

    john@ubuntu:~$ rosrun ros_cpp add_two_ints_server.py 
    Ready to add two ints.
    Returning [6 + 4 = 10]
    
    
    • 1
    • 2
    • 3
    • 4

    服务器与客户端的python代码如下:

    • add_two_ints_server.py
    
    #!/usr/bin/env python
      
    from ros_essentials_cpp.srv import AddTwoInts
    from ros_essentials_cpp.srv import AddTwoIntsRequest
    from ros_essentials_cpp.srv import AddTwoIntsResponse
    
    import rospy
    
    def handle_add_two_ints(req):
        print ("Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b)))
        return AddTwoIntsResponse(req.a + req.b)
    
    def add_two_ints_server():
        rospy.init_node('add_two_ints_server')
        s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
        print ("Ready to add two ints.")
        rospy.spin()
    
    if __name__ == "__main__":
        add_two_ints_server()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • add_two_ints_client.py:
    #!/usr/bin/env python
    
    import sys
    import rospy
    from ros_essentials_cpp.srv import AddTwoInts
    from ros_essentials_cpp.srv import AddTwoIntsRequest
    from ros_essentials_cpp.srv import AddTwoIntsResponse
    
    def add_two_ints_client(x, y):
        rospy.wait_for_service('add_two_ints')
        try:
            add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
            resp1 = add_two_ints(x, y)
            return resp1.sum
        except rospy.ServiceException(e):
            print ("Service call failed: %s"%e)
    
    def usage():
        return
    
    if __name__ == "__main__":
        if len(sys.argv) == 3:
            x = int(sys.argv[1])
            y = int(sys.argv[2])
        else:
            print ("%s [x y]"%sys.argv[0])
            sys.exit(1)
        print ("Requesting %s+%s"%(x, y))
        s = add_two_ints_client(x, y)
        print ("%s + %s = %s"%(x, y, s))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    使用rosserial Windows client C++实现与ROS的add_two_ints service服务通信

    参考关于如何利用rosserial在windows和linux间实现service服务 和 arduino的rosserial的实现: rosserial/rosserial_arduino/src/ros_lib/examples/ServiceClient/ServiceClient.pde

    rosserial Windows client C++实现代码如下:

    #include 
    #include 
    #include 
    #include "ros.h"
    #include 
    #include 
    
    ros::NodeHandle nh;
    using ros_essentials_cpp::AddTwoInts;
    
    ros::ServiceClient<ros_essentials_cpp::AddTwoInts::Request, ros_essentials_cpp::AddTwoInts::Response> client("add_two_ints");
    
    ros_essentials_cpp::AddTwoInts::Request req;
    ros_essentials_cpp::AddTwoInts::Response res;
    
    int main(int argc, char ** argv)
    {
    	std::cout << "Hello World!\n";
    	char *ros_master = "192.168.86.28";
    
    	if (argc != 3)
    	{
    		printf("usage: add_two_ints_client X Y");
    		return 1;
    	}
    
    	printf("Connecting to server at %s\n", ros_master);
    	nh.initNode(ros_master);
    
    	nh.serviceClient(client);
    
    	while (!nh.connected())
    	{
    		nh.spinOnce();
    		nh.loginfo("John is connected");	
    	}
    
    	req.a = atoll(argv[1]);
    	req.b = atoll(argv[2]);
    	
    	client.call(req, res);
    	printf("Sum: %ld", (long int)res.sum);
    	return 0;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    成功的测试结果

    这里要启动rosserial_server

    john@ubuntu:~$ rosrun rosserial_server socket_node
    [ INFO] [1659280508.931238641]: Listening for rosserial TCP connections on port 11411
    
    
    • 1
    • 2
    • 3

    否则会报错:

    Failed to receive data from server 10093
    Send failed with error 10093
    Failed to receive data from server 10093
    
    • 1
    • 2
    • 3

    rosserial Windows client C++客户端结果 (输入两个整数为5和20):

    Hello World!
    Connecting to server at 192.168.86.28
    Sum: 25
    D:\ROS_ServiceTest\Debug\ROS_ServiceTest.exe (process 20108) exited with code 0.
    To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
    Press any key to close this window . . .
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    服务器结果如下:

    john@ubuntu:~$ rosrun ros_essentials_cpp add_server.py 
    Ready to add two ints.
    Returning [6 + 4 = 10]
    Returning [5 + 20 = 25]
    
    • 1
    • 2
    • 3
    • 4

    串口处输出如下:

    john@ubuntu:~$ rosrun rosserial_server socket_node
    [ INFO] [1659280508.931238641]: Listening for rosserial TCP connections on port 11411
    [ INFO] [1659280566.121354532]: John is connected
    [ INFO] [1659280566.122366251]: John is connected
    [ INFO] [1659280566.123935089]: John is connected
    [ INFO] [1659280566.125541004]: John is connected
    [ INFO] [1659280566.125794801]: John is connected
    ......
    ......
    [ WARN] [1659280570.507645794]: Socket asio error, closing socket: system:104
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    参考

    关于如何利用rosserial在windows和linux间实现service服务
    Rosserial-embeddedlinux部署
    ROS串口编程学习笔记
    root / quad2 / arduino / src / ros_lib / examples / ServiceClient / ServiceClient.pde @ c1426757
    Github: rosserial/rosserial_arduino/src/ros_lib/examples/ServiceClient/ServiceClient.pde
    https://github.com/Waywrong/ros_win_msg/tree/master/RosserialWin
    http://wiki.ros.org/ROS/Tutorials/WritingServiceClient%28python%29
    http://wiki.ros.org/rosserial_windows
    https://answers.ros.org/question/299081/call-service-from-arduino/
    https://answers.ros.org/question/263060/what-arguments-for-rospyserviceproxy/
    https://atadiat.com/en/e-rosserial-arduino-introduction/

  • 相关阅读:
    【简单介绍下Faiss原理和使用】
    软件测试基础
    树-->算法总结
    2022牛客多校联赛第七场 题解
    NVIDIA 第七届 SkyHackathon(一)环境配置
    SQLi-LABS Page-3 (Stacked Injections)
    干豆数据集
    bp神经网络解决什么问题,bp神经网络的改进方法
    NR/5G - PUSCH repetition次数
    SQL设计时增加说明列
  • 原文地址:https://blog.csdn.net/scruffybear/article/details/126091179