Initial commit

This commit is contained in:
2026-07-27 13:51:19 +08:00
commit 7bec56ca51
5408 changed files with 1126933 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
cmake_minimum_required(VERSION 3.0.2)
project(cockpit)
find_package(catkin REQUIRED COMPONENTS
autoware_msgs
roscpp
sensor_msgs
serial
message_generation
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES cockpit
# CATKIN_DEPENDS autoware_msgs roscpp sensor_msgs
# DEPENDS system_lib
)
include_directories(
include
${catkin_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}/msg
)
add_executable(cockpit_node
src/cockpit_node.cpp
src/cockpit_core.cpp
)
target_link_libraries(cockpit_node
${catkin_LIBRARIES}
)
add_dependencies(cockpit_node
autoware_msgs_generate_messages_cpp
)
+50
View File
@@ -0,0 +1,50 @@
#ifndef COCKPIT_CORE_H
#define COCKPIT_CORE_H
#include "ros/ros.h"
#include "serial/serial.h"
#include "rc_receiver/rc.h"
#include "sensor_msgs/BatteryState.h"
#define __APP_NAME__ "cockpit_driver"
class CockPit{
public:
CockPit();
~CockPit();
void run();
private:
ros::NodeHandle nh_;
ros::NodeHandle private_nh_;
private:
/*串口号 */
std::string cockpit_com_;
/* 串口波特率 */
int baudrate_;
/* 驾驶模式控制的指令话题 */
std::string input_ctr_mode_topic_;
/* 电池状态的指令话题 */
std::string input_battery_state_topic_;
private:
uint16_t soc_ = 0;
uint8_t current_page_ = 0;
uint8_t drive_mode_ = 0;
private:
ros::Subscriber ctr_mode_sub_;
ros::Subscriber battery_state_sub_;
private:
serial::Serial serial_;
private:
void ctr_mode_callback(const rc_receiver::rc::ConstPtr &msg);
void battery_status_callback(const sensor_msgs::BatteryState::ConstPtr& msg);
void process(const ros::TimerEvent& e);
void serial_initial();
};
#endif
+13
View File
@@ -0,0 +1,13 @@
<launch>
<arg name="cockpit_com_" default="/dev/ttyUSB0"/>
<arg name="baudrate_" default="115200"/>
<arg name="input_ctr_mode_topic_" default="/remote_ctrl"/>
<arg name="input_battery_state_topic_" default="/sensor/battery_state"/>
<node name="cockpit_node" pkg="cockpit" type="cockpit_node" output="screen">
<param name="cockpit_com_" value="$(arg cockpit_com_)" type="string"/>
<param name="baudrate_" value="$(arg baudrate_)" type="int"/>
<param name="input_ctr_mode_topic_" value="$(arg input_ctr_mode_topic_)" type="string"/>
<param name="input_battery_state_topic_" value="$(arg input_battery_state_topic_)" type="string"/>
</node>
</launch>
+71
View File
@@ -0,0 +1,71 @@
<?xml version="1.0"?>
<package format="2">
<name>cockpit</name>
<version>0.0.0</version>
<description>The cockpit package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="zhangshu@todo.todo">zhangshu</maintainer>
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/cockpit</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>autoware_msgs</build_depend>
<build_depend>roscpp</build_depend>
<build_depend>sensor_msgs</build_depend>
<build_depend>serial</build_depend>
<build_export_depend>autoware_msgs</build_export_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>sensor_msgs</build_export_depend>
<build_export_depend>serial</build_export_depend>
<exec_depend>autoware_msgs</exec_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>sensor_msgs</exec_depend>
<exec_depend>serial</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
+156
View File
@@ -0,0 +1,156 @@
#include "cockpit_core.h"
CockPit::CockPit() : nh_(""), private_nh_("~")
{
private_nh_.param<std::string>("cockpit_com_", cockpit_com_, "");
private_nh_.param<int>("baudrate_", baudrate_, 115200);
private_nh_.param<std::string>("input_ctr_mode_topic_", input_ctr_mode_topic_, "");
private_nh_.param<std::string>("input_battery_state_topic_", input_battery_state_topic_, "");
}
CockPit::~CockPit() {}
void CockPit::run()
{
serial_initial();
ctr_mode_sub_ = nh_.subscribe<rc_receiver::rc>(input_ctr_mode_topic_, 1, &CockPit::ctr_mode_callback, this);
battery_state_sub_ = nh_.subscribe<sensor_msgs::BatteryState>(input_battery_state_topic_, 1, &CockPit::battery_status_callback, this);
ros::Timer timer = nh_.createTimer(ros::Duration(0.4), &CockPit::process, this, false, true);
ros::spin();
}
void CockPit::serial_initial()
{
serial::Timeout timeOut = serial::Timeout::simpleTimeout(1000);
try
{
serial_.setPort(cockpit_com_);
serial_.setBaudrate(baudrate_);
serial_.setTimeout(timeOut);
serial_.open();
}
catch (serial::IOException &e)
{
ROS_ERROR("[%s] Unable to open cockpit com", __APP_NAME__);
return;
}
}
void CockPit::ctr_mode_callback(const rc_receiver::rc::ConstPtr &msg)
{
drive_mode_ = msg->control_mode;
}
void CockPit::battery_status_callback(const sensor_msgs::BatteryState::ConstPtr &msg)
{
soc_ = msg->percentage * 10;
current_page_ = (msg->power_supply_status == 1) ? 1 : 0;
}
/* CRC16 数组 */
static const uint8_t aucCRCHi[] = {0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00,
0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80,
0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80,
0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00,
0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40};
static const uint8_t aucCRCLo[] = {0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D,
0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB,
0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2,
0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37,
0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8,
0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24,
0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63,
0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE,
0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F,
0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C,
0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46,
0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40};
// CRC计算函数
uint16_t usMBCRC16(uint8_t *pucFrame, uint16_t usLen)
{
uint8_t ucCRCHi = 0xFF; // 初始值为0xFF(高字节)
uint8_t ucCRCLo = 0xFF; // 初始值为0xFF(低字节)
int iIndex;
while (usLen--)
{
iIndex = ucCRCLo ^ *(pucFrame++);
ucCRCLo = (uint8_t)(ucCRCHi ^ aucCRCHi[iIndex]);
ucCRCHi = aucCRCLo[iIndex];
}
return (uint16_t)(ucCRCHi << 8 | ucCRCLo); // 大端序结果(高字节在前)
}
uint8_t Intelligent_str_cmd[18] = {0x5A, 0xA5, 0x0F, 0x10, 0x00, 0xBA, 0xD7, 0xD4, 0xB6, 0xAF, 0xB5, 0xBC, 0xBA, 0xBD, 0x00, 0x00, 0x7A, 0xC1};
uint8_t remote_str_cmd[18] = {0x5A, 0xA5, 0x0F, 0x10, 0x00, 0xBA, 0xD2, 0xA3, 0xBF, 0xD8, 0xBC, 0xDD, 0xCA, 0xBB, 0x00, 0x00, 0xA9, 0xDE};
uint8_t page0_cmd[10] = {0x5A, 0xA5, 0x07, 0x10, 0x70, 0X00, 0X00, 0X00, 0XFF, 0X03};
uint8_t page1_charging_cmd[10] = {0x5A, 0xA5, 0x07, 0x10, 0x70, 0X00, 0X00, 0X01, 0X3E, 0XC3};
uint8_t buffer_battery[10] = {0x5A, 0xA5, 0x07, 0x10, 0x00, 0x5C, 0x03, 0xE8, 0x25, 0x6F};
void CockPit::process(const ros::TimerEvent &e)
{
// 发送页面显示
if (current_page_ == 0)
{
serial_.write(page0_cmd, sizeof(page0_cmd));
ros::Duration(0.01).sleep();//指令间隔延时
static int count = 0; // 用于命令发送计数
/* 智驾模式 */
if (drive_mode_ == 0)
{
if (count < 2)
{
serial_.write(Intelligent_str_cmd, sizeof(Intelligent_str_cmd));
}
else
{
count = 2;
}
count++;
}
else
{
/* 遥控模式 */
if (count > -2)
{
serial_.write(remote_str_cmd, sizeof(remote_str_cmd));
}
else
{
count = -2;
}
count--;
}
}
else
{
// 充电页面
serial_.write(page1_charging_cmd, sizeof(page1_charging_cmd));
}
ros::Duration(0.01).sleep();
// 发送电量显示
buffer_battery[6] = (soc_ & 0xFFFF) >> 8;
buffer_battery[7] = soc_ & 0xFF;
/* 校验 */
uint16_t Voltage_CRC = usMBCRC16(&buffer_battery[3], 5);
buffer_battery[8] = (uint8_t)(Voltage_CRC >> 0); // CRC校验值
buffer_battery[9] = (uint8_t)(Voltage_CRC >> 8);
// 串口发送
serial_.write(buffer_battery, sizeof(buffer_battery));
}
+8
View File
@@ -0,0 +1,8 @@
#include "cockpit_core.h"
int main(int argc, char **argv){
ros::init(argc, argv, "cockpit_node");
CockPit cock_pit;
cock_pit.run();
return 0;
}