diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..dc04706
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,237 @@
+cmake_minimum_required(VERSION 3.0.2)
+project(Air_Ground_CEC)
+
+## Compile as C++11, supported in ROS Kinetic and newer
+add_compile_options(-std=c++11)
+
+## Find catkin macros and libraries
+## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
+## is used, also find other catkin packages
+find_package(catkin REQUIRED COMPONENTS
+ roscpp
+ std_msgs
+ cv_bridge
+ sensor_msgs
+ image_transport
+)
+
+## System dependencies are found with CMake's conventions
+# find_package(Boost REQUIRED COMPONENTS system)
+
+
+## Uncomment this if the package has a setup.py. This macro ensures
+## modules and global scripts declared therein get installedsudo sh -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
+## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
+# catkin_python_setup()
+
+################################################
+## Declare ROS messages, services and actions ##
+################################################
+
+## To declare and build messages, services or actions from within this
+## package, follow these steps:
+## * Let MSG_DEP_SET be the set of packages whose message types you use in
+## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
+## * In the file package.xml:
+## * add a build_depend tag for "message_generation"
+## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
+## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
+## but can be declared for certainty nonetheless:
+## * add a exec_depend tag for "message_runtime"
+## * In this file (CMakeLists.txt):
+## * add "message_generation" and every package in MSG_DEP_SET to
+## find_package(catkin REQUIRED COMPONENTS ...)
+## * add "message_runtime" and every package in MSG_DEP_SET to
+## catkin_package(CATKIN_DEPENDS ...)
+## * uncomment the add_*_files sections below as needed
+## and list every .msg/.srv/.action file to be processed
+## * uncomment the generate_messages entry below
+## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
+
+## Generate messages in the 'msg' folder
+# add_message_files(
+# FILES
+# Message1.msg
+# Message2.msg
+# )
+
+## Generate services in the 'srv' folder
+# add_service_files(
+# FILES
+# Service1.srv
+# Service2.srv
+# )
+
+## Generate actions in the 'action' folder
+# add_action_files(
+# FILES
+# Action1.action
+# Action2.action
+# )
+
+## Generate added messages and services with any dependencies listed here
+# generate_messages(
+# DEPENDENCIES
+# std_msgs # Or other packages containing msgs
+# )
+
+################################################
+## Declare ROS dynamic reconfigure parameters ##
+################################################
+
+## To declare and build dynamic reconfigure parameters within this
+## package, follow these steps:
+## * In the file package.xml:
+## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
+## * In this file (CMakeLists.txt):
+## * add "dynamic_reconfigure" to
+## find_package(catkin REQUIRED COMPONENTS ...)
+## * uncomment the "generate_dynamic_reconfigure_options" section below
+## and list every .cfg file to be processed
+
+## Generate dynamic reconfigure parameters in the 'cfg' folder
+# generate_dynamic_reconfigure_options(
+# cfg/DynReconf1.cfg
+# cfg/DynReconf2.cfg
+# )
+
+###################################
+## catkin specific configuration ##
+###################################
+## The catkin_package macro generates cmake config files for your package
+## Declare things to be passed to dependent projects
+## INCLUDE_DIRS: uncomment this if your package contains header files
+## LIBRARIES: libraries you create in this project that dependent projects also need
+## CATKIN_DEPENDS: catkin_packages dependent projects also need
+## DEPENDS: system dependencies of this project that dependent projects also need
+catkin_package(
+# INCLUDE_DIRS include
+# LIBRARIES Air_Ground_CEC
+# CATKIN_DEPENDS roscpp
+# DEPENDS system_lib
+)
+
+###########
+## Build ##
+###########
+
+find_package(OpenCV REQUIRED)
+find_package(Qt5 REQUIRED COMPONENTS Widgets )
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ src/include/qnode.hpp
+ src/include/joystick.h
+ src/include/dashboard.h
+ src/main/main.cpp
+ src/main/mainwindow.cpp
+ src/main/qnode.cpp
+ src/main/joystick.cpp
+ src/main/dashboard.cpp
+ src/ui/mainwindow.hpp
+ src/ui/mainwindow.ui
+
+)
+
+QT5_add_resources(qrc_Files src/resources/images.qrc)
+## Specify additional locations of header files
+## Your package locations should be listed before other locations
+include_directories(
+ include/Air_Ground_CEC
+ ${catkin_INCLUDE_DIRS}
+ ${OpenCV_INCLUDE_DIRS}
+)
+
+add_executable(Air_Ground_CEC ${SOURCES} ${qrc_Files})
+target_link_libraries(Air_Ground_CEC
+ Qt5::Widgets
+ ${catkin_LIBRARIES}
+ ${OpenCV_LIBRARIES}
+)
+
+## Declare a C++ library
+# add_library(${PROJECT_NAME}
+# src/${PROJECT_NAME}/Air_Ground_CEC.cpp
+# )
+
+## Add cmake target dependencies of the library
+## as an example, code may need to be generated before libraries
+## either from message generation or dynamic reconfigure
+# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
+
+## Declare a C++ executable
+## With catkin_make all packages are built within a single CMake context
+## The recommended prefix ensures that target names across packages don't collide
+# add_executable(${PROJECT_NAME}_node src/Air_Ground_CEC_node.cpp)
+
+## Rename C++ executable without prefix
+## The above recommended prefix causes long target names, the following renames the
+## target back to the shorter version for ease of user use
+## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
+# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
+
+## Add cmake target dependencies of the executable
+## same as for the library above
+# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
+
+## Specify libraries to link a library or executable target against
+# target_link_libraries(${PROJECT_NAME}_node
+# ${catkin_LIBRARIES}
+# )
+
+#############
+## Install ##
+#############
+
+# all install targets should use catkin DESTINATION variables
+# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
+
+## Mark executable scripts (Python etc.) for installation
+## in contrast to setup.py, you can choose the destination
+# catkin_install_python(PROGRAMS
+# scripts/my_python_script
+# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
+# )
+
+## Mark executables for installation
+## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
+# install(TARGETS ${PROJECT_NAME}_node
+# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
+# )
+
+## Mark libraries for installation
+## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
+# install(TARGETS ${PROJECT_NAME}
+# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
+# )
+
+## Mark cpp header files for installation
+# install(DIRECTORY include/${PROJECT_NAME}/
+# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
+# FILES_MATCHING PATTERN "*.h"
+# PATTERN ".svn" EXCLUDE
+# )
+
+## Mark other files for installation (e.g. launch and bag files, etc.)
+# install(FILES
+# # myfile1
+# # myfile2
+# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
+# )
+
+#############
+## Testing ##
+#############
+
+## Add gtest based cpp test target and link libraries
+# catkin_add_gtest(${PROJECT_NAME}-test test/test_Air_Ground_CEC.cpp)
+# if(TARGET ${PROJECT_NAME}-test)
+# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
+# endif()
+
+## Add folders to be run by python nosetests
+# catkin_add_nosetests(test)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0d88f33
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# Air-ground-CEC
+
+test
\ No newline at end of file
diff --git a/doc/空地协同无人侦察系统-软件设计规格说明书.doc b/doc/空地协同无人侦察系统-软件设计规格说明书.doc
new file mode 100644
index 0000000..21c3aba
Binary files /dev/null and b/doc/空地协同无人侦察系统-软件设计规格说明书.doc differ
diff --git a/doc/空地协同无人侦察系统-软件需求构思及描述.docx b/doc/空地协同无人侦察系统-软件需求构思及描述.docx
new file mode 100644
index 0000000..98af291
Binary files /dev/null and b/doc/空地协同无人侦察系统-软件需求构思及描述.docx differ
diff --git a/doc/空地协同无人侦察系统-软件需求规格说明书.docx b/doc/空地协同无人侦察系统-软件需求规格说明书.docx
new file mode 100644
index 0000000..8083faa
Binary files /dev/null and b/doc/空地协同无人侦察系统-软件需求规格说明书.docx differ
diff --git a/model/UML设计图.vsdx b/model/UML设计图.vsdx
new file mode 100755
index 0000000..ac1e19d
Binary files /dev/null and b/model/UML设计图.vsdx differ
diff --git a/package.xml b/package.xml
new file mode 100644
index 0000000..9c40002
--- /dev/null
+++ b/package.xml
@@ -0,0 +1,73 @@
+
+
+ Air_Ground_CEC
+ 0.1.0
+ The Air_Ground_CEC package
+
+
+
+
+ jackyma
+
+
+
+
+
+ Apache 2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ catkin
+ roscpp
+ roscpp
+ roscpp
+
+ opencv2
+ opencv2
+ opencv2
+
+ message_generation
+ message_generation
+ message_runtime
+
+ std_msgs sensor_msgs cv_bridge image_transport
+ std_msgs sensor_msgs cv_bridge image_transport
+ std_msgs sensor_msgs cv_bridge image_transport
+
+
+
+
+
+
+
diff --git a/src/Djitellowhite/Djitellowhite.cpp b/src/Djitellowhite/Djitellowhite.cpp
new file mode 100644
index 0000000..c8a8f52
--- /dev/null
+++ b/src/Djitellowhite/Djitellowhite.cpp
@@ -0,0 +1,146 @@
+#include"Djitellowhite.h"
+#include
+#include
+
+
+#include
+#include
+#include
+
+#include
+#include
+
+using namespace cv;
+using namespace std;
+Tello::Tello(const char* IP) {
+ this->stream_on=false;
+ this->host = inet_addr(IP);
+ cout << "create successfully!" << endl;
+
+}
+Tello::~Tello() {}
+void Tello::set_conf(int socket){
+ this->sock = socket;
+}
+void Tello::get_connect(sockaddr_in serveraddr) {
+ char tmp[10] = {"command"};
+ send_message(tmp,serveraddr,0);// 0 -> timeout
+ cout << "connect successfully!" <host;
+}
+void Tello::takeoff(sockaddr_in serveraddr) {
+ char tmp[10] = {"takeoff"};
+ send_message(tmp,serveraddr,0);// 0 -> timeout
+ cout << "takeoff successfully!" < timeout
+ cout << "land successfully!" <sock,buffer,strlen(buffer),0,(struct sockaddr *)&server_addr, sizeof(server_addr));
+ return true;
+}
+void* Tello::udp_response_receiver(void* arg){
+ //int m_SockServer; //创建socket对象
+ //sockaddr_in serveraddr; //创建sockaddr_in对象储存自身信息(当有多个端口,可以多个绑定)
+ //sockaddr_in serveraddrfrom;
+
+ //serveraddr.sin_family = AF_INET; //设置服务器地址家族
+ //serveraddr.sin_port = htons(8889); //设置服务器端口号
+ //serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0");
+ //m_SockServer = socket(AF_INET, SOCK_DGRAM, 0); //创建一个临时变量并赋值给m_SockServer
+ //int i = bind(m_SockServer, (sockaddr*)&serveraddr, sizeof(serveraddr)); //把名字和套接字绑定
+ //std::cout << "bind:" << i << std::endl;
+
+ int socket = *(int *)arg;
+
+ cout << "receive start" << endl;
+ while(1){
+ char buffer[20];
+ int iret;
+ memset(buffer,0,sizeof(buffer));
+
+ iret = recv(socket, buffer,20,MSG_WAITALL);
+ if(iret > 0 && iret <10){
+ printf("Message from tello: %s\n", buffer);
+ }
+ }
+}
+void Tello::forward(sockaddr_in serveraddr){
+ char tmp[15] = {"forward 20"};
+ send_message(tmp,serveraddr,0);// 0 -> timeout
+ cout << "forward successfully!" < timeout
+ cout << "back successfully!" < timeout
+ cout << "left successfully!" < timeout
+ cout << "right successfully!" < timeout
+ cout << "up successfully!" < timeout
+ cout << "down successfully!" < timeout
+ cout << "cw successfully!" < timeout
+ cout << "ccw successfully!" <stream_on = true;
+
+ cout << "vid";
+ VideoCapture cap("udp://@0.0.0.0:11111");
+ cout << "cap";
+ if(!cap.isOpened()){
+ cout << "fuck off";
+ return;
+ }
+
+ Mat frame;
+ cout << "continue!";
+ while(1){
+ cap>>frame;
+ if(frame.empty())
+ break;
+ imshow("video",frame);
+ waitKey(20);
+
+ }
+ cap.release();
+
+
+}
diff --git a/src/Djitellowhite/Djitellowhite.h b/src/Djitellowhite/Djitellowhite.h
new file mode 100644
index 0000000..bfaa936
--- /dev/null
+++ b/src/Djitellowhite/Djitellowhite.h
@@ -0,0 +1,80 @@
+#ifndef _DJITELLOWHITE_H
+#define _DJITELLOWHITE_H
+#include
+#include
+#include
+#include
+#include
+#include
+/*Library for interacting with DJI Ryze Tello drones.*/
+
+
+//coding = utf - 8
+
+/* """C++ wrapper to interact with the Ryze Tello drone using the official Tello api.
+ Tello API documentation:
+ [1.3](https://dl-cdn.ryzerobotics.com/downloads/tello/20180910/Tello%20SDK%20Documentation%20EN_1.3.pdf)
+*/
+
+#define RESPONSE_TIMEOUT 7 //in seconds
+#define TAKEOFF_TIMEOUT 20 //in seconds
+#define FRAME_GRAB_TIMEOUT 3
+#define TIME_BTW_COMMANDS 0.1 //in seconds
+#define TIME_BTW_RC_CONTROL_COMMANDS 0.001 //in seconds
+#define RETRY_COUNT 3 //number of retries after a failed command
+
+
+//Video stream, server socket
+#define VS_UDP_IP "0.0.0.0"
+#define VS_UDP_PORT 11111
+
+#define CONTROL_UDP_PORT 8889
+#define STATE_UDP_PORT 8890
+
+#define BUFFER_SIZE 1024
+//Constants for video settings
+#define BITRATE_AUTO 0
+#define BITRATE_1MBPS 1
+#define BITRATE_2MBPS 2
+#define BITRATE_3MBPS 3
+#define BITRATE_4MBPS 4
+#define BITRATE_5MBPS 5
+#define RESOLUTION_480P "low"
+#define RESOLUTION_720P "high"
+#define FPS_5 "low"
+#define FPS_15 "middle"
+#define FPS_30 "high"
+#define CAMERA_FORWARD 0
+#define CAMERA_DOWNWARD 1
+//日志模块暂时不写
+
+class Tello {
+private:
+ int sock;
+ bool stream_on;
+ unsigned long host;
+public:
+ Tello(const char* IP);
+ ~Tello();
+ void set_conf(int socket);
+ unsigned long gethost();
+ void get_connect(sockaddr_in serveraddr);
+ void takeoff(sockaddr_in serveraddr);
+ void land(sockaddr_in serveraddr);
+ void forward(sockaddr_in serveraddr);
+ void back(sockaddr_in serveraddr);
+ void left(sockaddr_in serveraddr);
+ void right(sockaddr_in serveraddr);
+ void up(sockaddr_in serveraddr);
+ void down(sockaddr_in serveraddr);
+ void cw(sockaddr_in serveraddr);
+ void ccw(sockaddr_in serveraddr);
+ bool send_message(char* msg,sockaddr_in server_addr,int timeout = RESPONSE_TIMEOUT);
+ static void *udp_response_receiver(void* arg);
+ void get_video(sockaddr_in serveraddr);
+};
+
+
+
+
+#endif
diff --git a/src/Djitellowhite/Djitellowhite.o b/src/Djitellowhite/Djitellowhite.o
new file mode 100644
index 0000000..12a9638
Binary files /dev/null and b/src/Djitellowhite/Djitellowhite.o differ
diff --git a/src/Djitellowhite/Hardwarelistener.h b/src/Djitellowhite/Hardwarelistener.h
new file mode 100644
index 0000000..599fa82
--- /dev/null
+++ b/src/Djitellowhite/Hardwarelistener.h
@@ -0,0 +1,6 @@
+#ifndef _HARDWARELISTENER_H
+#define _HARDWARELISTENER_H
+#include "Djitellowhite.h"
+int listenkeyboard(Tello T,sockaddr_in serveraddr);
+int scanKeyboard();
+#endif
diff --git a/src/Djitellowhite/Triplet.cpp b/src/Djitellowhite/Triplet.cpp
new file mode 100644
index 0000000..9c0ef65
--- /dev/null
+++ b/src/Djitellowhite/Triplet.cpp
@@ -0,0 +1,45 @@
+#include"Djitellowhite.h"
+#include"Hardwarelistener.h"
+#include
+using namespace std;
+int main(void){
+ Tello T("192.168.10.1");
+ int socket_fd, err;
+
+ if((socket_fd = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1)
+ {
+ cout << "initialized error" << endl;
+ cout << 0;
+ return -1;
+ }
+
+ //cout << 1 << socket_fd;
+ T.set_conf(socket_fd);
+
+ pthread_t thread_receive;
+ err = pthread_create(&thread_receive,nullptr,T.udp_response_receiver,&socket_fd);
+ sleep(3);
+ struct sockaddr_in serveraddr;
+ memset(&serveraddr,0,sizeof(serveraddr));
+ serveraddr.sin_family=AF_INET;
+ serveraddr.sin_addr.s_addr=T.gethost();
+ serveraddr.sin_port=htons(CONTROL_UDP_PORT);
+
+
+
+ if(err!=0)
+ {
+ cout << err << " " << "can't create thread";
+ }
+
+ T.get_connect(serveraddr);
+ //sleep(1);
+ //T.takeoff(serveraddr);
+ T.get_video(serveraddr);
+ sleep(5);
+ //T.land(serveraddr);
+
+ pthread_join(thread_receive,NULL);
+ listenkeyboard(T,serveraddr);
+ return 0;
+}
diff --git a/src/Djitellowhite/keyboard.cpp b/src/Djitellowhite/keyboard.cpp
new file mode 100644
index 0000000..dcf3ade
--- /dev/null
+++ b/src/Djitellowhite/keyboard.cpp
@@ -0,0 +1,57 @@
+#include
+#include
+#include "Hardwarelistener.h"
+#include
+
+using namespace std;
+int scanKeyboard()
+{
+
+ int in;
+
+ struct termios new_settings;
+ struct termios stored_settings;
+ //设置终端参数
+ tcgetattr(0,&stored_settings);
+ new_settings = stored_settings;
+ new_settings.c_lflag &= (~ICANON);
+ new_settings.c_cc[VTIME] = 0;
+ tcgetattr(0,&stored_settings);
+ new_settings.c_cc[VMIN] = 1;
+ tcsetattr(0,TCSANOW,&new_settings);
+ in = getchar();
+ tcsetattr(0,TCSANOW,&stored_settings);
+
+ return in;
+
+}
+
+//测试函数
+int listenkeyboard(Tello T, sockaddr_in serveraddr){
+ while(1){
+ switch(scanKeyboard())
+ {
+ case (int)'w':
+ cout << "forward"<< endl;
+ T.forward(serveraddr);
+ break;
+ case (int)'s':
+ cout << "back" << endl;
+ T.back(serveraddr);
+ break;
+ case (int)'a':
+ cout << "left" <
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#define PORT 8890
+
+void udp_server(int sockfd)
+{
+
+ socklen_t len;
+ char buf[1024] = {0};
+ struct sockaddr_in server_addr;
+ int n;
+ int opt = 1;
+ len = sizeof(server_addr);
+ memset(&buf, 0, sizeof(buf));
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ server_addr.sin_port = htons(PORT);
+
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //当服务器非正常断开的时候重启服务器,不会进入TIME_WAIT状态
+
+ if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
+ printf("can not bind\n");
+ exit(1);
+ }
+
+ while (1) {
+ printf("========wait for client's request========\n");
+ n = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&server_addr, &len);
+ buf[n] = '\0';
+ printf("receive client's data: %s\n", buf);
+ sendto(sockfd, buf, n, 0, (struct sockaddr *)&server_addr, len);
+ printf("send data to client: %s\n", buf);
+ }
+
+ close(sockfd);
+}
+
+int main(int argc, char **argv)
+{
+ int sockfd;
+
+ if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+ printf("create socket false\n");
+ exit(1);
+ }
+
+ udp_server(sockfd);
+
+ exit(0);
+}
+
+
diff --git a/src/Djitellowhite/test b/src/Djitellowhite/test
new file mode 100755
index 0000000..5becd75
Binary files /dev/null and b/src/Djitellowhite/test differ
diff --git a/src/include/dashboard.h b/src/include/dashboard.h
new file mode 100644
index 0000000..cf3d39a
--- /dev/null
+++ b/src/include/dashboard.h
@@ -0,0 +1,53 @@
+#ifndef DASHBOARD_H
+#define DASHBOARD_H
+
+#include
+
+class DashBoard : public QWidget {
+ Q_OBJECT
+ public:
+ enum Gear {
+ kGear_1 = 1,
+ kGear_2,
+ kGear_3,
+ kGear_4,
+ kGear_5,
+ kGear_6,
+ kGear_7,
+ kGear_8,
+ kGear_D,
+ kGear_N,
+ kGear_P,
+ kGear_R
+ };
+
+ public:
+ explicit DashBoard(QWidget* parent = nullptr);
+
+ public slots:
+ void set_gear(const Gear gear);
+ void set_rpm(const int rpm);
+ void set_speed(const int speed);
+ void set_temperature(const double temperature);
+ void set_oil(const int oil);
+
+ protected:
+ void paintEvent(QPaintEvent* event);
+
+ private:
+ void draw_tachometer(QPainter& painter); // 转速表
+ void draw_speedometer(QPainter& painter); // 迈速表
+ void draw_gear(QPainter& painter); // 挡位
+ void draw_thermometer(QPainter& painter); // 水箱温度计
+ void draw_oil_meter(QPainter& painter); // 油表
+
+ private:
+ Gear _gear{kGear_N};
+ int _rpm;
+ int _speed;
+ double _temperature;
+ int _oil;
+ QWidget* parent;
+};
+
+#endif // DASHBOARD_H
diff --git a/src/include/joystick.h b/src/include/joystick.h
new file mode 100644
index 0000000..26969d3
--- /dev/null
+++ b/src/include/joystick.h
@@ -0,0 +1,55 @@
+#ifndef JOYSTICK_H
+#define JOYSTICK_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+class JoyStick : public QWidget {
+ Q_OBJECT
+
+ public:
+ JoyStick(QWidget *parent = 0);
+ ~JoyStick();
+ enum {
+ upleft = 0,
+ up,
+ upright,
+ left,
+ stop,
+ right,
+ downleft,
+ down,
+ downright
+ };
+ signals:
+ void keyNumchanged(int num);
+
+ protected:
+ void paintEvent(QPaintEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ // void resizeEvent(QResizeEvent *event)override;
+ private:
+ int mouseX;
+ int mouseY;
+ int JoyStickX; //摇杆
+ int JoyStickY;
+ int JoyStickR;
+ int padX; //底盘
+ int padY;
+ int padR;
+ double handPadDis; //两圆圆心距离
+ bool mousePressed;
+ QTimer *tim;
+
+ private:
+ double Pointdis(int a, int b, int x, int y); //两点距离
+ int getKeyNum();
+};
+
+#endif // JoyStick_H
diff --git a/src/include/qnode.hpp b/src/include/qnode.hpp
new file mode 100644
index 0000000..9f99191
--- /dev/null
+++ b/src/include/qnode.hpp
@@ -0,0 +1,64 @@
+#ifndef Air_Ground_CEC_QNODE_HPP_
+#define Air_Ground_CEC_QNODE_HPP_
+
+#ifndef Q_MOC_RUN
+#include
+#endif
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+class QNode : public QThread{
+ Q_OBJECT
+
+public:
+ QNode(int argc, char **argv);
+ virtual ~QNode();
+ bool init();
+ void SubAndPubTopic();
+ void KeyboardMove(char key, float speed_linear, float speed_trun);
+
+Q_SIGNALS:
+ void speed_x(double x);
+ void speed_th(double th);
+ void power(float p);
+
+private:
+ int init_argc;
+ char **init_argv;
+ ros::Publisher chatter_publisher;
+ ros::Subscriber chatter_subscriber;
+ ros::Publisher cmd_pub;
+ ros::Subscriber cmdVel_sub;
+ ros::Subscriber power_sub;
+
+ QString odom_topic;
+ QString batteryState_topic;
+
+
+ void speedCallback(const nav_msgs::Odometry::ConstPtr& msg);
+ void powerCallback(const std_msgs::Float32& message_holder);
+ void myCallback(const std_msgs::Float64& message_holder);
+
+};
+
+#endif
+
diff --git a/src/main/dashboard.cpp b/src/main/dashboard.cpp
new file mode 100644
index 0000000..d5a6ed3
--- /dev/null
+++ b/src/main/dashboard.cpp
@@ -0,0 +1,384 @@
+#include "../include/dashboard.h"
+
+#include
+#include
+#include
+
+#include
+
+#include "QDebug"
+DashBoard::DashBoard(QWidget* parent)
+ : QWidget(parent),
+ _gear(kGear_1),
+ _rpm(0),
+ _speed(0),
+ _temperature(0),
+ _oil(0) {
+ QFontDatabase::addApplicationFont(":/fonts/DejaVuSans.ttf");
+ this->resize(parent->size());
+ this->parent = parent;
+}
+
+void DashBoard::set_gear(const DashBoard::Gear gear) {
+ _gear = gear;
+ update();
+}
+
+void DashBoard::set_rpm(const int rpm) {
+ _rpm = rpm;
+ update();
+}
+
+void DashBoard::set_speed(const int speed) {
+ _speed = speed;
+ _rpm = speed;
+ update();
+}
+
+void DashBoard::set_temperature(const double temperature) {
+ _temperature = temperature;
+ update();
+}
+
+void DashBoard::set_oil(const int oil) {
+ _oil = oil;
+ update();
+}
+
+void DashBoard::paintEvent(QPaintEvent* event) {
+ this->resize(parent->size());
+ QWidget::paintEvent(event);
+
+ int side = qMin(int(parent->width() / 1.8), parent->height());
+
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.translate(parent->width() / 2, parent->height() / 2);
+ painter.scale(side / 200.0, side / 200.0);
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(Qt::NoBrush);
+
+ draw_tachometer(painter);
+ draw_speedometer(painter);
+ draw_gear(painter);
+ draw_thermometer(painter);
+ draw_oil_meter(painter);
+}
+
+void DashBoard::draw_tachometer(QPainter& painter) {
+ static QColor normal_color(26, 245, 245, 245);
+ static QColor overrun_color(245, 64, 64, 225);
+
+ // 绘制表盘外檐
+ painter.save();
+ painter.setPen(QPen(normal_color, 1, Qt::SolidLine));
+ QRect rect(-95, -95, 190, 190);
+ painter.drawArc(rect, 0, 270 * 16);
+ painter.restore();
+
+ // 绘制红色区域
+ painter.save();
+ static QRectF rectangle_outer(-95, -95, 190, 190);
+ static QRectF rectangle_inner(-87, -87, 174, 174);
+ painter.setBrush(overrun_color);
+ QPainterPath path;
+ path.arcTo(rectangle_outer, 0.0, 108.0);
+ path.arcTo(rectangle_inner, 108, -108);
+ painter.drawPath(path);
+ painter.restore();
+
+ // 绘制大刻度
+ painter.save();
+ painter.setPen(QPen(normal_color, 1, Qt::SolidLine));
+ painter.rotate(90);
+ for (int i = 0; i < 21; ++i) {
+ painter.drawLine(88, 0, 94, 0);
+ painter.rotate(13.5);
+ }
+ painter.restore();
+
+ // 绘制小刻度
+ painter.save();
+ painter.setPen(QPen(normal_color, 1, Qt::SolidLine));
+ painter.rotate(90);
+ for (int i = 0; i < 100; ++i) {
+ painter.drawLine(91, 0, 94, 0);
+ painter.rotate(2.7);
+ }
+ painter.restore();
+
+ // 绘制表盘数字
+ painter.save();
+ painter.rotate(90);
+ painter.setPen(normal_color);
+ painter.setFont(QFont("Times", 14));
+ for (int i = 0; i < 11; ++i) {
+ painter.save();
+ if (i > 6) {
+ painter.setPen(overrun_color);
+ }
+ painter.rotate(27.0 * i);
+ painter.translate(76, 0);
+ painter.rotate(270 - 27.0 * i);
+ painter.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter,
+ QString::number(i));
+ painter.restore();
+ }
+ painter.restore();
+
+ // 绘制指针
+ static const QPoint hand[] = {QPoint(-4, 0), QPoint(0, 94), QPoint(4, 0),
+ QPoint(0, -6)};
+ static QColor hand_color(26, 245, 245, 176);
+ painter.save();
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(hand_color);
+ painter.rotate(27.0 * (_rpm / 10.0));
+ painter.drawConvexPolygon(hand, 4);
+ painter.restore();
+
+ // 绘制文字
+ painter.save();
+ painter.setPen(normal_color);
+ painter.setFont(QFont("DejaVu Sans", 8));
+ painter.drawText(QRect(-50, -70, 100, 50), Qt::AlignCenter, "×10");
+ painter.setFont(QFont("DejaVu Sans", 8, 50, true));
+ painter.drawText(QRect(-50, 34, 32, 16), Qt::AlignCenter, "CM/S");
+ painter.restore();
+}
+
+void DashBoard::draw_speedometer(QPainter& painter) {
+ painter.save();
+
+ painter.setPen(QColor(64, 64, 245));
+ painter.setFont(QFont("DejaVu Sans", 6, 50, true));
+ painter.drawText(QRect(80, 50, 70, 20), Qt::AlignCenter, "SPEED");
+
+ painter.setPen(QColor(26, 245, 245));
+ painter.setFont(QFont("DejaVu Sans", 24, 63, true));
+ painter.drawText(QRect(80, 50, 70, 50), Qt::AlignBottom | Qt::AlignLeft,
+ QString("%0").arg(QString::number(_speed), 3, '0'));
+
+ painter.setPen(QColor(26, 245, 245));
+ painter.setFont(QFont("DejaVu Sans", 8, 63, true));
+ painter.drawText(QRect(145, 75, 40, 20), Qt::AlignBottom | Qt::AlignLeft,
+ "cm/s");
+
+ painter.restore();
+}
+
+void DashBoard::draw_gear(QPainter& painter) {
+ static QRect gear_rect(0, 0, 80, 80);
+ static QRect suffix_rect(48, 48, 32, 32);
+ static QFont suffix_font("DejaVu Sans", 16, 63, true);
+
+ painter.save();
+ painter.setPen(QPen(QColor(26, 245, 245), 1, Qt::SolidLine));
+ painter.setFont(QFont("DejaVu Sans", 48, 63, true));
+
+ switch (_gear) {
+ case kGear_1:
+ painter.drawText(gear_rect, Qt::AlignCenter, QString::number(_gear));
+ painter.setFont(suffix_font);
+ painter.drawText(suffix_rect, Qt::AlignCenter, "st");
+ break;
+ case kGear_2:
+ painter.drawText(gear_rect, Qt::AlignCenter, QString::number(_gear));
+ painter.setFont(suffix_font);
+ painter.drawText(suffix_rect, Qt::AlignCenter, "nd");
+ break;
+ case kGear_3:
+ painter.drawText(gear_rect, Qt::AlignCenter, QString::number(_gear));
+ painter.setFont(suffix_font);
+ painter.drawText(suffix_rect, Qt::AlignCenter, "rd");
+ break;
+ case kGear_4:
+ case kGear_5:
+ case kGear_6:
+ case kGear_7:
+ case kGear_8:
+ painter.drawText(gear_rect, Qt::AlignCenter, QString::number(_gear));
+ painter.setFont(suffix_font);
+ painter.drawText(suffix_rect, Qt::AlignCenter, "th");
+ break;
+ case kGear_D:
+ painter.drawText(gear_rect, Qt::AlignCenter, "D");
+ break;
+ case kGear_N:
+ painter.drawText(gear_rect, Qt::AlignCenter, "N");
+ break;
+ case kGear_P:
+ painter.drawText(gear_rect, Qt::AlignCenter, "P");
+ break;
+ case kGear_R:
+ painter.drawText(gear_rect, Qt::AlignCenter, "R");
+ break;
+ default:
+ break;
+ }
+
+ painter.restore();
+}
+
+void DashBoard::draw_thermometer(QPainter& painter) {
+ painter.save();
+
+ painter.drawImage(QRect(115, -60, 8, 16),
+ QImage("://images/temperature-icon.png"));
+
+ painter.translate(-160, 100);
+
+ static QColor normal_color(26, 245, 245, 245);
+ static QColor overrun_color(245, 64, 64, 225);
+
+ // 绘制表盘外檐
+ painter.save();
+ painter.setPen(QPen(normal_color, 1, Qt::SolidLine));
+ QRect rect(-300, -300, 600, 600);
+ painter.drawArc(rect, 12 * 16, 20 * 16);
+ painter.restore();
+
+ // 绘制刻度
+ painter.save();
+ painter.setPen(QPen(normal_color, 1, Qt::SolidLine));
+ painter.rotate(-12);
+ painter.drawLine(300, 0, 306, 0);
+ painter.rotate(-10);
+ painter.drawLine(300, 0, 304, 0);
+ painter.rotate(-10);
+ painter.drawLine(300, 0, 306, 0);
+ painter.restore();
+
+ // 绘制刻度值
+ painter.save();
+ painter.setPen(normal_color);
+ painter.setFont(QFont("DejaVu Sans", 6));
+
+ painter.rotate(-12);
+ painter.save();
+ painter.translate(316, 0);
+ painter.rotate(12);
+ painter.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter,
+ QString::number(0) + "°C");
+ painter.restore();
+
+ painter.rotate(-10);
+ painter.save();
+ painter.translate(317, 0);
+ painter.rotate(22);
+ painter.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter,
+ QString::number(50) + "°C");
+ painter.restore();
+
+ painter.rotate(-10);
+ painter.save();
+ painter.translate(320, 0);
+ painter.rotate(32);
+ painter.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter,
+ QString::number(100) + "°C");
+ painter.restore();
+
+ painter.restore();
+
+ // 绘制红色区域
+ painter.save();
+ static QRectF rectangle_outer(-304, -304, 608, 608);
+ static QRectF rectangle_inner(-300.5, -300.5, 601, 601);
+ painter.setBrush(overrun_color);
+ QPainterPath path;
+ path.arcTo(rectangle_outer, 28, 3.9);
+ path.arcTo(rectangle_inner, 31.9, -3.9);
+ painter.drawPath(path);
+ painter.restore();
+
+ // 绘制指针
+ painter.save();
+ painter.setPen(QPen(overrun_color, 1, Qt::SolidLine));
+ painter.rotate(-12 - 0.2 * _temperature);
+ painter.drawLine(298, 0, 306, 0);
+ painter.restore();
+
+ painter.restore();
+}
+
+void DashBoard::draw_oil_meter(QPainter& painter) {
+ painter.save();
+
+ painter.drawImage(QRect(-130, -60, 16, 16),
+ QImage("://images/fuel-icon.png"));
+
+ painter.translate(160, 100);
+ painter.rotate(180);
+
+ static QColor normal_color(26, 245, 245, 245);
+ static QColor overrun_color(245, 64, 64, 225);
+
+ // 绘制表盘外檐
+ painter.save();
+ painter.setPen(QPen(normal_color, 1, Qt::SolidLine));
+ QRect rect(-300, -300, 600, 600);
+ painter.drawArc(rect, -12 * 16, -20 * 16);
+ painter.restore();
+
+ // 绘制刻度
+ painter.save();
+ painter.setPen(QPen(normal_color, 1, Qt::SolidLine));
+ painter.rotate(12);
+ painter.drawLine(300, 0, 306, 0);
+ painter.rotate(10);
+ painter.drawLine(300, 0, 304, 0);
+ painter.rotate(10);
+ painter.drawLine(300, 0, 306, 0);
+ painter.restore();
+
+ // 绘制刻度值
+ painter.save();
+ painter.setPen(normal_color);
+ painter.setFont(QFont("DejaVu Sans", 6));
+
+ painter.rotate(12);
+ painter.save();
+ painter.translate(316, 0);
+ painter.rotate(168);
+ painter.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter,
+ QString::number(0) + "%");
+ painter.restore();
+
+ painter.rotate(10);
+ painter.save();
+ painter.translate(317, 0);
+ painter.rotate(158);
+ painter.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter,
+ QString::number(50) + "%");
+ painter.restore();
+
+ painter.rotate(10);
+ painter.save();
+ painter.translate(320, 0);
+ painter.rotate(148);
+ painter.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter,
+ QString::number(100) + "%");
+ painter.restore();
+
+ painter.restore();
+
+ // 绘制红色区域
+ painter.save();
+ static QRectF rectangle_outer(-304, -304, 608, 608);
+ static QRectF rectangle_inner(-300.5, -300.5, 601, 601);
+ painter.setBrush(overrun_color);
+ QPainterPath path;
+ path.arcTo(rectangle_outer, -12.1, -3.9);
+ path.arcTo(rectangle_inner, -16, 3.9);
+ painter.drawPath(path);
+ painter.restore();
+
+ // 绘制指针
+ painter.save();
+ painter.setPen(QPen(overrun_color, 1, Qt::SolidLine));
+ painter.rotate(12 + 0.2 * _oil);
+ painter.drawLine(298, 0, 306, 0);
+ painter.restore();
+
+ painter.restore();
+}
diff --git a/src/main/joystick.cpp b/src/main/joystick.cpp
new file mode 100644
index 0000000..8d6eb41
--- /dev/null
+++ b/src/main/joystick.cpp
@@ -0,0 +1,105 @@
+#include "../include/joystick.h"
+
+#include
+JoyStick::JoyStick(QWidget* parent) : QWidget(parent) {
+ setPalette(QPalette(Qt::white));
+ resize(parent->width(), parent->height());
+ setMinimumSize(100, 100);
+ mouseX = width() / 2;
+ mouseY = height() / 2;
+ tim = new QTimer(this);
+ connect(tim, &QTimer::timeout, this,
+ [=] { emit keyNumchanged(getKeyNum()); });
+ // connect(this,&JoyStick::keyNumchanged,this,[=](int num){
+ // qDebug()<pos().x();
+ mouseY = event->pos().y();
+ if (r == true) {
+ update();
+ r = false;
+ } else {
+ r = true;
+ }
+}
+void JoyStick::mouseReleaseEvent(QMouseEvent* event) {
+ mouseX = width() / 2;
+ mouseY = height() / 2;
+ tim->stop();
+ mousePressed = false;
+ emit keyNumchanged(JoyStick::stop);
+ update();
+}
+void JoyStick::mousePressEvent(QMouseEvent* event) {
+ mouseX = event->pos().x();
+ mouseY = event->pos().y();
+ tim->start(100);
+ mousePressed = true;
+ update();
+}
+
+double JoyStick::Pointdis(int a, int b, int x, int y) {
+ return sqrt((double)((x - a) * (x - a) + (y - b) * (y - b)));
+}
+int JoyStick::getKeyNum() {
+ int x, y;
+ int keynum;
+ x = (int)(JoyStickX * 3.0 / (padR * 2));
+ y = (int)(JoyStickY * 3.0 / (padR * 2));
+ keynum = 3 * y + x;
+ return keynum;
+}
diff --git a/src/main/main.cpp b/src/main/main.cpp
new file mode 100644
index 0000000..e31bc33
--- /dev/null
+++ b/src/main/main.cpp
@@ -0,0 +1,27 @@
+
+#include "../ui/mainwindow.hpp"
+
+#include
+
+#include
+
+
+
+int main(int argc, char** argv)
+{
+
+
+ QApplication app(argc, argv);
+ MainWindow CEC(0,0,0);
+
+ CEC.show();
+ return app.exec();
+
+ return(0);
+}
+
+
+
+/*
+ * find . "(" -name "*.cpp" -or -name "*.h" -or -name "*.hpp" -or -name "*.qrc" ")" -print | xargs wc -l
+ */
diff --git a/src/main/mainwindow.cpp b/src/main/mainwindow.cpp
new file mode 100644
index 0000000..a7c0447
--- /dev/null
+++ b/src/main/mainwindow.cpp
@@ -0,0 +1,325 @@
+#include "../ui/mainwindow.hpp"
+
+
+
+MainWindow::MainWindow(int argc, char **argv, QWidget *parent) :
+ QMainWindow(parent), qnode(argc, argv),
+ ui(new Ui::MainWindow)
+
+{
+ qnode.init();
+ ui->setupUi(this);
+ initUis();
+ connections();
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+
+void MainWindow::initUis(){
+ setBtnStyles();
+
+
+ /*
+ * init
+ */
+
+ rock_widget = new JoyStick(ui->JoyStick_widget);
+ rock_widget->show();
+
+
+ m_DashBoard_x = new DashBoard(ui->widget_speed_x);
+ m_DashBoard_x->setGeometry(ui->widget_speed_x->rect());
+
+ m_DashBoard_th = new DashBoard(ui->widget_speed_th);
+ m_DashBoard_th->setGeometry(ui->widget_speed_th->rect());
+
+
+}
+
+
+void MainWindow::setBtnStyles(){
+ /*
+ * set PushButton state
+ */
+
+ ui->btn_main->setIcon(QIcon("://images/up.png"));
+ ui->btn_main->setText("mainWidget");
+ ui->btn_main->setStyleSheet(
+ "QPushButton:hover{"
+ "background-color:rgb(186, 189, 182);"
+ "border-bottom:2px solid rgb(67, 154, 246);}"
+ "QPushButton:checked{"
+ "background-color:cyan;"
+ "border-bottom:2px solid white}"
+ "QPushButton:pressed{"
+ "background-color:rgb(67, 154, 246)}"
+ "QPushButton{"
+ "background-color:rgb(238, 238, 236);"
+ "border:none;"
+ "padding:0px 0px 0px 0px;"
+ "margin:0px 0px 0px 0px;}");
+
+ ui->btn_uav->setStyleSheet(
+ "QPushButton:hover{"
+ "background-color:rgb(186, 189, 182);"
+ "border-bottom:2px solid rgb(67, 154, 246);}"
+ "QPushButton:checked{"
+ "background-color:cyan;"
+ "border-bottom:2px solid white}"
+ "QPushButton:pressed{"
+ "background-color:rgb(67, 154, 246)}"
+ "QPushButton{"
+ "background-color:rgb(238, 238, 236);"
+ "border:none;"
+ "padding:0px 0px 0px 0px;"
+ "margin:0px 0px 0px 0px;}");
+
+ ui->btn_ugv->setStyleSheet(
+ "QPushButton:hover{"
+ "background-color:rgb(186, 189, 182);"
+ "border-bottom:2px solid rgb(67, 154, 246);}"
+ "QPushButton:checked{"
+ "background-color:cyan;"
+ "border-bottom:2px solid white}"
+ "QPushButton:pressed{"
+ "background-color:rgb(67, 154, 246)}"
+ "QPushButton{"
+ "background-color:rgb(238, 238, 236);"
+ "border:none;"
+ "padding:0px 0px 0px 0px;"
+ "margin:0px 0px 0px 0px;}");
+
+ // 8 -> Forward: ↑
+ ui->pushButton_Forward->setShortcut(Qt::Key_8);
+ ui->pushButton_Forward->setStyleSheet(
+ "QPushButton{border-image: url(://images/up.png)}"
+ "QPushButton{border:none}"
+ "QPushButton:pressed{border-image: url(://images/up_2.png)}");
+ ui->pushButton_Forward->setFlat(true);
+
+ // 2 -> Back: ↓
+ ui->pushButton_Back->setShortcut(Qt::Key_2);
+ ui->pushButton_Back->setStyleSheet(
+ "QPushButton{border-image: url(://images/down.png)}"
+ "QPushButton{border:none}"
+ "QPushButton:pressed{border-image: url(://images/down_2.png)}");
+ ui->pushButton_Back->setFlat(true);
+
+ // 4 -> Left: ←
+ ui->pushButton_Left->setShortcut(Qt::Key_4);
+ ui->pushButton_Left->setStyleSheet(
+ "QPushButton{border-image: url(://images/left.png)}"
+ "QPushButton{border:none}"
+ "QPushButton:pressed{border-image: url(://images/left_2.png)}");
+ ui->pushButton_Left->setFlat(true);
+
+ // 6 -> Right: →
+ ui->pushButton_Right->setShortcut(Qt::Key_6);
+ ui->pushButton_Right->setStyleSheet(
+ "QPushButton{border-image: url(://images/right.png)}"
+ "QPushButton{border:none}"
+ "QPushButton:pressed{border-image: url(://images/right_2.png)}");
+ ui->pushButton_Right->setFlat(true);
+
+ // 7 -> Left_Forward: ↖
+ ui->pushButton_Left_Forward->setShortcut(Qt::Key_7);
+ ui->pushButton_Left_Forward->setStyleSheet(
+ "QPushButton{border-image: url(://images/up_left.png)}"
+ "QPushButton{border:none}"
+ "QPushButton:pressed{border-image: url(://images/up_left_2.png)}");
+ ui->pushButton_Left_Forward->setFlat(true);
+
+ // 9 -> Right_Forward: ↗
+ ui->pushButton_Right_Forward->setShortcut(Qt::Key_9);
+ ui->pushButton_Right_Forward->setStyleSheet(
+ "QPushButton{border-image: url(://images/up_right.png)}"
+ "QPushButton{border:none}"
+ "QPushButton:pressed{border-image: url(://images/up_right_2.png)}");
+ ui->pushButton_Right_Forward->setFlat(true);
+
+ // 1 -> Left_Back: ↙
+ ui->pushButton_Left_Back->setShortcut(Qt::Key_1);
+ ui->pushButton_Left_Back->setStyleSheet(
+ "QPushButton{border-image: url(://images/down_left.png)}"
+ "QPushButton{border:none}"
+ "QPushButton:pressed{border-image: url(://images/down_left_2.png)}");
+ ui->pushButton_Left_Back->setFlat(true);
+
+ // 3 -> Right_Back: ↘
+ ui->pushButton_Right_Back->setShortcut(Qt::Key_3);
+ ui->pushButton_Right_Back->setStyleSheet(
+ "QPushButton{border-image: url(://images/down_right.png)}"
+ "QPushButton{border:none}"
+ "QPushButton:pressed{border-image: url(://images/down_right_2.png)}");
+ ui->pushButton_Right_Back->setFlat(true);
+
+}
+
+
+void MainWindow::slot_keyboard_control(){
+ QPushButton *btn = qobject_cast(sender());
+ std::string btn_name = btn->text().toStdString();
+ char key = ' ';
+
+ if (btn_name == "↙")
+ key = '1';
+ else if (btn_name == "↓")
+ key = '2';
+ else if (btn_name == "↘")
+ key = '3';
+ else if (btn_name == "←")
+ key = '4';
+ //else if (btn_name == "")
+ // key = '5';
+ else if (btn_name == "→")
+ key = '6';
+ else if (btn_name == "↖")
+ key = '7';
+ else if (btn_name == "↑")
+ key = '8';
+ else if (btn_name == "↗")
+ key = '9';
+
+ //速度
+ float liner = ui->horizontalSlider_linear->value() * 0.01;
+ float turn = ui->horizontalSlider_raw->value() * 0.01;
+ //bool is_rage_mode = ui->checkBox_rage_mode->isChecked();
+ //std::cout<horizontalSlider_linear->value() * 0.01;
+ float turn = ui->horizontalSlider_raw->value() * 0.01;
+ switch (key) {
+ case upleft:
+ qnode.KeyboardMove('7', liner, turn);
+ break;
+ case up:
+ qnode.KeyboardMove('8', liner, turn);
+ break;
+ case upright:
+ qnode.KeyboardMove('9', liner, turn);
+ break;
+ case left:
+ qnode.KeyboardMove('4', liner, turn);
+ break;
+ case right:
+ qnode.KeyboardMove('6', liner, turn);
+ break;
+ case downleft:
+ qnode.KeyboardMove('1', liner, turn);
+ break;
+ case down:
+ qnode.KeyboardMove('2', liner, turn);
+ break;
+ case downright:
+ qnode.KeyboardMove('3', liner, turn);
+ break;
+ }
+
+}
+
+void MainWindow::connections(){
+ QObject::connect(ui->btn_main, &QPushButton::clicked, this, [=](){
+ ui->stackedWidget_main->setCurrentIndex(0);
+ });
+ QObject::connect(ui->btn_uav, &QPushButton::clicked, this, [=](){
+ ui->stackedWidget_main->setCurrentIndex(1);
+ });
+ QObject::connect(ui->btn_ugv, &QPushButton::clicked, this, [=](){
+ ui->stackedWidget_main->setCurrentIndex(2);
+ });
+
+ QObject::connect(ui->btn_system, &QPushButton::clicked, this, [=](){
+ ui->stackedWidget_ros_control->setCurrentIndex(1);
+ });
+ QObject::connect(ui->btn_keyboard, &QPushButton::clicked, this, [=](){
+ ui->stackedWidget_ros_control->setCurrentIndex(0);
+ });
+
+ /*
+ * 绑定速度控制按钮
+ */
+
+ // 8 -> Forward: ↑
+ connect(ui->pushButton_Forward, SIGNAL(clicked()), this, SLOT(slot_keyboard_control()));
+ // 2 -> Back: ↓
+ connect(ui->pushButton_Back, SIGNAL(clicked()), this, SLOT(slot_keyboard_control()));
+ // 4 -> Left: ←
+ connect(ui->pushButton_Left, SIGNAL(clicked()), this, SLOT(slot_keyboard_control()));
+ // 6 -> Right: →
+ connect(ui->pushButton_Right, SIGNAL(clicked()), this, SLOT(slot_keyboard_control()));
+ // 7 -> Left_Forward: ↖
+ connect(ui->pushButton_Left_Forward, SIGNAL(clicked()), this, SLOT(slot_keyboard_control()));
+ // 9 -> Right_Forward: ↗
+ connect(ui->pushButton_Right_Forward, SIGNAL(clicked()), this, SLOT(slot_keyboard_control()));
+ // 1 -> Left_Back: ↙
+ connect(ui->pushButton_Left_Back, SIGNAL(clicked()), this, SLOT(slot_keyboard_control()));
+ // 3 -> Right_Back: ↘
+ connect(ui->pushButton_Right_Back, SIGNAL(clicked()), this, SLOT(slot_keyboard_control()));
+
+ connect(rock_widget, SIGNAL(keyNumchanged(int)), this,
+ SLOT(slot_rockKeyChange(int)));
+
+ //绑定slider的函数
+ connect(ui->horizontalSlider_raw, SIGNAL(valueChanged(int)), this,
+ SLOT(Slider_raw_valueChanged(int)));
+ connect(ui->horizontalSlider_linear, SIGNAL(valueChanged(int)), this,
+ SLOT(Slider_linear_valueChanged(int)));
+
+ connect(&qnode, SIGNAL(speed_x(double)), this, SLOT(slot_speed_x(double)));
+ connect(&qnode, SIGNAL(speed_th(double)), this, SLOT(slot_speed_th(double)));
+}
+
+
+void MainWindow::slot_speed_x(double x) {
+ m_DashBoard_x->set_speed(abs(x * 100));
+ if (x > 0.001) {
+ m_DashBoard_x->set_gear(DashBoard::kGear_D);
+ } else if (x < -0.001) {
+ m_DashBoard_x->set_gear(DashBoard::kGear_R);
+ } else {
+ m_DashBoard_x->set_gear(DashBoard::kGear_N);
+ }
+ QString number = QString::number(abs(x * 100)).mid(0, 2);
+ if (number[1] == ".") {
+ number = number.mid(0, 1);
+ }
+ //ui.label_speed->setText(number);
+}
+
+
+void MainWindow::slot_speed_th(double th){
+ m_DashBoard_th->set_speed(abs(th * 100));
+ if (th > 0.001) {
+ m_DashBoard_x->set_gear(DashBoard::kGear_D);
+ } else if (th < -0.001) {
+ m_DashBoard_x->set_gear(DashBoard::kGear_R);
+ } else {
+ m_DashBoard_x->set_gear(DashBoard::kGear_N);
+ }
+ QString number = QString::number(abs(th * 100)).mid(0, 2);
+ if (number[1] == ".") {
+ number = number.mid(0, 1);
+ }
+}
+
+
+//滑动条处理槽函数
+void MainWindow::Slider_raw_valueChanged(int v) {
+ ui->label_raw->setText(QString::number(v));
+}
+//滑动条处理槽函数
+void MainWindow::Slider_linear_valueChanged(int v) {
+ ui->label_linear->setText(QString::number(v));
+}
+
+
diff --git a/src/main/qnode.cpp b/src/main/qnode.cpp
new file mode 100644
index 0000000..0ee8df5
--- /dev/null
+++ b/src/main/qnode.cpp
@@ -0,0 +1,78 @@
+#include "../include/qnode.hpp"
+
+#include "sensor_msgs/image_encodings.h"
+
+QNode::QNode(int argc, char **argv) : init_argc(argc), init_argv(argv){
+
+
+
+}
+
+
+QNode::~QNode() {
+ if (ros::isStarted()) {
+ ros::shutdown(); // explicitly needed since we use ros::start();
+ ros::waitForShutdown();
+ }
+ wait();
+}
+
+bool QNode::init() {
+ QSettings topic_setting("ros_controller", "settings");
+ odom_topic = topic_setting.value("topic/topic_odom", "odom").toString();
+ batteryState_topic =
+ topic_setting.value("topic/topic_power", "battery_state").toString();
+ ros::init(init_argc,init_argv,"Air_Ground_CEC",
+ ros::init_options::AnonymousName | ros::init_options::NoSigintHandler);
+ SubAndPubTopic();
+ return true;
+}
+
+void QNode::SubAndPubTopic(){
+ ros::NodeHandle n;
+ //创建速度话题的订阅者
+ cmdVel_sub = n.subscribe(odom_topic.toStdString(), 200,
+ &QNode::speedCallback, this);
+ //power_sub = n.subscribe(batteryState_topic.toStdString(), 1000,
+ // &QNode::powerCallback, this);
+ cmd_pub = n.advertise("cmd_vel", 1);
+}
+
+void QNode::KeyboardMove(char key, float speed_linear, float speed_trun){
+ std::map> moveBindings {
+ // {'key', {x, y, z, th}}
+ {'7', {1, 1, 0, 1}}, {'8', {1, 0, 0, 0}}, {'9', {1, -1, 0, -1}},
+ {'4', {0, 0, 0, 1}}, {'5', {0, 0, 0, 0}}, {'6', {0, 0, 0, -1}},
+ {'1', {-1, 1, 0, 1}}, {'2', {-1, 0, 0, 0}}, {'3', {-1, -1, 0, -1}}
+ };
+
+ float x = moveBindings[key][0];
+ float y = moveBindings[key][1];
+ float z = moveBindings[key][2];
+ float th = moveBindings[key][3];
+
+ //计算线速度和角速度
+ float speed = speed_linear;
+ float turn = speed_trun;
+
+
+
+ geometry_msgs::Twist twist;
+ twist.linear.x = x * speed;
+ twist.linear.y = y * speed;
+ twist.linear.z = z * speed;
+
+ twist.angular.x = 0;
+ twist.angular.y = 0;
+ twist.angular.z = th * turn;
+
+ cmd_pub.publish(twist);
+ ros::spinOnce();
+}
+
+//速度回调函数
+void QNode::speedCallback(const nav_msgs::Odometry::ConstPtr& msg)
+{
+ emit speed_x(msg->twist.twist.linear.x);
+ emit speed_th(msg->twist.twist.angular.z);
+}
diff --git a/src/resources/images.qrc b/src/resources/images.qrc
new file mode 100644
index 0000000..5b4cff0
--- /dev/null
+++ b/src/resources/images.qrc
@@ -0,0 +1,20 @@
+
+
+ images/down.png
+ images/down_2.png
+ images/down_left.png
+ images/down_left_2.png
+ images/down_right.png
+ images/down_right_2.png
+ images/left.png
+ images/left_2.png
+ images/right.png
+ images/right_2.png
+ images/up.png
+ images/up_2.png
+ images/up_left.png
+ images/up_left_2.png
+ images/up_right.png
+ images/up_right_2.png
+
+
diff --git a/src/resources/images/down.png b/src/resources/images/down.png
new file mode 100644
index 0000000..1fdba49
Binary files /dev/null and b/src/resources/images/down.png differ
diff --git a/src/resources/images/down_2.png b/src/resources/images/down_2.png
new file mode 100644
index 0000000..b0f2433
Binary files /dev/null and b/src/resources/images/down_2.png differ
diff --git a/src/resources/images/down_left.png b/src/resources/images/down_left.png
new file mode 100644
index 0000000..d29e9dc
Binary files /dev/null and b/src/resources/images/down_left.png differ
diff --git a/src/resources/images/down_left_2.png b/src/resources/images/down_left_2.png
new file mode 100644
index 0000000..dd21fc2
Binary files /dev/null and b/src/resources/images/down_left_2.png differ
diff --git a/src/resources/images/down_right.png b/src/resources/images/down_right.png
new file mode 100644
index 0000000..f65187d
Binary files /dev/null and b/src/resources/images/down_right.png differ
diff --git a/src/resources/images/down_right_2.png b/src/resources/images/down_right_2.png
new file mode 100644
index 0000000..408b905
Binary files /dev/null and b/src/resources/images/down_right_2.png differ
diff --git a/src/resources/images/left.png b/src/resources/images/left.png
new file mode 100644
index 0000000..2b60f08
Binary files /dev/null and b/src/resources/images/left.png differ
diff --git a/src/resources/images/left_2.png b/src/resources/images/left_2.png
new file mode 100644
index 0000000..26ea2cc
Binary files /dev/null and b/src/resources/images/left_2.png differ
diff --git a/src/resources/images/right.png b/src/resources/images/right.png
new file mode 100644
index 0000000..0a6ca1d
Binary files /dev/null and b/src/resources/images/right.png differ
diff --git a/src/resources/images/right_2.png b/src/resources/images/right_2.png
new file mode 100644
index 0000000..581bbe8
Binary files /dev/null and b/src/resources/images/right_2.png differ
diff --git a/src/resources/images/up.png b/src/resources/images/up.png
new file mode 100644
index 0000000..5a5717f
Binary files /dev/null and b/src/resources/images/up.png differ
diff --git a/src/resources/images/up_2.png b/src/resources/images/up_2.png
new file mode 100644
index 0000000..200be6e
Binary files /dev/null and b/src/resources/images/up_2.png differ
diff --git a/src/resources/images/up_left.png b/src/resources/images/up_left.png
new file mode 100644
index 0000000..53d47cb
Binary files /dev/null and b/src/resources/images/up_left.png differ
diff --git a/src/resources/images/up_left_2.png b/src/resources/images/up_left_2.png
new file mode 100644
index 0000000..b8824ba
Binary files /dev/null and b/src/resources/images/up_left_2.png differ
diff --git a/src/resources/images/up_right.png b/src/resources/images/up_right.png
new file mode 100644
index 0000000..21c37f5
Binary files /dev/null and b/src/resources/images/up_right.png differ
diff --git a/src/resources/images/up_right_2.png b/src/resources/images/up_right_2.png
new file mode 100644
index 0000000..1fa93ac
Binary files /dev/null and b/src/resources/images/up_right_2.png differ
diff --git a/src/ui/Triplet/.gitignore b/src/ui/Triplet/.gitignore
new file mode 100644
index 0000000..fab7372
--- /dev/null
+++ b/src/ui/Triplet/.gitignore
@@ -0,0 +1,73 @@
+# This file is used to ignore files which are generated
+# ----------------------------------------------------------------------------
+
+*~
+*.autosave
+*.a
+*.core
+*.moc
+*.o
+*.obj
+*.orig
+*.rej
+*.so
+*.so.*
+*_pch.h.cpp
+*_resource.rc
+*.qm
+.#*
+*.*#
+core
+!core/
+tags
+.DS_Store
+.directory
+*.debug
+Makefile*
+*.prl
+*.app
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+Thumbs.db
+*.res
+*.rc
+/.qmake.cache
+/.qmake.stash
+
+# qtcreator generated files
+*.pro.user*
+
+# xemacs temporary files
+*.flc
+
+# Vim temporary files
+.*.swp
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.sdf
+*.opensdf
+*.vcxproj
+*vcxproj.*
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# Python byte code
+*.pyc
+
+# Binaries
+# --------
+*.dll
+*.exe
+
diff --git a/src/ui/Triplet/Triplet.pro b/src/ui/Triplet/Triplet.pro
new file mode 100644
index 0000000..06138d8
--- /dev/null
+++ b/src/ui/Triplet/Triplet.pro
@@ -0,0 +1,38 @@
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++11
+
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp
+
+HEADERS += \
+ mainwindow.h
+
+FORMS += \
+ mainwindow.ui
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+INCLUDEPATH += /usr/local/include \
+/usr/local/include/opencv2 \
+/usr/local/include/opencv4
+
+
+LIBS += /usr/local/lib/libopencv_world.so
diff --git a/src/ui/Triplet/main.cpp b/src/ui/Triplet/main.cpp
new file mode 100644
index 0000000..fd3e533
--- /dev/null
+++ b/src/ui/Triplet/main.cpp
@@ -0,0 +1,11 @@
+#include "mainwindow.h"
+
+#include
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+ return a.exec();
+}
diff --git a/src/ui/Triplet/mainwindow.cpp b/src/ui/Triplet/mainwindow.cpp
new file mode 100644
index 0000000..5a195f4
--- /dev/null
+++ b/src/ui/Triplet/mainwindow.cpp
@@ -0,0 +1,45 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ , ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+ timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(importFrame()));
+
+ //InitVideo();
+}
+
+void MainWindow::importFrame()
+{
+ capture >> frame;
+ cvtColor(frame, frame, CV_BGR2RGB);
+ QImage srcQImage = QImage((uchar*)(frame.data), frame.cols, frame.rows, QImage::Format_RGB888);
+ ui->label->setPixmap(QPixmap::fromImage(srcQImage));
+ ui->label->resize(srcQImage.size());
+ ui->label->show();
+}
+
+
+
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+
+
+void MainWindow::on_PLAY_clicked()
+{
+ capture.open("udp://@0.0.0.0:11111");
+ timer->start(30);
+}
+
+void MainWindow::on_CLOSE_clicked()
+{
+ timer->stop();
+ capture.release();
+}
diff --git a/src/ui/Triplet/mainwindow.h b/src/ui/Triplet/mainwindow.h
new file mode 100644
index 0000000..b959c59
--- /dev/null
+++ b/src/ui/Triplet/mainwindow.h
@@ -0,0 +1,47 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+#include
+#include
+#include "opencv2/opencv.hpp"
+#include
+#include
+#include
+#include
+
+using namespace std;
+using namespace cv;
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class MainWindow; }
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = nullptr);
+ ~MainWindow();
+ VideoCapture cap;
+ void InitVideo();
+
+
+private slots:
+
+
+ void importFrame();//read video
+
+ void on_PLAY_clicked();//start video
+
+ void on_CLOSE_clicked();//finish video
+
+private:
+ Ui::MainWindow *ui;
+ VideoCapture capture;
+ QTimer *timer;
+ Mat frame;
+ bool isCamerea = 0;
+};
+#endif // MAINWINDOW_H
diff --git a/src/ui/Triplet/mainwindow.ui b/src/ui/Triplet/mainwindow.ui
new file mode 100644
index 0000000..96a2ec2
--- /dev/null
+++ b/src/ui/Triplet/mainwindow.ui
@@ -0,0 +1,71 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 1280
+ 768
+
+
+
+ MainWindow
+
+
+
+
+
+ 1100
+ 440
+ 80
+ 25
+
+
+
+ CLOSE
+
+
+
+
+
+ 1100
+ 250
+ 80
+ 25
+
+
+
+ PLAY
+
+
+
+
+
+ 50
+ 30
+ 731
+ 461
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ui/mainwindow.hpp b/src/ui/mainwindow.hpp
new file mode 100644
index 0000000..3a50f5e
--- /dev/null
+++ b/src/ui/mainwindow.hpp
@@ -0,0 +1,64 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+#include
+#include
+
+#include "ui_mainwindow.h"
+#include "../include/joystick.h"
+#include "../include/qnode.hpp"
+#include "../include/dashboard.h"
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(int argc, char **argv, QWidget *parent = 0);
+ ~MainWindow();
+ enum {
+ upleft = 0,
+ up,
+ upright,
+ left,
+ stop,
+ right,
+ downleft,
+ down,
+ downright
+ };
+
+
+
+public slots:
+ void slot_keyboard_control();
+ //void slot_command_control(int linear, int angular);
+ void slot_rockKeyChange(int);
+ void slot_speed_x(double x);
+ void slot_speed_th(double th);
+ void Slider_raw_valueChanged(int v);
+ void Slider_linear_valueChanged(int v);
+
+
+
+private:
+ Ui::MainWindow *ui;
+ QNode qnode;
+ JoyStick *rock_widget;
+ DashBoard *m_DashBoard_x;
+ DashBoard *m_DashBoard_th;
+
+ void initUis();
+ void setBtnStyles();
+ void connections();
+
+
+
+};
+
+#endif // MAINWINDOW_H
diff --git a/src/ui/mainwindow.ui b/src/ui/mainwindow.ui
new file mode 100644
index 0000000..4ff96fa
--- /dev/null
+++ b/src/ui/mainwindow.ui
@@ -0,0 +1,886 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 1440
+ 810
+
+
+
+ MainWindow
+
+
+
+
+
+
+ -
+
+
+ 2
+
+
+
+
+
+ 780
+ 200
+ 311
+ 151
+
+
+
+ Main Widget
+
+
+
+
+
+
+
+ 680
+ 290
+ 271
+ 121
+
+
+
+ UAV Widget
+
+
+
+
+
+
+
+ 1000
+ 30
+ 407
+ 680
+
+
+
+
-
+
+
+ 1
+
+
+
+
-
+
+
-
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Preferred
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
-
+
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 15
+
+
+
+ ↖
+
+
+
+ -
+
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 15
+
+
+
+ QPushButton{border-image: url(://images/up.png);}
+
+
+ ↑
+
+
+
+ -
+
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 15
+
+
+
+ ↗
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 15
+
+
+
+ ←
+
+
+
+ -
+
+
+
+ 90
+ 64
+
+
+
+
+ 90
+ 64
+
+
+
+ 全向模式(k)
+
+
+ K
+
+
+
+ -
+
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 15
+
+
+
+
+
+
+ →
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 15
+
+
+
+ ↙
+
+
+
+ -
+
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 15
+
+
+
+ QPushButton{border-image: url(://images/down.png);}
+QPushButton{border:none;}
+QPushButton:pressed{border-image: url(://images/down_2.png);}
+
+
+ ↓
+
+
+
+ -
+
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 15
+
+
+
+ ↘
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 30
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
-
+
+
+ 线速度(cm/s):
+
+
+
+ -
+
+
+ 100
+
+
+ 1
+
+
+ 50
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ 50
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+ 角速度(cm/s):
+
+
+
+ -
+
+
+ 100
+
+
+ 100
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ 100
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 30
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 200
+ 200
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 385
+ 21
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 221
+
+
+
+ TextLabel
+
+
+
+ -
+
+
+
+ 300
+ 0
+
+
+
+
+ 12312312
+ 12312312
+
+
+
+ QListView{
+border-top: 5px solid qlineargradient(y0:0, y1:1,stop: 0 #ececef, stop: 1 white);
+border-left: 5px solid qlineargradient(x0:0, x1:1,stop: 0 #ececef, stop: 1 white);
+ border-bottom: 5px solid qlineargradient(y0:0, y1:1,stop: 0 white, stop: 1 #ececef);
+border-right: 5px solid qlineargradient(x0:0, x1:1,stop: 0 white, stop: 1 #ececef);
+background-color: rgb(255,255,255);
+}
+
+
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 45
+
+
+
+ system
+
+
+
+ -
+
+
+
+ 0
+ 45
+
+
+
+ keyboard
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 20
+
+
+
+
+
+
+
+
+
+
+
+ 240
+ 380
+ 302
+ 300
+
+
+
+
+ 300
+ 300
+
+
+
+
+
+
+
+
+
+ 580
+ 380
+ 302
+ 300
+
+
+
+
+ 300
+ 300
+
+
+
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 60
+
+
+
+
+
+
+
+
+
+
+ 32
+ 32
+
+
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+
+
+
+
+
+
+
+ 32
+ 32
+
+
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+ ArrowCursor
+
+
+
+
+
+
+
+
+
+ ../../../../../catkin_ws/src/Ros_Qt5_Gui_App/ui../../../../../catkin_ws/src/Ros_Qt5_Gui_App/ui
+
+
+
+ 32
+ 32
+
+
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+ PointingHandCursor
+
+
+ QPushButton:hover{
+background-color:rgb(186, 189, 182);
+border-bottom:2px solid rgb(67, 154, 246);
+}
+QPushButton:checked{
+background-color:cyan;
+border-bottom:2px solid white
+}
+QPushButton:pressed{
+background-color:rgb(67, 154, 246)
+}
+QPushButton{
+background-color:rgb(238, 238, 236);
+border:none;
+padding:0px 0px 0px 0px;
+margin:0px 0px 0px 0px;
+}
+
+
+
+
+
+
+ ../../../../../catkin_ws/src/Ros_Qt5_Gui_App/ui../../../../../catkin_ws/src/Ros_Qt5_Gui_App/ui
+
+
+
+ 32
+ 32
+
+
+
+
+ -
+
+
+
+ 0
+ 60
+
+
+
+ PointingHandCursor
+
+
+ QPushButton:hover{
+background-color:rgb(186, 189, 182);
+border-bottom:2px solid rgb(67, 154, 246);
+}
+QPushButton:checked{
+background-color:cyan;
+border-bottom:2px solid white
+}
+QPushButton:pressed{
+background-color:rgb(67, 154, 246)
+}
+QPushButton{
+background-color:rgb(238, 238, 236);
+border:none;
+padding:0px 0px 0px 0px;
+margin:0px 0px 0px 0px;
+}
+
+
+
+
+
+
+ ../../../../../catkin_ws/src/Ros_Qt5_Gui_App/ui../../../../../catkin_ws/src/Ros_Qt5_Gui_App/ui
+
+
+
+ 32
+ 32
+
+
+
+
+
+
+
+
+
+
+
+