clion 初始化開發配置筆記針對ros
1. clion模板配置
模板數據在下面!
2.大小寫匹配提示
3. 打開clion後不會進入上一次項目
2. c++ class 模板配置
#parse("C File Header.h")
#[[#ifndef]]# ${INCLUDE_GUARD}
#[[#define]]# ${INCLUDE_GUARD}
${NAMESPACES_OPEN}
class ${NAME} {
public:
${NAME}();
~${NAME}();
};
${NAMESPACES_CLOSE}
#[[#endif]]# //${INCLUDE_GUARD}
#parse("C File Header.h")
#[[#include]]# "${HEADER_FILENAME}"
${NAME}::${NAME}(){
}
${NAME}::~${NAME}(){
}
3.python ros環境配置
Clion的Python環境¶
爲了演示第一個程序,首先我們按照前面的例子,在workspace中創建一個demo_py
的package,我們基於這個demo_py
進行講解開發。
使用clion打開demo_py
。
1. 創建scripts目錄¶
在demo_py
的目錄中創建scripts
目錄,用於寫python代碼。
2.配置Python環境¶
打開clion的setting
,來到Build,Execution,Deployment
的Python Interpreter下
,點擊設置按鍵,點擊添加。
打開python環境設置按鈕,添加python環境
Tip
特別要注意**的是,目前ROS Melodic版本還**不支持python3,要等到ROS N版纔會支持。
因此,我們選擇環境的時候**選擇python2.x版本**。
注意: 新建的python文件需要改權限才能運行 chmoe 777 *
-----------------------------------------------------------------------------------------------
模板數據
python 模板:
py_main
#!/usr/bin/env python
# coding:utf-8
import rospy
# 導入數據
from std_msgs.msg import String
if __name__ == '__main__':
# 節點名
nodeName = 'py_publisher'
# 初始化節點 定義匿名節點加參數 anonymous=True
rospy.init_node(nodeName,anonymous=True)
py_node
import rospy
# 節點名
nodeName = 'py_publisher'
# 初始化節點 定義匿名節點加參數 anonymous=True
rospy.init_node(nodeName,anonymous=True)
1.py_class_PyQt5
#!/usr/bin/env python
# coding:utf-8
from PyQt5.QtWidgets import QWidget,QFormLayout,QLineEdit,QPushButton,QLabel
from geometry_msgs.msg import Twist
from turtlesim.msg import Pose
import rospy
class MainWindow(QWidget):
def __init__(self,publisher):
super(MainWindow, self).__init__()
pass
2.py_main_PyQt5
#!/usr/bin/env python
# coding:utf-8
from PyQt5.QtWidgets import QApplication
from MainWindow import MainWindow
import sys
import rospy
if __name__ == '__main__':
# 創建節點
rospy.init_node("py_control")
# 創建Qt
app = QApplication(sys.argv)
# 創建窗口
w = MainWindow()
# 展示窗口
w.show()
# 等待程序結束
sys.exit(app.exec_())
3.1server
py_client_main
#!/usr/bin/env python
# coding:utf-8
import rospy
from roscpp_tutorials.srv import TwoInts,TwoIntsRequest
if __name__ == '__main__':
# 創建節點
rospy.init_node("py_client")
# service名字
serviceName = 'py_service'
# 創建客戶端
proxy = rospy.ServiceProxy(serviceName, TwoInts)
# 等待service上線
proxy.wait_for_service()
# 請求數據
req = TwoIntsRequest()
req.a = 12
req.b = 13
# 調用service
result = proxy.call(req)
print result
py_client
import rospy
from roscpp_tutorials.srv import TwoInts,TwoIntsRequest
# service名字
serviceName = 'py_service'
# 創建客戶端
proxy = rospy.ServiceProxy(serviceName, TwoInts)
# 等待service上線
proxy.wait_for_service()
# 請求數據
req = TwoIntsRequest()
req.a = 12
req.b = 13
# 調用service
result = proxy.call(req)
print result
3.1 py_server_main
#!/usr/bin/env python
# coding:utf-8
import rospy
from roscpp_tutorials.srv import TwoInts
def callBack(req):
return req.a+req.b
if __name__ == '__main__':
# 創建節點
rospy.init_node("py_server")
# service名字
serviceName = 'py_service'
# 創建server端
service = rospy.Service(serviceName, TwoInts, callBack)
# 阻塞
rospy.spin()
py_server
import rospy
from roscpp_tutorials.srv import TwoInts
def callBack(req):
return req.a+req.b
# 創建節點
rospy.init_node("py_server")
# service名字
serviceName = 'py_service'
# 創建server端
service = rospy.Service(serviceName, TwoInts, callBack)
# 阻塞
rospy.spin()
4. topic
py_publisher_main
#!/usr/bin/env python
# coding:utf-8
import rospy
# 導入數據
from std_msgs.msg import String
if __name__ == '__main__':
# 節點名
nodeName = 'py_publisher'
# 初始化節點
rospy.init_node(nodeName,anonymous=True)
# 話題名
topicName = 'py_topic'
# 創建發佈者
publisher = rospy.Publisher(topicName, String, queue_size=5)
# 每一秒鐘發送一條消息
rate = rospy.Rate(1)
i = 0
# 循環
while not rospy.is_shutdown():
# 消息內容
data = String()
data.data = 'hello {}'.format(i)
# 發送消息
publisher.publish(data)
# 增加數據
i += 1
rate.sleep()
py_publisher
import rospy
# 導入數據
from std_msgs.msg import String
# 話題名
topicName = 'py_topic'
# 創建發佈者
publisher = rospy.Publisher(topicName, String, queue_size=5)
# 每一秒鐘發送一條消息
rate = rospy.Rate(1)
i = 0
# 循環
while not rospy.is_shutdown():
# 消息內容
data = String()
data.data = 'hello {}'.format(i)
# 發送消息
publisher.publish(data)
# 增加數據
i += 1
rate.sleep()
py_subscriber_main
#!/usr/bin/env python
# coding:utf-8
import rospy
# from std_msgs.msg import String
from geometry_msgs.msg import Twist
import threading
# python訂閱者回調在子線程中
def callBack(data):
print '接收的線程id:{}'.format(threading.current_thread().name)
print '收到數據:{}'.format(data.linear.x)
if __name__ == '__main__':
print '主線程線程id:{}'.format(threading.current_thread().name)
# 節點名
nodeName = 'py_subscriber'
# 初始化節點
rospy.init_node(nodeName,anonymous=True)
# topic名字
topicName = 'py_topic'
# 創建訂閱者
# 參數1:topic名字
# 參數2:topic數據類型
# 參數3:回調函數
subscriber = rospy.Subscriber(topicName, Twist, callBack)
# 事件處理
rospy.spin()
py_subscriber
import rospy
# from std_msgs.msg import String
from geometry_msgs.msg import Twist
def callBack(data):
data.linear.x
print '收到數據:{}'.format(data.linear.x)
# topic名字
topicName = 'py_topic'
# 創建訂閱者
# 參數1:topic名字
# 參數2:topic數據類型
# 參數3:回調函數
subscriber = rospy.Subscriber(topicName, Twist, callBack)
# 事件處理
rospy.spin()
c++ 模板:
cpp_main
#include <iostream>
#include <ros/ros.h>
using namespace std;
int main(int argc,char *argv[]){
//節點名
string nodeName = "$args1$";
//初始化節點
ros::init(argc,argv,nodeName);
//創建節點
ros::NodeHandle node;
$args2$
//事件輪詢
ros::spin();
return 0;
}
cpp_node
//創建節點
ros::NodeHandle node;
1. cpp_class_source_Qt5
#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QCheckBox>
#include <ros/ros.h>
#include <std_srvs/Empty.h>
#include <turtlesim/Spawn.h>
#include <turtlesim/Kill.h>
#include <turtlesim/SetPen.h>
#include <turtlesim/TeleportAbsolute.h>
#include <turtlesim/TeleportRelative.h>
#include <iostream>
#include "MainWindow.h"
MainWindow::MainWindow(ros::NodeHandle node, QWidget *parent) : QWidget(parent), node(node)
{
}
MainWindow::~MainWindow() {
}
2. cpp_class_head_Qt5
#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QCheckBox>
#include <ros/ros.h>
#include <std_srvs/Empty.h>
#include <turtlesim/Spawn.h>
#include <turtlesim/Kill.h>
#include <turtlesim/SetPen.h>
#include <turtlesim/TeleportAbsolute.h>
#include <turtlesim/TeleportRelative.h>
#include <iostream>
using namespace std;
class MainWindow: public QWidget {
public:
explicit MainWindow(ros::NodeHandle node,QWidget* parent = Q_NULLPTR);
~MainWindow() override;
};
3.server
cpp_client_main
#include <iostream>
#include <ros/ros.h>
#include <roscpp_tutorials/TwoInts.h>
using namespace std;
int main(int argc,char *argv[]){
//節點名
string nodeName = "cpp_client";
//初始化節點
ros::init(argc,argv,nodeName,ros::init_options::AnonymousName);
//創建節點
ros::NodeHandle node;
//service名字
string serviceName = "cpp_service";
//創建client
ros::ServiceClient client = node.serviceClient<roscpp_tutorials::TwoInts>(serviceName);
//等待server端上線
client.waitForExistence();
//定義數據
roscpp_tutorials::TwoInts service;
service.request.a = 12;
service.request.b = 13;
//調用service
client.call(service);
ROS_INFO_STREAM("result:"<<service.response.sum);
//事件輪詢
ros::spin();
return 0;
}
cpp_client
#include <iostream>
#include <ros/ros.h>
#include <roscpp_tutorials/TwoInts.h>
using namespace std;
//service名字
string serviceName = "cpp_service";
//創建client
ros::ServiceClient client = node.serviceClient<roscpp_tutorials::TwoInts>(serviceName);
//等待server端上線
client.waitForExistence();
//定義數據
roscpp_tutorials::TwoInts service;
service.request.a = 12;
service.request.b = 13;
//調用service
client.call(service);
ROS_INFO_STREAM("result:"<<service.response.sum);
//事件輪詢
ros::spin();
3.1
cpp_server_main
#include <iostream>
#include <ros/ros.h>
#include <roscpp_tutorials/TwoInts.h>
using namespace std;
bool callBack(roscpp_tutorials::TwoIntsRequest& req,roscpp_tutorials::TwoIntsResponse& res){
//從請求中獲取兩個參數
//把和通過res返回出去
res.sum = req.a+req.b;
return true;
}
int main(int argc,char *argv[]){
//節點名
string nodeName = "cpp_server";
//初始化節點
ros::init(argc,argv,nodeName);
//創建節點
ros::NodeHandle node;
//service名字
string serviceName = "cpp_service";
//創建server端
const ros::ServiceServer &server = node.advertiseService(serviceName, callBack);
//事件輪詢
ros::spin();
return 0;
}
cpp_server
#include <iostream>
#include <ros/ros.h>
#include <roscpp_tutorials/TwoInts.h>
using namespace std;
bool callBack(roscpp_tutorials::TwoIntsRequest& req,roscpp_tutorials::TwoIntsResponse& res){
//從請求中獲取兩個參數
//把和通過res返回出去
res.sum = req.a+req.b;
return true;
}
//service名字
string serviceName = "cpp_service";
//創建server端
const ros::ServiceServer &server = node.advertiseService(serviceName, callBack);
//事件輪詢
ros::spin();
4 topic
cpp_publisher_main
#include <iostream>
#include <ros/ros.h>
#include <std_msgs/String.h>
using namespace std;
int main(int argc,char *argv[]){
//節點名
string nodeName = "cpp_publisher";
//初始化節點 匿名節點
ros::init(argc,argv,nodeName,ros::init_options::AnonymousName);
//創建節點
ros::NodeHandle node;
//節點名
string topicName = "cpp_topic";
//創建topic發送者
//參數1:節點名
//參數2:消息隊列容量
const ros::Publisher &publisher = node.advertise<std_msgs::String>(topicName, 5);
//每隔一秒鐘發送一條消息
ros::Rate rate(1);
int i = 0;
while (ros::ok()){
std_msgs::String data;
data.data = "hello "+to_string(i);
//發送一條消息
publisher.publish(data);
//增加i
i+=1;
//睡眠
rate.sleep();
}
return 0;
}
cpp_publishe
#include <iostream>
#include <ros/ros.h>
#include <std_msgs/String.h>
using namespace std;
//節點名
string topicName = "cpp_topic";
//創建topic發送者
//參數1:節點名
//參數2:消息隊列容量
const ros::Publisher &publisher = node.advertise<std_msgs::String>(topicName, 5);
//每隔一秒鐘發送一條消息
ros::Rate rate(1);
int i = 0;
while (ros::ok()){
std_msgs::String data;
data.data = "hello "+to_string(i);
//發送一條消息
publisher.publish(data);
//增加i
i+=1;
//睡眠
rate.sleep();
}
cpp_subscriber_main
#include <iostream>
#include <std_msgs/String.h>
#include <ros/ros.h>
#include <thread>
using namespace std;
//c++ 訂閱者的回調在主線程中
void callBack(std_msgs::String::ConstPtr data){
cout<<"回調:"<<this_thread::get_id()<<endl;
cout<<"收到消息:"<<data->data<<endl;
}
int main(int argc, char *argv[]) {
cout<<"主線程:"<<this_thread::get_id()<<endl;
//節點名
string nodeName = "cpp_subscriber";
// string nodeName = "cpp_publisher";
//初始化節點
ros::init(argc, argv, nodeName,ros::init_options::AnonymousName);
//創建節點
ros::NodeHandle node;
//topic名字
string topicName = "cpp_topic";
//訂閱者
//參數1:topic名字
//參數2:隊列長度
//參數3:回調函數
//注意:返回的Subscriber必須要接收,如果不接受 可能收不到消息
const ros::Subscriber &subscriber = node.subscribe<std_msgs::String>(topicName, 5, callBack);
//ros::spin 處理事件
ros::spin();
return 0;
}
cpp_subscriber
#include <iostream>
#include <std_msgs/String.h>
#include <ros/ros.h>
#include <thread>
using namespace std;
//c++ 訂閱者的回調在主線程中
void callBack(std_msgs::String::ConstPtr data){
cout<<"回調:"<<this_thread::get_id()<<endl;
cout<<"收到消息:"<<data->data<<endl;
}
//topic名字
string topicName = "cpp_topic";
//訂閱者
//參數1:topic名字
//參數2:隊列長度
//參數3:回調函數
//注意:返回的Subscriber必須要接收,如果不接受 可能收不到消息
const ros::Subscriber &subscriber = node.subscribe<std_msgs::String>(topicName, 5, callBack);
ros::spin();