Initial commit
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user