Broke out segwayrmp and segway_msgs

This commit is contained in:
Ryan Lewis 2022-08-03 14:48:00 -04:00
parent 37aac69eee
commit c26af222a5
35 changed files with 5 additions and 1452 deletions

View File

@ -1,2 +1,5 @@
# ROS2_ws_for_RMP220 # segway_msgs
ROS2.0 support package for Segway RMP chassis, through which you can drive the RMP220 chassis and get the chassis status information.
ROS2 messages for Segway RMP chassis, through which you can drive the RMP220 chassis and get the chassis status information.
Derived from [this fork](https://github.com/LuckierDodge/ROS2_ws_for_RMP220) of the original segway package.

View File

@ -1,81 +0,0 @@
cmake_minimum_required(VERSION 3.5)
project(segwayrmp)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpic -Wl,-R${PROJECT_SOURCE_DIR}/lib")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpic")
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclpy REQUIRED)
find_package(std_msgs REQUIRED)
find_package(nav_msgs REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(segway_msgs REQUIRED)
find_package(tf2 REQUIRED)
find_package(tf2_ros REQUIRED)
find_package(rclcpp_action REQUIRED)
find_package(rclcpp_components REQUIRED)
add_executable(SmartCar
src/SmartCar.cpp
src/robot.cpp
)
target_include_directories(SmartCar PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_link_directories(SmartCar PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/lib
)
# message(WARNING ${PROJECT_SOURCE_DIR} + "!!" + ${CMAKE_CURRENT_SOURCE_DIR} + "!!" + ${PROJECT_NAME})
ament_target_dependencies(SmartCar
"rclcpp" "std_msgs" "nav_msgs" "sensor_msgs" "geometry_msgs" "segway_msgs" "tf2" "tf2_ros"
)
target_link_libraries(SmartCar
${PROJECT_SOURCE_DIR}/lib/libctrl_arm64-v8a.so
)
add_executable(drive_segway_sample
tools/drive_segway_sample.cpp
)
target_include_directories(drive_segway_sample PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
ament_target_dependencies(drive_segway_sample
"rclcpp" "std_msgs" "nav_msgs" "sensor_msgs" "geometry_msgs" "segway_msgs" "tf2" "tf2_ros"
)
install(TARGETS
SmartCar
drive_segway_sample
DESTINATION
lib/${PROJECT_NAME})
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()

View File

@ -1,109 +0,0 @@
#ifdef __cplusplus
extern "C" {
#endif
#ifndef COMM_CTRL_H
#define COMM_CTRL_H
#include <stdbool.h>
#include <stdint.h>
#include "comm_ctrl_navigation.h"
// Map table transmission value gain coefficient;
#define ERROR_LINE_LIMIT_VEL_VALUE (5 * LINE_SPEED_TRANS_GAIN_MPS)
#define ERROR_ANGULAR_LIMIT_VEL_VALUE (5 * ANGULAR_SPEED_TRANS_GAIN_RADPS)
#define ACC_VALUE_GAIN 100
#define RMP_HOST_ERR_BIT_MCU_HEART_BEAT 0 //The heartbeat with the chassis was interrupted
#define RMP_HOST_ERR_BIT_SERIAL_PORT_LOST 1 //Serial port module unplugged
void AprGxJniEventRegister(int32_t (*callback)(int32_t));
//-------------------Timestamp------------------------
//--------------------GX--API------------------
int init_control(void);
void exit_control(void);
int16_t get_forward_speed_limit(void);
int16_t get_backward_speed_limit(void);
int16_t get_angular_speed_limit(void);
uint16_t get_Stop_Bottom_Status(void);
uint8_t set_calib_chassis_imu_gyro(void);//Reserve for later versions
uint16_t get_Chassis_Imu_Calib_Result(void); //Reserve for later versions
void clear_Chassis_Imu_Calib_Result(void);//Reserve for later versions
uint8_t set_calib_chassis_current(void);
uint16_t get_chassis_current_calib_result(void);
void clear_chassis_current_calib_result(void);
//-----------------GX IAP--------------------
void IapAllBoard(const char **file_paths, char **versions);
int32_t IapSingerBoard(char * path,char * boradname,char* version);
//int32_t getIapTotalProgress(void);
//------------------GX Host-------------------
char* GetGxHardVersion(void);
void TracePrint_Switch(bool status); //true or false
void SetNavigationStatus(uint8_t status);
void setSaveRecordCmd(void); //开始保存log接口     ps:上层调用
void clearRecordCmd(void); //清除保存log命令     ps:上层不需要调<E8A681>?so每次保存完log后会自动调用
uint8_t getSaveRecordCmd(void); //获取是否开始保存log   ps:so自动调用,上层不需要调<E8A681>?
uint8_t GetNavigationStatus(void);
void set_gx_route_bat_voltage(uint16_t voltage);
int16_t get_cmd_speed_forward(void);
int16_t get_fbk_speed_forward(void);
int16_t get_encode_fbk_speed_forward(void);
int16_t get_cmd_w_forward(void);
int16_t get_fbk_w_forward(void);
int16_t get_rec_cmd_vx(void);
int16_t get_rec_cmd_w(void);
int16_t get_pid_target_vx(void);
int16_t get_pid_target_w(void);
int16_t get_encode_speed_L(void);
int16_t get_encode_speed_R(void);
int16_t get_heart_beat_data(board_name_e board_type);
void set_host_error(uint8_t offset, uint8_t err_bool_value);
uint32_t get_host_error(void);
uint32_t get_host_speed_cmd_cnt(void);
uint32_t get_chassis_reply_speed_cmd_cnt(void);
int32_t get_encoder_l_ticks(void);
int32_t get_encoder_r_ticks(void);
char * get_smart_car_serial(void);
uint8_t get_comu_interface_serial0_can1();
void showHostBuildTime(void);
void showChassisCentralBuildTime(void);
/* 暂时不开放此接口由于map表只能发送整数故此接口待修改乘以10或<30>?00下发电机板收到命令数据后再恢复数据 */
uint8_t set_cmd_acc(double linear_x_acc, double linear_x_brake_acc, double angular_z_acc);//Set the linear and angular accelerated speed: m/s2 ; rad/s2.
uint8_t set_chassis_no_load(void);
uint8_t set_chassis_full_load(void);
void ackWriteCentralMapInit();
uint8_t ctrlMapAckWrite( uint8_t dest_id, uint8_t map_start_index, uint32_t mem_len);
void set_chassis_charge_status(int16_t chargestatus);
uint32_t get_chassis_central_Err_Status(void);
uint16_t get_chassis_l_motor_Err_Status(void);
uint16_t get_chassis_r_motor_Err_Status(void);
uint32_t get_chassis_bms_Err_Status(void);
char * show_host_version(void);
int16_t get_charge_mos_ctrl_cmd(void);// Get chassis charge_ctrl mos cmd; 1:turn on; 0: turn off
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,180 +0,0 @@
#ifdef __cplusplus
extern "C" {
#endif
#ifndef COMM_CTRL_NAVIGATION_H
#define COMM_CTRL_NAVIGATION_H
#include <stdbool.h>
#include <stdint.h>
#define TYPE_ID_NUM 10 //Number of callback functions
//--------------------------DATA CALL BACK INDEX--------------------------
#define Chassis_Data_Speed 1
#define Chassis_Data_Ticks 2
#define Chassis_Data_Odom_Pose_xy 3
#define Chassis_Data_Odom_Euler_xy 4
#define Chassis_Data_Odom_Euler_z 5
#define Chassis_Data_Odom_Linevel_xy 6
#define Chassis_Data_Imu_Gyr 7 //IMU Gyroscope data 陀螺仪数据上报
#define Chassis_Data_Imu_Acc 8 //IMU Accelerometer data 加速度计数据上<E68DAE>?
//-----------------------Event---------------------------------------------
#define ChassisBootReadyEvent 1 // Chassis central control boot OK
#define PadPowerOffEvent 2 // The chassis will power off
#define OnEmergeStopEvent 3 // The chassis emergency stop button is triggered
#define OutEmergeStopEvent 4 // The chassis emergency stop button recover
#define OnLockedRotorProtectEvent 5 // the chassis motor locked-rotor
#define OutLockedRotorProtectEvent 6 // the chassis motor no longer locked-rotor
#define OnLostCtrlProtectEvent 7 // the chassis motor lost control
#define OutLostCtrlProtectEvent 8 // the chassis motor no longer lost control
#define CalibrateGyroSuccess 9 // Chassis gyroscope calibration successful
#define CalibrateGyroFail 10 // Chassis gyroscope calibration failed
#define CalibratePasheCurrentSuccess 11 // Chassis gyroscope calibration successful
#define CalibratePasheCurrentFail 12 // Chassis gyroscope calibration failed
//---------The proportional coefficient of the callback gyro data------------------
#define CHASSIS_IMU_GYR_VALUE_TRANS_SCALE 900 //900~~32768(MAX value for int16: map table ) * 57.3(degrees for 1 rad) /2000(Gyroscope range: 2000dps)
#define CHASSIS_IMU_ACC_VALUE_TRANS_SCALE 4000 //4000~~32768(MAX value for int16: map table )/8(Accelerometer range: 8g)
#define LINE_SPEED_TRANS_GAIN_MPS 3600 //3600-->1m/s
#define ANGULAR_SPEED_TRANS_GAIN_RADPS 1000 //1000-->1rad/s
#define NO_LOAD 0 // Set the chassis parameters as no-load parameters, The chassis defaults to no load
#define FULL_LOAD 1 // Set the chassis parameters as full load parameters
//-----------------------Version V0.6 and above---------------------------
#define LOCK_MODE 0 // Lock the car
#define CTRL_MODE 1 // Control the car
#define PUSH_MODE 2 // push the car
#define EMERG_MODE 3 // emergency
#define ERROR_MODE 4 // Internal error
//-------------------Timestamp------------------------
#define MAX_BASIC_FRM_SZ 0x1F
#pragma pack(1)
typedef struct StampedBasicFrame_{
uint32_t type_id; //Data type number
uint64_t timestamp; //Linux timestamp
char data[MAX_BASIC_FRM_SZ]; //Chassis specific data
} StampedBasicFrame;
#pragma pack()
typedef void (*h_aprctrl_datastamped_t)(StampedBasicFrame* frm);
typedef void (*h_aprctrl_event_t)(int32_t event_num);
typedef struct {
h_aprctrl_datastamped_t on_new_data;
}s_aprctrl_datastamped_t;
typedef struct {
h_aprctrl_event_t event_callback;
}s_aprctrl_event_t;
typedef enum {
Host = 1,
Central = 2, //底盘只连中控<E4B8AD>?
Motor = 3,
BMS = 4
}board_name_e;
typedef enum {
comu_serial = 0,
comu_can = 1
}comu_choice_e;
typedef struct{
int16_t l_speed;//Left wheel speed
int16_t r_speed;//Right wheel speed
int16_t car_speed;//Vehicle linear speed
int16_t turn_speed;//Turning speed
}chassis_speed_data_t;
typedef struct{
int32_t l_ticks;//Left wheel ticks
int32_t r_ticks;//Right wheel ticks
}motor_ticks_t;
typedef struct{
float pos_x;
float pos_y;
}odom_pos_xy_t;
typedef struct{
float euler_x;
float euler_y;
}odom_euler_xy_t;
typedef struct{
float euler_z;
}odom_euler_z_t;
typedef struct{
float vel_line_x;
float vel_line_y;
}odom_vel_line_xy_t;
typedef struct{
int16_t gyr[3];
}imu_gyr_original_data_t;
typedef struct{
int16_t acc[3];
}imu_acc_original_data_t;
void aprctrl_datastamped_jni_register(s_aprctrl_datastamped_t* f); //The callback registration function
void aprctrl_eventcallback_jni_register(s_aprctrl_event_t* f); //Event callback registration function
uint32_t get_err_state(board_name_e board_name);//Gets the software error status
int16_t get_bat_soc(void);//Gets the percentage of battery left
int16_t get_bat_charging(void);//Gets the charging status of the battery
int32_t get_bat_mvol(void);//Gets battery voltage, mV
int32_t get_bat_mcurrent(void);//Gets battery current, mA
int16_t get_bat_temp(void);// Gets battery temperature
int16_t get_chassis_work_model(void);//Get the chassis working mode
uint8_t get_chassis_load_state(void);//Gets whether the chassis parameters are empty or full load, 0: no_load, 1: full_load
uint16_t get_chassis_mode(void);//Gets chassis mode
int16_t get_ctrl_cmd_src(void); // Get the source of the control command
int32_t get_vehicle_meter(void); //Get the total mileage meters of the chssis
uint16_t get_host_version(void);
uint16_t get_chassis_central_version(void);
uint16_t get_chassis_motor_version(void);
int16_t get_line_forward_max_vel_fb(void);
int16_t get_line_backward_max_vel_fb(void);
int16_t get_angular_max_vel_fb(void);
int32_t getIapTotalProgress(void);
void iapCentralBoard(void);//Operate on the Central board: IAP
void iapMotorBoard(void);//Operate on the Motor board: IAP
bool isHostIapOver(void);//Query whether a single IAP ends
int16_t getHostIapResult(void);
int16_t getHostIapErrorCode(void);
int16_t get_chassis_hang_mode(void);//Get chassis hang_mode; 1: in Hang_mode; 0: not in Hand_mode.
int16_t get_charge_mos_ctrl_status(void);//Get the status of switch for charging MOS on the central board, charging:1; no charge:0
void set_cmd_vel(double linear_x,double angular_z);//Set the linear and angular speeds of the vehicle: m/s ; rad/s.
uint8_t set_line_forward_max_vel(double linear_forward_max_x);//Set the maximum linear velocity in the direction of advance
uint8_t set_line_backward_max_vel(double linear_backward_max_x);//Set the maximum linear velocity in the backward direction
uint8_t set_angular_max_vel(double angular_max_z);//Set the maximum angular velocity
uint8_t set_enable_ctrl(uint16_t enable_flag);//Set chassis movement enable
int init_control_ctrl(void);//Chassis initialization
void exit_control_ctrl(void);//Chassis software finished running
void set_smart_car_serial(const char * serial_no);//Set the serial port name
void set_comu_interface(comu_choice_e comu_choice); //Set communication interface: 'comu_serial': serial port; 'comu_can': CAN port
uint8_t set_chassis_load_state(int16_t newLoadSet);//Sets whether the chassis parameters are empty or full load, 0: no_load, 1: full_load
uint8_t set_chassis_poweroff(void);//Set two - wheel differential chassis shutdown
uint8_t set_remove_push_cmd(void);//An order to remove the push status
void setHostIapCanceled(void);
void set_chassis_hang_mode(int16_t enterHand);//Set chassis hang_mode; 1: enter the Hang_mode; 0: exit the Hand_mode.
uint8_t set_charge_mos_ctrl(bool on);//Set the switch for charging MOS on the central board; charging:1, stop charging:0.
extern int32_t IapSingerBoard(char * path,char * boradname,char* version);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,169 +0,0 @@
#ifndef _ROBOT_H
#define _ROBOT_H
#include <functional>
#include <chrono>
#include <memory>
#include <string>
#include "stdint.h"
#include <time.h>
#include <sys/time.h>
#include <rosidl_typesupport_cpp/message_type_support.hpp>
#include "rclcpp/rclcpp.hpp"
#include <geometry_msgs/msg/transform_stamped.hpp>
#include <geometry_msgs/msg/twist.hpp>
#include <nav_msgs/msg/odometry.hpp>
#include <sensor_msgs/msg/imu.hpp>
#include "tf2_ros/transform_broadcaster.h"
#include <tf2_ros/static_transform_broadcaster.h>
#include "tf2/LinearMath/Quaternion.h"
#include "comm_ctrl_navigation.h"
#include "rclcpp_action/rclcpp_action.hpp"
#include "segway_msgs/msg/bms_fb.hpp"
#include "segway_msgs/msg/chassis_ctrl_src_fb.hpp"
#include "segway_msgs/msg/chassis_mileage_meter_fb.hpp"
#include "segway_msgs/msg/chassis_mode_fb.hpp"
#include "segway_msgs/msg/error_code_fb.hpp"
#include "segway_msgs/msg/motor_work_mode_fb.hpp"
#include "segway_msgs/msg/speed_fb.hpp"
#include "segway_msgs/msg/ticks_fb.hpp"
#include "segway_msgs/srv/chassis_send_event.hpp"
#include "segway_msgs/srv/ros_get_charge_mos_ctrl_status_cmd.hpp"
#include "segway_msgs/srv/ros_get_load_param_cmd.hpp"
#include "segway_msgs/srv/ros_get_sw_version_cmd.hpp"
#include "segway_msgs/srv/ros_get_vel_max_feedback_cmd.hpp"
#include "segway_msgs/srv/ros_set_charge_mos_ctrl_cmd.hpp"
#include "segway_msgs/srv/ros_set_chassis_enable_cmd.hpp"
#include "segway_msgs/srv/ros_set_chassis_poweroff_cmd.hpp"
#include "segway_msgs/srv/ros_set_load_param_cmd.hpp"
#include "segway_msgs/srv/ros_set_remove_push_cmd.hpp"
#include "segway_msgs/srv/ros_set_vel_max_cmd.hpp"
#include "segway_msgs/action/ros_set_iap_cmd.hpp"
#define pi 3.141592654
#define pi_2 6.283185308
namespace robot
{
class Chassis
{
public:
using iapCmd = segway_msgs::action::RosSetIapCmd;
using goalHandaleIapCmd = rclcpp_action::ServerGoalHandle<iapCmd>;
Chassis(rclcpp::Node::SharedPtr nh);
static void pub_event_callback(int event_no);
private:
std::shared_ptr<rclcpp::Node> node;
std::string bins_directory;
std::string chassis_version;
std::string route_version;
std::string connect_version;
tf2::Quaternion odom_quat;
std::shared_ptr<tf2_ros::StaticTransformBroadcaster> odom_broadcaster;
segway_msgs::msg::BmsFb bms_fb;
segway_msgs::msg::ChassisCtrlSrcFb chassis_ctrl_src_fb;
segway_msgs::msg::ChassisMileageMeterFb chassis_mileage_meter_fb;
segway_msgs::msg::ChassisModeFb chassis_mode_fb;
segway_msgs::msg::ErrorCodeFb error_code_fb;
segway_msgs::msg::MotorWorkModeFb motor_work_mode_fb;
segway_msgs::msg::SpeedFb speed_fb;
segway_msgs::msg::TicksFb ticks_fb;
geometry_msgs::msg::TransformStamped odom_trans;
nav_msgs::msg::Odometry odom_fb;
sensor_msgs::msg::Imu imu_fb;
rclcpp::Subscription<geometry_msgs::msg::Twist>::SharedPtr velocity_sub;
rclcpp::Publisher<segway_msgs::msg::BmsFb>::SharedPtr bms_fb_pub;
rclcpp::Publisher<segway_msgs::msg::ChassisCtrlSrcFb>::SharedPtr chassis_ctrl_src_fb_pub;
rclcpp::Publisher<segway_msgs::msg::ChassisMileageMeterFb>::SharedPtr chassis_mileage_meter_fb_pub;
rclcpp::Publisher<segway_msgs::msg::ChassisModeFb>::SharedPtr chassis_mode_fb_pub;
rclcpp::Publisher<segway_msgs::msg::ErrorCodeFb>::SharedPtr error_code_fb_pub;
rclcpp::Publisher<segway_msgs::msg::MotorWorkModeFb>::SharedPtr motor_work_mode_fb_pub;
rclcpp::Publisher<segway_msgs::msg::SpeedFb>::SharedPtr speed_fb_pub;
rclcpp::Publisher<segway_msgs::msg::TicksFb>::SharedPtr ticks_fb_pub;
rclcpp::Publisher<nav_msgs::msg::Odometry>::SharedPtr odom_pub;
rclcpp::Publisher<sensor_msgs::msg::Imu>::SharedPtr imu_pub;
rclcpp::Service<segway_msgs::srv::RosGetChargeMosCtrlStatusCmd>::SharedPtr ros_get_charge_mos_ctrl_status_cmd_server;
rclcpp::Service<segway_msgs::srv::RosGetLoadParamCmd>::SharedPtr ros_get_load_param_cmd_server;
rclcpp::Service<segway_msgs::srv::RosGetSwVersionCmd>::SharedPtr ros_get_sw_version_cmd_server;
rclcpp::Service<segway_msgs::srv::RosGetVelMaxFeedbackCmd>::SharedPtr ros_get_vel_max_feedback_cmd_server;
rclcpp::Service<segway_msgs::srv::RosSetChargeMosCtrlCmd>::SharedPtr ros_set_charge_mos_ctrl_cmd_server;
rclcpp::Service<segway_msgs::srv::RosSetChassisEnableCmd>::SharedPtr ros_set_chassis_enable_cmd_server;
rclcpp::Service<segway_msgs::srv::RosSetChassisPoweroffCmd>::SharedPtr ros_set_chassis_poweroff_cmd_server;
rclcpp::Service<segway_msgs::srv::RosSetLoadParamCmd>::SharedPtr ros_set_load_param_cmd_server;
rclcpp::Service<segway_msgs::srv::RosSetRemovePushCmd>::SharedPtr ros_set_remove_push_cmd_server;
rclcpp::Service<segway_msgs::srv::RosSetVelMaxCmd>::SharedPtr ros_set_vel_max_cmd_server;
void ros_get_charge_mos_ctrl_status_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosGetChargeMosCtrlStatusCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosGetChargeMosCtrlStatusCmd::Response> response);
void ros_get_load_param_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosGetLoadParamCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosGetLoadParamCmd::Response> response);
void ros_get_sw_version_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosGetSwVersionCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosGetSwVersionCmd::Response> response);
void ros_get_vel_max_feedback_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosGetVelMaxFeedbackCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosGetVelMaxFeedbackCmd::Response> response);
void ros_set_charge_mos_ctrl_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetChargeMosCtrlCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetChargeMosCtrlCmd::Response> response);
void ros_set_chassis_enable_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetChassisEnableCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetChassisEnableCmd::Response> response);
void ros_set_chassis_poweroff_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetChassisPoweroffCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetChassisPoweroffCmd::Response> response);
void ros_set_load_param_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetLoadParamCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetLoadParamCmd::Response> response);
void ros_set_remove_push_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetRemovePushCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetRemovePushCmd::Response> response);
void ros_set_vel_max_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetVelMaxCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetVelMaxCmd::Response> response);
rclcpp_action::Server<iapCmd>::SharedPtr iap_action_server;
rclcpp::TimerBase::SharedPtr timer_1hz;
rclcpp::TimerBase::SharedPtr timer_1000hz;
s_aprctrl_datastamped_t timestamp_data;
s_aprctrl_event_t event_data;
void timer_1000hz_callback(void);
void timer_1hz_callback(void);
void speed_pub_callback(void);
void ticks_pub_callback(void);
void imu_pub_callback(void);
void pub_odom_callback(void);
void cmd_vel_callback(const geometry_msgs::msg::Twist::SharedPtr msg) const;
void iapCmdExecute(const std::shared_ptr<goalHandaleIapCmd> goal_handle);
rclcpp_action::GoalResponse handle_iapCmdGoal(
const rclcpp_action::GoalUUID & uuid,
std::shared_ptr<const iapCmd::Goal> goal)
{
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "Receive goal request with iap_board %d", goal->iap_board);
(void)uuid;
return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
}
rclcpp_action::CancelResponse handle_iapCmdCancel(
const std::shared_ptr<goalHandaleIapCmd> goal_handle)
{
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "Received request to cancel goal");
(void)goal_handle;
return rclcpp_action::CancelResponse::ACCEPT;
}
void handle_iapCmdAccepted(const std::shared_ptr<goalHandaleIapCmd> goal_handle)
{
using namespace std::placeholders;
(void)goal_handle;
std::thread{std::bind(&Chassis::iapCmdExecute, this, _1), goal_handle}.detach();
}
};
}
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,31 +0,0 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>segwayrmp</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="chunxin.chu@ninebot.com">ninebot</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
<depend>rclpy</depend>
<depend>std_msgs</depend>
<depend>nav_msgs</depend>
<depend>geometry_msgs</depend>
<!-- <depend>sensor_msgs</depned> -->
<depend>segway_msgs</depend>
<depend>tf2</depend>
<depend>tf2_ros</depend>
<depend>rclcpp_action</depend>
<depend>rclcpp_components</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>

View File

@ -1,27 +0,0 @@
#include "rclcpp/rclcpp.hpp"
#include "segwayrmp/robot.h"
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("SmartCar");
node->declare_parameter<std::string>("serial_full_name", "/dev/ttyUSB0");
std::string serial_full_name;
node->get_parameter("serial_full_name", serial_full_name);
// init_control()parameter: Fill in the full path name of the actual serial port being used
set_smart_car_serial((char*)serial_full_name.c_str());//If a serial port is used, set the serial port name.
set_comu_interface(comu_serial);//Before calling init_control_ctrl, need to call this function set whether the communication port is serial or CAN.
if (init_control_ctrl() == -1) {
printf("init_control failed!\n");
exit_control_ctrl();
} else {
printf("init_control success!\n");
}
robot::Chassis sbv(node);
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}

View File

@ -1,489 +0,0 @@
#include "segwayrmp/robot.h"
#include <cwchar>
#define VEL_DT 0.05 //50ms
#define RAD_DEGREE_CONVER 57.2958
#define HOST_SPEED_UINIT 3600 //
#define HOST_ANGULAR_SPEED_UINIT 2271
typedef struct{
uint32_t typeId;
uint8_t dataSize;
uint64_t *segwayTimeStamp;
uint8_t * updateFlag;
void * dataPtr;
}SegwayData;
chassis_speed_data_t SpeedData;
uint64_t Speed_TimeStamp;
uint8_t Speed_update;
motor_ticks_t TickData;
uint64_t Tick_TimeStamp;
uint8_t Tick_update;
imu_gyr_original_data_t ImuGyroData;
uint64_t ImuGyro_TimeStamp;
uint8_t ImuGyro_update;
imu_acc_original_data_t ImuAccData;
uint64_t ImuAcc_TimeStamp;
uint8_t ImuAcc_update;
odom_pos_xy_t OdomPoseXy;
odom_euler_xy_t OdomEulerXy;
odom_euler_z_t OdomEulerZ;
odom_vel_line_xy_t OdomVelLineXy;
uint64_t Odom_TimeStamp;
uint8_t OdomPoseXy_update;
uint8_t OdomEulerXy_update;
uint8_t OdomEulerZ_update;
uint8_t OdomVelLineXy_update;
static SegwayData segway_data_tbl[] = {
{Chassis_Data_Speed, sizeof(SpeedData), &Speed_TimeStamp, &Speed_update, &SpeedData},
{Chassis_Data_Ticks, sizeof(TickData), &Tick_TimeStamp, &Tick_update, &TickData},
{Chassis_Data_Imu_Gyr, sizeof(ImuGyroData), &ImuGyro_TimeStamp, &ImuGyro_update, &ImuGyroData},
{Chassis_Data_Imu_Acc, sizeof(ImuAccData), &ImuAcc_TimeStamp, &ImuAcc_update, &ImuAccData},
{Chassis_Data_Odom_Pose_xy, sizeof(OdomPoseXy), &Odom_TimeStamp, &OdomPoseXy_update, &OdomPoseXy},
{Chassis_Data_Odom_Euler_xy, sizeof(OdomEulerXy), &Odom_TimeStamp, &OdomEulerXy_update, &OdomEulerXy},
{Chassis_Data_Odom_Euler_z, sizeof(OdomEulerZ), &Odom_TimeStamp, &OdomEulerZ_update, &OdomEulerZ},
{Chassis_Data_Odom_Linevel_xy, sizeof(OdomVelLineXy), &Odom_TimeStamp, &OdomVelLineXy_update, &OdomVelLineXy}
};
std::shared_ptr<rclcpp::Node> car_node;
rclcpp::Client<segway_msgs::srv::ChassisSendEvent>::SharedPtr event_client;
void PubData(StampedBasicFrame_ *frame)
{
uint8_t i = 0;
for (; i < sizeof(segway_data_tbl)/sizeof(segway_data_tbl[0]); i++)
{
if (frame->type_id == segway_data_tbl[i].typeId) break;
}
if (i < sizeof(segway_data_tbl)/sizeof(segway_data_tbl[0])){
*(segway_data_tbl[i].segwayTimeStamp) = frame->timestamp;
*(segway_data_tbl[i].updateFlag) =1;
memcpy( segway_data_tbl[i].dataPtr, frame->data, segway_data_tbl[i].dataSize);
}
}
void EventPubData(int event_no)
{
robot::Chassis::pub_event_callback(event_no);
}
namespace robot
{
void Chassis::pub_event_callback(int event_no)
{
using eventServiceResponseFutrue = rclcpp::Client<segway_msgs::srv::ChassisSendEvent>::SharedFuture;
auto event_request = std::make_shared<segway_msgs::srv::ChassisSendEvent::Request>();
event_request->chassis_send_event_id = event_no;
auto event_response_receive_callback = [](eventServiceResponseFutrue futrue) {
(void)futrue;
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "event sended successfully");
};
auto event_future_result = event_client->async_send_request(event_request, event_response_receive_callback);
}
Chassis::Chassis(rclcpp::Node::SharedPtr nh) : node(nh)
{
using namespace std::placeholders;
car_node = nh;
timestamp_data.on_new_data = PubData;
aprctrl_datastamped_jni_register(&timestamp_data);
event_data.event_callback = EventPubData;
aprctrl_eventcallback_jni_register(&event_data);
node->declare_parameter<std::string>("bins_directory", "/sdcard/firmware/");
node->declare_parameter<std::string>("chassis_version", "1.01");
node->declare_parameter<std::string>("route_version", "1.01");
node->declare_parameter<std::string>("connect_version", "1.01");
bms_fb_pub = node->create_publisher<segway_msgs::msg::BmsFb>("/bms_fb", 1);
chassis_ctrl_src_fb_pub = node->create_publisher<segway_msgs::msg::ChassisCtrlSrcFb>("/chassis_ctrl_src_fb", 1);
chassis_mileage_meter_fb_pub = node->create_publisher<segway_msgs::msg::ChassisMileageMeterFb>("/chassis_mileage_meter_fb", 1);
chassis_mode_fb_pub = node->create_publisher<segway_msgs::msg::ChassisModeFb>("/chassis_mode_fb", 1);
error_code_fb_pub = node->create_publisher<segway_msgs::msg::ErrorCodeFb>("/error_code_fb", 1);
motor_work_mode_fb_pub = node->create_publisher<segway_msgs::msg::MotorWorkModeFb>("/motor_work_mode_fb", 1);
speed_fb_pub = node->create_publisher<segway_msgs::msg::SpeedFb>("/speed_fb", 1);
ticks_fb_pub = node->create_publisher<segway_msgs::msg::TicksFb>("/ticks_fb", 1);
odom_pub = node->create_publisher<nav_msgs::msg::Odometry>("/odom", 1);
imu_pub = node->create_publisher<sensor_msgs::msg::Imu>("/imu", 1);
event_client = node->create_client<segway_msgs::srv::ChassisSendEvent>("event_srv");
ros_get_charge_mos_ctrl_status_cmd_server = node->create_service<segway_msgs::srv::RosGetChargeMosCtrlStatusCmd>(
"get_charge_mos_ctrl_status", std::bind(&Chassis::ros_get_charge_mos_ctrl_status_cmd_callback, this, _1, _2));
ros_get_load_param_cmd_server = node->create_service<segway_msgs::srv::RosGetLoadParamCmd>(
"get_load_param", std::bind(&Chassis::ros_get_load_param_cmd_callback, this, _1, _2));
ros_get_sw_version_cmd_server = node->create_service<segway_msgs::srv::RosGetSwVersionCmd>(
"get_sw_version", std::bind(&Chassis::ros_get_sw_version_cmd_callback, this, _1, _2));
ros_get_vel_max_feedback_cmd_server = node->create_service<segway_msgs::srv::RosGetVelMaxFeedbackCmd>(
"get_vel_max_feedback", std::bind(&Chassis::ros_get_vel_max_feedback_cmd_callback, this, _1, _2));
ros_set_charge_mos_ctrl_cmd_server = node->create_service<segway_msgs::srv::RosSetChargeMosCtrlCmd>(
"set_charge_mos_ctrl", std::bind(&Chassis::ros_set_charge_mos_ctrl_cmd_callback, this, _1, _2));
ros_set_chassis_enable_cmd_server = node->create_service<segway_msgs::srv::RosSetChassisEnableCmd>(
"set_chassis_enable", std::bind(&Chassis::ros_set_chassis_enable_cmd_callback, this, _1, _2));
ros_set_chassis_poweroff_cmd_server = node->create_service<segway_msgs::srv::RosSetChassisPoweroffCmd>(
"set_chassis_poweroff", std::bind(&Chassis::ros_set_chassis_poweroff_cmd_callback, this, _1, _2));
ros_set_load_param_cmd_server = node->create_service<segway_msgs::srv::RosSetLoadParamCmd>(
"set_load_param", std::bind(&Chassis::ros_set_load_param_cmd_callback, this, _1, _2));
ros_set_remove_push_cmd_server = node->create_service<segway_msgs::srv::RosSetRemovePushCmd>(
"set_remove_push", std::bind(&Chassis::ros_set_remove_push_cmd_callback, this, _1, _2));
ros_set_vel_max_cmd_server = node->create_service<segway_msgs::srv::RosSetVelMaxCmd>(
"set_vel_max", std::bind(&Chassis::ros_set_vel_max_cmd_callback, this, _1, _2));
velocity_sub = node->create_subscription<geometry_msgs::msg::Twist>(
"cmd_vel", 1, std::bind(&Chassis::cmd_vel_callback, this, std::placeholders::_1));
iap_action_server = rclcpp_action::create_server<iapCmd>(
node,
"iapCmd",
std::bind(&Chassis::handle_iapCmdGoal, this, _1, _2),
std::bind(&Chassis::handle_iapCmdCancel, this, _1),
std::bind(&Chassis::handle_iapCmdAccepted, this, _1));
odom_broadcaster = std::make_shared<tf2_ros::StaticTransformBroadcaster>(node);
timer_1000hz = node->create_wall_timer(std::chrono::milliseconds(1), std::bind(&Chassis::timer_1000hz_callback, this));
timer_1hz = node->create_wall_timer(std::chrono::milliseconds(1000), std::bind(&Chassis::timer_1hz_callback, this));
}
void Chassis::ros_get_charge_mos_ctrl_status_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosGetChargeMosCtrlStatusCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosGetChargeMosCtrlStatusCmd::Response> response)
{
int16_t ret = 0;
if (request->ros_get_chassis_charge_ctrl_status == true){
ret = get_charge_mos_ctrl_status();
response->chassis_charge_ctrl_status = ret;
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "receive RosGetChargeMosCtrlStatusCmd cmd[%d], charge_ctrl_status[%d]",
1, ret);
}
else {
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_get_chassis_charge_ctrl_status false");
}
}
void Chassis::ros_get_load_param_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosGetLoadParamCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosGetLoadParamCmd::Response> response)
{
if (request->ros_get_load_param == false) {
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_get_load_param fasle");
return ;
}
response->get_load_param = get_chassis_load_state();
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "get_load_param[%d]", response->get_load_param );
}
void Chassis::ros_get_sw_version_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosGetSwVersionCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosGetSwVersionCmd::Response> response)
{
if (request->ros_get_sw_version_cmd == false) {
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_get_sw_version_cmd fasle");
return;
}
response->host_version = get_host_version();
response->central_version = get_chassis_central_version();
response->motor_version = get_chassis_motor_version();
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_get_sw_version_cmd true");
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "host_version:%d, central_version:%d, motor_version:%d",
response->host_version, response->central_version, response->motor_version);
}
void Chassis::ros_get_vel_max_feedback_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosGetVelMaxFeedbackCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosGetVelMaxFeedbackCmd::Response> response)
{
if (request->ros_get_vel_max_fb_cmd == false) {
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_get_vel_max_fb_cmd fasle");
return;
}
response->forward_max_vel_fb = get_line_forward_max_vel_fb();
response->backward_max_vel_fb = get_line_backward_max_vel_fb();
response->angular_max_vel_fb = get_angular_max_vel_fb();
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_get_vel_max_fb_cmd true");
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "forward_max_vel_fb:%d, backward_max_vel_fb:%d, angular_max_vel_fb:%d",
response->forward_max_vel_fb, response->backward_max_vel_fb, response->angular_max_vel_fb);
}
void Chassis::ros_set_charge_mos_ctrl_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetChargeMosCtrlCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetChargeMosCtrlCmd::Response> response)
{
uint8_t ret;
if (request->ros_set_chassis_charge_ctrl == false) {
ret = set_charge_mos_ctrl(false);
}
else {
ret = set_charge_mos_ctrl(true);
}
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_set_chassis_charge_ctrl cmd[%d]", request->ros_set_chassis_charge_ctrl);
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "chassis_set_charge_ctrl_result[%d]", ret);
response->chassis_set_charge_ctrl_result = ret;
}
void Chassis::ros_set_chassis_enable_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetChassisEnableCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetChassisEnableCmd::Response> response)
{
uint8_t ret;
if (request->ros_set_chassis_enable_cmd == false) {
ret = set_enable_ctrl(0);
}
else {
ret = set_enable_ctrl(1);
}
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_set_chassis_enable_cmd cmd[%d]", request->ros_set_chassis_enable_cmd);
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "chassis_set_chassis_enable_result[%d]", ret);
response->chassis_set_chassis_enable_result = ret;
}
void Chassis::ros_set_chassis_poweroff_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetChassisPoweroffCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetChassisPoweroffCmd::Response> response)
{
if (request->ros_set_chassis_poweroff_cmd == false) {
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_set_chassis_poweroff_cmd fasle");
return;
}
uint8_t ret = set_chassis_poweroff();
response->chassis_set_poweroff_result = ret;
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "chassis_set_poweroff_result[%d]", ret);
}
void Chassis::ros_set_load_param_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetLoadParamCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetLoadParamCmd::Response> response)
{
int16_t value = request->ros_set_load_param;
if (value != 0 && value != 1){
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_set_load_param[%d] out of normal range ", value);
return;
}
uint8_t ret = set_chassis_load_state(value);
response->chassis_set_load_param_result = ret;
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "chassis_set_load_param_result[%d]", ret);
}
void Chassis::ros_set_remove_push_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetRemovePushCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetRemovePushCmd::Response> response)
{
if (request->ros_set_remove_push_cmd == false) {
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_set_remove_push_cmd fasle");
return;
}
uint8_t ret = set_remove_push_cmd();
response->chassis_set_revove_push_result = ret;
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "chassis_set_revove_push_result[%d]", ret);
}
void Chassis::ros_set_vel_max_cmd_callback(const std::shared_ptr<segway_msgs::srv::RosSetVelMaxCmd::Request> request,
std::shared_ptr<segway_msgs::srv::RosSetVelMaxCmd::Response> response)
{
double forward = request->ros_set_forward_max_vel;
double backward = request->ros_set_backward_max_vel;
double angular = request->ros_set_angular_max_vel;
uint8_t ret_forw = set_line_forward_max_vel(forward);
uint8_t ret_back = set_line_backward_max_vel(backward);
uint8_t ret_angl = set_angular_max_vel(angular);
response->chassis_set_max_vel_result = ret_forw | ret_back | ret_angl;
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "ros_set_forward_max_vel[%lf], ros_set_backward_max_vel[%lf], ros_set_angular_max_vel[%lf]",
forward, backward, angular);
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "set_line_forward_max_vel result[%d], set_line_backward_max_vel result[%d], set_angular_max_vel result[%d]",
ret_forw, ret_back, ret_angl);
}
void Chassis::iapCmdExecute(const std::shared_ptr<goalHandaleIapCmd> goal_handle)
{
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "Executing goal");
rclcpp::Rate loop_rate(1);
const auto goal = goal_handle->get_goal();
auto feedback = std::make_shared<iapCmd::Feedback>();
auto result = std::make_shared<iapCmd::Result>();
int32_t iap_percent_fb;
node->get_parameter("bins_directory", bins_directory);
node->get_parameter("chassis_version", chassis_version);
node->get_parameter("route_version", route_version);
node->get_parameter("connect_version", connect_version);
char bin_dir[100] = {0};
char ver[100] = {0};
switch (goal->iap_board)
{
case 1:
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "iap central board");
bins_directory = bins_directory + "/central.bin";
bins_directory.copy(bin_dir, bins_directory.length(), 0);
chassis_version.copy(ver, chassis_version.length(), 0);
IapSingerBoard(bin_dir, (char*)"central", ver);
break;
case 2:
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "iap motor board");
bins_directory = bins_directory + "/motor.bin";
bins_directory.copy(bin_dir, bins_directory.length(), 0);
route_version.copy(ver, route_version.length(), 0);
IapSingerBoard(bin_dir, (char*)"motor", ver);
break;
default:
RCLCPP_ERROR(rclcpp::get_logger("SmartCar"),
"iap_board value error, out of [1 2]", goal->iap_board);
result->set__iap_result(5);
goal_handle->canceled(result);
return;
}
while (rclcpp::ok())
{
if (goal_handle->is_canceling()) {
result->set__iap_result(5);
goal_handle->canceled(result);
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "Goal canceled");
return;
}
iap_percent_fb = getIapTotalProgress();
feedback->set__iap_percent(iap_percent_fb);
goal_handle->publish_feedback(feedback);
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "iap percent: %d", iap_percent_fb);
loop_rate.sleep();
if (iap_percent_fb == 100) {
RCLCPP_INFO_ONCE(rclcpp::get_logger("SmartCar"), "iap successful");
break;
} else if (iap_percent_fb < 0) {
RCLCPP_INFO_ONCE(rclcpp::get_logger("SmartCar"), "iap failed");
break;
}
}
if (rclcpp::ok()) {
if (iap_percent_fb == 100) {
result->set__iap_result(3);
goal_handle->succeed(result);
RCLCPP_INFO(rclcpp::get_logger("SmartCar"), "goal succeeded, iap succeeded");
} else {
result->set__iap_result(getHostIapResult());
result->set__error_code(getHostIapErrorCode());
goal_handle->succeed(result);
RCLCPP_ERROR(rclcpp::get_logger("SmartCar"), "goal failed, iap failed");
}
}
}
void Chassis::cmd_vel_callback(const geometry_msgs::msg::Twist::SharedPtr msg) const
{
double angular_vel = msg->angular.z;
double linear_vel = msg->linear.x;
angular_vel = (angular_vel > 3.0 ? 3.0 : (angular_vel < -3.0 ? -3.0 : angular_vel));
linear_vel = (linear_vel > 3.0 ? 3.0 : (linear_vel < -1.0 ? -1.0 : linear_vel));
set_cmd_vel(linear_vel, angular_vel);
// printf("vl:%lf, va:%lf\n", linear_vel, angular_vel);
}
void Chassis::timer_1hz_callback(void)
{
bms_fb.bat_soc = get_bat_soc();
bms_fb.bat_charging = get_bat_charging();
bms_fb.bat_vol = get_bat_mvol();
bms_fb.bat_current = get_bat_mcurrent();
bms_fb.bat_temp = get_bat_temp();
bms_fb_pub->publish(bms_fb);
chassis_ctrl_src_fb.chassis_ctrl_cmd_src = get_ctrl_cmd_src();
chassis_ctrl_src_fb_pub->publish(chassis_ctrl_src_fb);
chassis_mileage_meter_fb.vehicle_meters = get_vehicle_meter();
chassis_mileage_meter_fb_pub->publish(chassis_mileage_meter_fb);
chassis_mode_fb.chassis_mode = get_chassis_mode();//0-lock_mode; 1-ctrl_mode; 2-push_mode; 3-emergency_mode; 4-error_mode
chassis_mode_fb_pub->publish(chassis_mode_fb);
error_code_fb.host_error = get_err_state(Host);
error_code_fb.central_error = get_err_state(Central);
error_code_fb.left_motor_error = get_err_state(Motor) & 0xffff;
error_code_fb.right_motor_error = (get_err_state(Motor) >> 16) & 0xffff;
error_code_fb.bms_error = get_err_state(BMS);
error_code_fb_pub->publish(error_code_fb);
motor_work_mode_fb.motor_work_mode = get_chassis_work_model();
motor_work_mode_fb_pub->publish(motor_work_mode_fb);
}
void Chassis::timer_1000hz_callback(void)
{
speed_pub_callback();
ticks_pub_callback();
imu_pub_callback();
pub_odom_callback();
}
void Chassis::speed_pub_callback(void)
{
if (Speed_update == 1) {
Speed_update = 0;
speed_fb.car_speed = SpeedData.car_speed;
speed_fb.car_speed /= LINE_SPEED_TRANS_GAIN_MPS;
speed_fb.turn_speed = SpeedData.turn_speed;
speed_fb.turn_speed /= ANGULAR_SPEED_TRANS_GAIN_RADPS;
speed_fb.l_speed = SpeedData.l_speed;
speed_fb.l_speed /= LINE_SPEED_TRANS_GAIN_MPS;
speed_fb.r_speed = SpeedData.r_speed;
speed_fb.r_speed /= LINE_SPEED_TRANS_GAIN_MPS;
speed_fb.speed_timestamp = Speed_TimeStamp;
speed_fb_pub->publish(speed_fb);
}
}
void Chassis::ticks_pub_callback(void)
{
if (Tick_update == 1) {
Tick_update = 0;
ticks_fb.l_ticks = TickData.l_ticks;
ticks_fb.r_ticks = TickData.r_ticks;
ticks_fb.ticks_timestamp = Tick_TimeStamp;
ticks_fb_pub->publish(ticks_fb);
}
}
void Chassis::imu_pub_callback(void)
{
if (ImuGyro_update == 1 && ImuAcc_update == 1){
ImuGyro_update = 0;
ImuAcc_update = 0;
imu_fb.header.stamp = node->now();
imu_fb.header.frame_id = "base_link";
imu_fb.angular_velocity.x = (double)ImuGyroData.gyr[0] / 900.0;
imu_fb.angular_velocity.y = (double)ImuGyroData.gyr[1] / 900.0;
imu_fb.angular_velocity.z = (double)ImuGyroData.gyr[2] / 900.0;
imu_fb.linear_acceleration.x = (double)ImuAccData.acc[0] / 4000.0 * 9.8;
imu_fb.linear_acceleration.y = (double)ImuAccData.acc[1] / 4000.0 * 9.8;
imu_fb.linear_acceleration.z = (double)ImuAccData.acc[2] / 4000.0 * 9.8;
imu_pub->publish(imu_fb);
}
}
void Chassis::pub_odom_callback(void)
{
if ((OdomPoseXy_update & OdomEulerXy_update & OdomEulerZ_update & OdomVelLineXy_update) == 1) {
OdomPoseXy_update = 0, OdomEulerXy_update = 0, OdomEulerZ_update = 0, OdomVelLineXy_update = 0;
odom_quat.setRPY(0, 0, OdomEulerZ.euler_z / RAD_DEGREE_CONVER);
odom_trans.header.stamp = node->now();
odom_trans.header.frame_id = "odom";
odom_trans.child_frame_id = "base_link";
odom_trans.transform.translation.x = OdomPoseXy.pos_x;
odom_trans.transform.translation.y = OdomPoseXy.pos_y;
odom_trans.transform.translation.z = 0.0;
odom_trans.transform.rotation.x = odom_quat.x();
odom_trans.transform.rotation.y = odom_quat.y();
odom_trans.transform.rotation.z = odom_quat.z();
odom_trans.transform.rotation.w = odom_quat.w();
odom_broadcaster->sendTransform(odom_trans);
odom_fb.header.stamp = node->now();
odom_fb.header.frame_id = "odom";
odom_fb.pose.pose.position.x = OdomPoseXy.pos_x;
odom_fb.pose.pose.position.y = OdomPoseXy.pos_y;
odom_fb.pose.pose.position.z = 0.0;
odom_fb.pose.pose.orientation.x = odom_quat.x();
odom_fb.pose.pose.orientation.y = odom_quat.y();
odom_fb.pose.pose.orientation.z = odom_quat.z();
odom_fb.pose.pose.orientation.w = odom_quat.w();
odom_fb.child_frame_id = "base_link";
odom_fb.twist.twist.linear.x = (double)SpeedData.car_speed / LINE_SPEED_TRANS_GAIN_MPS;
odom_fb.twist.twist.linear.y = 0;
odom_fb.twist.twist.angular.z = (double)SpeedData.turn_speed / ANGULAR_SPEED_TRANS_GAIN_RADPS;;
odom_pub->publish(odom_fb);
}
}
}

View File

@ -1,364 +0,0 @@
#include "segwayrmp/robot.h"
#include <termio.h>
#include <stdio.h>
#include <iostream>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#define PRINTHELP 'h'
#define ADDLINEVEL 'w'
#define DECLINEVEL 's'
#define ADDANGULARVEL 'a'
#define DECANGULARVEL 'd'
#define PRINTCURVEL 'f'
#define VELRESETZERO 'g'
#define ENABLECMD 'e'
#define CHASSISPAUSE 'q'
// #define CLEARSCRAM 'c'
// #define GETERROR 'x'
#define IAPCENTRAL 'v'
#define IAPMOTOR 'b'
#define PRINTERRSW 'r'
using iapCmd = segway_msgs::action::RosSetIapCmd;
using goalHandleIapCmd = rclcpp_action::ClientGoalHandle<iapCmd>;
std::shared_ptr<rclcpp::Node> drive_node;
rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr velocity_pub;
rclcpp::Subscription<segway_msgs::msg::ErrorCodeFb>::SharedPtr error_sub;
rclcpp::Client<segway_msgs::srv::RosSetChassisEnableCmd>::SharedPtr enable_client;
// rclcpp::Client<segway_msgs::srv::ClearChassisScramStatusCmd>::SharedPtr clear_scram_client;
// rclcpp::Client<segway_msgs::srv::GetGxErrorCmd>::SharedPtr get_err_client;
rclcpp::Service<segway_msgs::srv::ChassisSendEvent>::SharedPtr event_server;
rclcpp_action::Client<iapCmd>::SharedPtr iap_client;
uint8_t print_error = 0;
char const* print_help() {
char const* printHelp =
"\t h : Displays the required keys and their meaning\n"
"\t w : Increase forward speed by 0.1m/s\n"
"\t s : Decrease forward speed by 0.1m/s\n"
"\t a : Increase the angular velocity by 0.1rad/s\n"
"\t d : Decrease the angular velocity by 0.1rad/s\n"
"\t f : Displays current speed Settings\n"
"\t g : Speed reset to zero\n"
"\t e : Chassis enable switch\n"
"\t q : Running pause. Click 'q'key again to resume running by the previous speed. W/S/A/D keys can also restore chassis running\n"
"\t v : Iap the central board, please put the bin file in /sdcard/firmware/\n"
"\t b : Iap the motor board, please put the bin file in /sdcard/firmware/\n"
"\t r : Open or close the switch: printing error code\n"
"\t others : Do nothing\n";
return printHelp;
}
void changemode(int dir)
{
static struct termios oldt, newt;
if ( dir == 1 )
{
tcgetattr( STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt);
}
else
tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
}
int kbhit (void)
{
struct timeval tv;
fd_set rdfs; //一组fd集合
tv.tv_sec = 0;
tv.tv_usec = 0; //时间为0非阻塞
FD_ZERO(&rdfs); //fd集合清空
FD_SET (STDIN_FILENO, &rdfs); //增加新的fd
select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv); //非阻塞检测fd为0的tty读取状态rdfs特定位置1
return FD_ISSET(STDIN_FILENO, &rdfs); //判断指定的标准输入fd是否在rdfs集合中
}
static int scanKeyboard()
{
int input_char = 0;
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);
changemode(1);
if (kbhit()) {
input_char = getchar();
printf("\n");
}
changemode(0);
tcsetattr(0, TCSANOW, &stored_settings);
return input_char;
}
char get_keyboard()
{
char keyvalue = scanKeyboard();
return keyvalue;
}
void goal_response_callback(std::shared_future<goalHandleIapCmd::SharedPtr> future)
{
auto goal_handle = future.get();
if (!goal_handle) {
RCLCPP_ERROR(rclcpp::get_logger("drive_segway_sample"), "Goal was rejected by server");
} else {
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "Goal accepted by server, waiting for result");
}
}
void feedback_callback(
goalHandleIapCmd::SharedPtr,
const std::shared_ptr<const iapCmd::Feedback> feedback)
{
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "IAP process percentage[%d]", feedback->iap_percent);
}
void result_callback(const goalHandleIapCmd::WrappedResult & result)
{
switch (result.code) {
case rclcpp_action::ResultCode::SUCCEEDED:
break;
case rclcpp_action::ResultCode::ABORTED:
RCLCPP_ERROR(rclcpp::get_logger("drive_segway_sample"), "Goal was aborted");
return;
case rclcpp_action::ResultCode::CANCELED:
RCLCPP_ERROR(rclcpp::get_logger("drive_segway_sample"), "Goal was canceled");
return;
default:
RCLCPP_ERROR(rclcpp::get_logger("drive_segway_sample"), "Unknown result code");
return;
}
if (result.result->iap_result == 3) {
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "iap success!");
} else {
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "iap fail!, error_code[%#x]", result.result->error_code);
}
}
void drive_chassis_test()
{
static uint16_t set_enable_cmd = 1;
uint8_t enable_switch = 0;
static double set_line_speed;
static double set_angular_speed;
static double send_line_speed;
static double send_angular_speed;
static uint8_t chassis_pause = 0;
// uint8_t clear_scram_flag = 0;
// uint8_t get_err_flag = 0;
uint8_t iap_flag = 0;
auto enable_request = std::make_shared<segway_msgs::srv::RosSetChassisEnableCmd::Request>();
// auto clear_scram_requst = std::make_shared<segway_msgs::srv::ClearChassisScramStatusCmd::Request>();
// auto get_err_request = std::make_shared<segway_msgs::srv::GetGxErrorCmd::Request>();
char keyvalue = get_keyboard();
switch (keyvalue)
{
case PRINTHELP:
printf("%s\n", print_help());
break;
case ADDLINEVEL :
set_line_speed += 0.1;
send_line_speed = set_line_speed;
send_angular_speed = set_angular_speed;
printf("current set_line_speed[%lf], set_angular_speed[%lf]\n", set_line_speed, set_angular_speed);
break;
case DECLINEVEL :
set_line_speed -= 0.1;
send_line_speed = set_line_speed;
send_angular_speed = set_angular_speed;
printf("current set_line_speed[%lf], set_angular_speed[%lf]\n", set_line_speed, set_angular_speed);
break;
case ADDANGULARVEL :
set_angular_speed += 0.1;
send_line_speed = set_line_speed;
send_angular_speed = set_angular_speed;
printf("current set_line_speed[%lf], set_angular_speed[%lf]\n", set_line_speed, set_angular_speed);
break;
case DECANGULARVEL :
set_angular_speed -= 0.1;
send_line_speed = set_line_speed;
send_angular_speed = set_angular_speed;
printf("current set_line_speed[%lf], set_angular_speed[%lf]\n", set_line_speed, set_angular_speed);
break;
case PRINTCURVEL :
printf("current set_line_speed[%lf], set_angular_speed[%lf]\n", set_line_speed, set_angular_speed);
break;
case VELRESETZERO :
set_line_speed = 0;
set_angular_speed = 0;
send_line_speed = 0;
send_angular_speed = 0;
printf("current set_line_speed[%lf], set_angular_speed[%lf]\n", set_line_speed, set_angular_speed);
break;
case ENABLECMD :
enable_switch = 1;
enable_request->ros_set_chassis_enable_cmd = set_enable_cmd;
++set_enable_cmd;
set_enable_cmd %= 2;
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"),
"enable chassis switch[%d]", enable_request->ros_set_chassis_enable_cmd);
printf("current set_line_speed[%lf], set_angular_speed[%lf]\n", set_line_speed, set_angular_speed);
break;
case CHASSISPAUSE :
++chassis_pause;
chassis_pause %= 2;
if (chassis_pause) {
send_line_speed = 0;
send_angular_speed = 0;
printf("Stop the chassis temporarily\n");
} else {
send_line_speed = set_line_speed;
send_angular_speed = set_angular_speed;
printf("current set_line_speed[%lf], set_angular_speed[%lf]\n", set_line_speed, set_angular_speed);
}
break;
// case CLEARSCRAM :
// // clear_scram_flag = 1;
// break;
// case GETERROR:
// // get_err_flag = 1;
// break;
case IAPCENTRAL:
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "iap chassis");
iap_flag = 1;
break;
case IAPMOTOR:
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "iap route");
iap_flag = 2;
break;
case PRINTERRSW:
print_error = ~print_error;
break;
default:
break;
}
geometry_msgs::msg::Twist cmd_vel;
cmd_vel.linear.x = send_line_speed;
cmd_vel.angular.z = send_angular_speed;
velocity_pub->publish(cmd_vel);
if (enable_switch){
using enableServiceResponseFutrue = rclcpp::Client<segway_msgs::srv::RosSetChassisEnableCmd>::SharedFuture;
auto enable_response_receive_callback = [](enableServiceResponseFutrue futrue) {
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"),
"event sended successfully, result:%d", futrue.get()->chassis_set_chassis_enable_result);
};
auto enable_future_result = enable_client->async_send_request(enable_request, enable_response_receive_callback);
}
// if (clear_scram_flag) {
// using clearServiceResponseFuture = rclcpp::Client<segway_msgs::srv::ClearChassisScramStatusCmd>::SharedFuture;
// auto clear_response_receive_callback = [](clearServiceResponseFuture future) {
// RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"),
// "clear scram status successfully, result:%d", future.get()->clear_scram_result);
// };
// auto clear_future_result = clear_scram_client->async_send_request(clear_scram_requst, clear_response_receive_callback);
// }
// if (get_err_flag) {
// using errorServiceResponseFuture = rclcpp::Client<segway_msgs::srv::GetGxErrorCmd>::SharedFuture;
// auto error_response_receive_callback = [](errorServiceResponseFuture future) {
// RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"),
// "chassis_error_code[%d], route_error_code[%d], connect_error_code[%d]",
// future.get()->chassis_error_code,
// future.get()->route_error_code,
// future.get()->connect_error_code);
// };
// auto error_future_result = get_err_client->async_send_request(get_err_request, error_response_receive_callback);
// }
if (iap_flag & 3) {
auto goal_msg = iapCmd::Goal();
goal_msg.iap_board = iap_flag;
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "sending goal, iap cmd goal");
auto send_goal_options = rclcpp_action::Client<iapCmd>::SendGoalOptions();
send_goal_options.goal_response_callback = std::bind(&goal_response_callback, std::placeholders::_1);
send_goal_options.feedback_callback = std::bind(&feedback_callback, std::placeholders::_1, std::placeholders::_2);
send_goal_options.result_callback = std::bind(&result_callback, std::placeholders::_1);
iap_client->async_send_goal(goal_msg, send_goal_options);
}
}
void get_error_code_callback(const segway_msgs::msg::ErrorCodeFb::SharedPtr msg)
{
if (print_error != 0) {
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "host_error[%#x], central_error[%#x], \
left_motor_error[%#x], right_motor_error[%#x], bms_err[%#x]",
msg->host_error, msg->central_error, msg->left_motor_error, msg->right_motor_error, msg->bms_error);
}
}
void get_chassis_event_callback(const std::shared_ptr<segway_msgs::srv::ChassisSendEvent::Request> request,
std::shared_ptr<segway_msgs::srv::ChassisSendEvent::Response> response)
{
(void)response;
switch (request->chassis_send_event_id)
{
case OnEmergeStopEvent:
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "CHASSIS EVENT: The chassis emergency stop button is triggered");
break;
case OutEmergeStopEvent:
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "CHASSIS EVENT: OThe chassis emergency stop button recover");
break;
case PadPowerOffEvent:
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "CHASSIS EVENT: The chassis will power off");
break;
case OnLockedRotorProtectEvent:
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "CHASSIS EVENT: the chassis motor locked-rotor");
break;
case OutLockedRotorProtectEvent:
RCLCPP_INFO(rclcpp::get_logger("drive_segway_sample"), "CHASSIS EVENT: the chassis motor no longer locked-rotor");
break;
default:
break;
}
}
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
drive_node = rclcpp::Node::make_shared("drive_segway_sample");
velocity_pub = drive_node->create_publisher<geometry_msgs::msg::Twist>("cmd_vel", 1);
error_sub = drive_node->create_subscription<segway_msgs::msg::ErrorCodeFb>(
"error_code_fb", 1, std::bind(&get_error_code_callback, std::placeholders::_1));
enable_client = drive_node->create_client<segway_msgs::srv::RosSetChassisEnableCmd>("set_chassis_enable");
// clear_scram_client = drive_node->create_client<segway_msgs::srv::ClearChassisScramStatusCmd>("clear_scram_status_srv");
// get_err_client = drive_node->create_client<segway_msgs::srv::GetGxErrorCmd>("get_error_srv");
event_server = drive_node->create_service<segway_msgs::srv::ChassisSendEvent>(
"event_srv", std::bind(&get_chassis_event_callback, std::placeholders::_1, std::placeholders::_2));
iap_client = rclcpp_action::create_client<iapCmd>(drive_node, "iapCmd");
rclcpp::TimerBase::SharedPtr timer_100hz =
drive_node->create_wall_timer(std::chrono::milliseconds(10), &drive_chassis_test);
printf("%s\n", print_help());
rclcpp::spin(drive_node);
rclcpp::shutdown();
return 0;
}