对上交代码进行修改,主要将能量机关去掉,添加了同济的PnP位姿解算,但是同济有个四元数,获取IMU部分没有启用,可能导致精度不够。当前还存在反陀螺功能,修改为逻辑和弹道预测相结合,主要在时间关系上进行调整。

This commit is contained in:
2026-03-21 11:57:34 +08:00
commit 56985997ae
80 changed files with 60253 additions and 0 deletions

120
others/src/additions.cpp Normal file
View File

@@ -0,0 +1,120 @@
//
// Created by sjturm on 19-5-17.
//
#include <cstring>
#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/videoio/videoio_c.h>
#include <additions.h>
#include <camera/camera_wrapper.h>
#include <armor_finder/armor_finder.h>
#include <log.h>
#define RECEIVE_LOG_LEVEL LOG_MSG
using namespace std;
using namespace cv;
extern WrapperHead *video;
extern Serial serial;
extern uint8_t last_state;
extern ArmorFinder armor_finder;
void uartReceive(Serial *pSerial) {
char buffer[40];
LOGM(STR_CTR(WORD_LIGHT_WHITE, "data receive start!"));
while (true) {
memset(buffer, 0, sizeof(buffer));
pSerial->ReadData((uint8_t *) buffer, sizeof(mcu_data)+1);
if (buffer[sizeof(mcu_data)] == '\n') {
memcpy(&mcu_data, buffer, sizeof(mcu_data));
LOGM("Get, state:%c, mark:%d!", mcu_data.state, (int) mcu_data.mark);
LOGM("Get yaw: %f, pitch: %f!", mcu_data.curr_yaw, mcu_data.curr_pitch);
// static int t = time(nullptr);
// static int cnt = 0;
// if(time(nullptr) > t){
// t = time(nullptr);
// LOGM("fps:%d", cnt);
// cnt = 0;
// }else{
// cnt++;
// }
}else{
// LOGW("corrupt data!");
}
}
}
cv::VideoWriter initVideoWriter(const std::string &filename_prefix) {
cv::VideoWriter video;
std::ifstream in(filename_prefix + "cnt.txt");
int cnt = 0;
if (in.is_open()) {
in >> cnt;
in.close();
}
std::string file_name = filename_prefix + std::to_string(cnt) + ".avi";
cnt++;
std::ofstream out(filename_prefix + "cnt.txt");
if (out.is_open()) {
out << cnt << std::endl;
out.close();
}
video.open(file_name, CV_FOURCC('P', 'I', 'M', '1'), 90, cv::Size(640, 480), true);
return video;
}
bool checkReconnect(bool is_camera_connect) {
if (!is_camera_connect) {
int curr_gain = ((CameraWrapper* )video)->gain;
int curr_exposure = ((CameraWrapper* )video)->exposure;
int curr_mode = ((CameraWrapper* )video)->mode; // 获取原始模式
delete video;
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 等待硬件释放
video = new CameraWrapper(curr_exposure, curr_gain, curr_mode/*, "armor"*/);
//video = new CameraWrapper(curr_exposure, curr_gain, 0/*, "armor"*/);
is_camera_connect = video->init();
}
return is_camera_connect;
}
auto video_writer = initVideoWriter(PROJECT_DIR"/video/");
void saveVideos(const cv::Mat &gimbal_src) {
if (!gimbal_src.empty()) {
video_writer.write(gimbal_src);
} else return;
}
void showOrigin(const cv::Mat &src) {
if (!src.empty()) {
imshow("origin", src);
cv::waitKey(1);
} else return;
}
void extract(cv::Mat &src) {//图像预处理将视频切成640×480的大小
if (src.empty()) return;
float length = static_cast<float>(src.cols);
float width = static_cast<float>(src.rows);
if (length / width > 1280.0 / 1024.0) {
length *= 1024 / width;
resize(src, src, cv::Size(length, 1024));
src = src(Rect((length - 1280) / 2, 0, 1280, 1024));
} else {
width *= 1280.0 / length;
resize(src, src, cv::Size(1280, width));
src = src(Rect(0, (width - 1024) / 2, 1280, 1024));
}
}
double getPointLength(const cv::Point2f &p) {
return sqrt(p.x * p.x + p.y * p.y);
}

View File

@@ -0,0 +1,189 @@
//
// Created by zhikun on 18-11-7.
//
#include <iostream>
#include <camera/camera_wrapper.h>
#include <log.h>
#include <additions.h>
#include <options.h>
#include <config/setconfig.h>
using namespace std;
using namespace cv;
CameraWrapper::CameraWrapper(int exposure, int gain, int camera_mode, const std::string &n) :
name(n),
init_done(false),
mode(camera_mode),
camera_cnts(2),
camera_status(-1),
rgb_buffer(nullptr),
channel(3),
gain(gain),
exposure(exposure){
}
void cameraCallback(CameraHandle hCamera, BYTE *pFrameBuffer, tSdkFrameHead* pFrameHead,PVOID pContext){
CameraWrapper *c = (CameraWrapper*)pContext;
CameraImageProcess(hCamera, pFrameBuffer, c->rgb_buffer, pFrameHead);
// 使用 cv::Mat 替代 IplImage
cv::Mat img(pFrameHead->iHeight, pFrameHead->iWidth,
c->channel == 3 ? CV_8UC3 : CV_8UC1,
c->rgb_buffer, pFrameHead->iWidth * c->channel);
c->src_queue.push(img.clone());
}
bool CameraWrapper::init() {
CameraSdkInit(1);
int camera_enumerate_device_status = CameraEnumerateDevice(camera_enum_list, &camera_cnts);
if (camera_enumerate_device_status != CAMERA_STATUS_SUCCESS) {
LOGE("CameraEnumerateDevice fail with %d!", camera_enumerate_device_status);
return false;
}
if (camera_cnts == 0) {
LOGE("No camera device detected!");
return false;
} else if (camera_cnts >= 1) {
LOGM("%d camera device detected!", camera_cnts);
}
int i;
for (i = 0; i < camera_cnts; i++) {
camera_status = CameraInit(&camera_enum_list[i], -1, -1, &h_camera);
if (camera_status != CAMERA_STATUS_SUCCESS) {
CameraUnInit(h_camera);
continue;
}
CameraGetFriendlyName(h_camera, camera_name);
if (name == "NULL" || strcmp(name.data(), camera_name) == 0) {
break;
}
CameraUnInit(h_camera);
}
if (i >= camera_cnts) {
LOGE("No device name %s or device open error!!", name.data());
return false;
}
auto status = CameraGetCapability(h_camera, &tCapability);
if (status != CAMERA_STATUS_SUCCESS) {
cout << "CameraGetCapability return error code " << status << endl;
return false;
}
rgb_buffer = (unsigned char *) malloc(tCapability.sResolutionRange.iHeightMax *
tCapability.sResolutionRange.iWidthMax * 3);
#ifdef Windows
char filepath[200];
sprintf(filepath, PROJECT_DIR"/others/%s.Config", name.data());
if (CameraReadParameterFromFile(h_camera, filepath) != CAMERA_STATUS_SUCCESS) {
LOGE("Load parameter %s from file fail!", filepath);
return false;
}
if (CameraLoadParameter(h_camera, PARAMETER_TEAM_A) != CAMERA_STATUS_SUCCESS) {
LOGE("CameraLoadParameter %s fail!", filepath);
return false;
}
LOGM("successfully loaded %s!", filepath);
#elif defined(Linux)
CameraReadParameterFromFile(h_camera, PROJECT_DIR"/others/MV-UB31-Group0.config");
CameraLoadParameter(h_camera, PARAMETER_TEAM_A);
CameraSetAeState(h_camera, false);
CameraSetExposureTime(h_camera, exposure * 1000);
CameraSetAnalogGain(h_camera, gain);
#endif
double t;
int g;
CameraGetExposureTime(h_camera, &t);
CameraGetAnalogGain(h_camera, &g);
LOGM("Exposure time: %lfms, gain:%d", t / 1000.0, g);
/*让SDK进入工作模式开始接收来自相机发送的图像
数据。如果当前相机是触发模式,则需要接收到
触发帧以后才会更新图像。 */
CameraPlay(h_camera);
/*其他的相机参数设置
例如 CameraSetExposureTime CameraGetExposureTime 设置/读取曝光时间
CameraSetImageResolution CameraGetImageResolution 设置/读取分辨率
CameraSetGamma、CameraSetContrast、CameraSetGain等设置图像伽马、对比度、RGB数字增益等等。
CameraGetFriendlyName CameraSetFriendlyName 获取/设置相机名称(该名称可写入相机硬件)
*/
cout << tCapability.sIspCapacity.bMonoSensor << endl;
if (tCapability.sIspCapacity.bMonoSensor) {
channel = 1;
CameraSetIspOutFormat(h_camera, CAMERA_MEDIA_TYPE_MONO8);
LOGM("camera %s mono ", camera_name);
} else {
channel = 3;
CameraSetIspOutFormat(h_camera, CAMERA_MEDIA_TYPE_BGR8);
LOGM("camera %s color ", camera_name);
}
if(mode == 2){
CameraSetCallbackFunction(h_camera, cameraCallback, this, nullptr);
}
init_done = true;
return true;
}
bool CameraWrapper::read(cv::Mat &src) {
if(init_done) {
if (mode == 0)return readProcessed(src);
if (mode == 1)return readRaw(src);
if (mode == 2)return readCallback(src);
} else {
return false;
}
}
bool CameraWrapper::readRaw(cv::Mat &src) {
if (CameraGetImageBuffer(h_camera, &frame_info, &pby_buffer, 500) == CAMERA_STATUS_SUCCESS) {
// 使用 cv::Mat 替代 IplImage
cv::Mat img(frame_info.iHeight, frame_info.iWidth, CV_8UC1, pby_buffer, frame_info.iWidth);
src = img.clone();
//在成功调用CameraGetImageBuffer后必须调用CameraReleaseImageBuffer来释放获得的buffer。
//否则再次调用CameraGetImageBuffer时程序将被挂起一直阻塞直到其他线程中调用CameraReleaseImageBuffer来释放了buffer
CameraReleaseImageBuffer(h_camera, pby_buffer);
return true;
} else {
src = cv::Mat();
return false;
}
}
bool CameraWrapper::readProcessed(cv::Mat &src) {
if (CameraGetImageBuffer(h_camera, &frame_info, &pby_buffer, 500) == CAMERA_STATUS_SUCCESS) {
CameraImageProcess(h_camera, pby_buffer, rgb_buffer,
&frame_info); // this function is super slow, better not to use it.
// 使用 cv::Mat 替代 IplImage
int mat_type = (channel == 3) ? CV_8UC3 : CV_8UC1;
cv::Mat img(frame_info.iHeight, frame_info.iWidth, mat_type, rgb_buffer, frame_info.iWidth * channel);
src = img.clone();
//在成功调用CameraGetImageBuffer后必须调用CameraReleaseImageBuffer来释放获得的buffer。
//否则再次调用CameraGetImageBuffer时程序将被挂起一直阻塞直到其他线程中调用CameraReleaseImageBuffer来释放了buffer
CameraReleaseImageBuffer(h_camera, pby_buffer);
return true;
} else {
src = cv::Mat();
return false;
}
}
bool CameraWrapper::readCallback(cv::Mat &src) {
systime ts, te;
getsystime(ts);
while(src_queue.empty()){
getsystime(te);
if(getTimeIntervalms(te, ts) > 500){
return false;
}
}
return src_queue.pop(src);
}
CameraWrapper::~CameraWrapper() {
CameraUnInit(h_camera);
//注意先反初始化后再free
if (rgb_buffer != nullptr)
free(rgb_buffer);
}

View File

@@ -0,0 +1,21 @@
//
// Created by xixiliadorabarry on 1/24/19.
//
#include "camera/video_wrapper.h"
VideoWrapper::VideoWrapper(const std::string &filename) {
video.open(filename);
}
VideoWrapper::~VideoWrapper() = default;
bool VideoWrapper::init() {
return video.isOpened();
}
bool VideoWrapper::read(cv::Mat &src) {
return video.read(src);
}

135
others/src/options.cpp Normal file
View File

@@ -0,0 +1,135 @@
//
// Created by xinyang on 19-3-27.
//
#include <options.h>
#include <log.h>
#include <cstring>
#include <map>
#include <string>
bool show_armor_box = true;
bool show_armor_boxes = false;
bool show_light_blobs = false;
bool show_origin = false;
bool run_with_camera = true;
bool save_video = false;
bool wait_uart = false;
bool save_labelled_boxes = false;
bool show_process = false;
bool save_mark = false;
bool show_info = true;
bool run_by_frame = false;
// 使用map保存所有选项及其描述和操作加快查找速度。
std::map<std::string, std::pair<std::string, void(*)(void)>> options = {
{"--help",{
"show the help information.", [](){
LOG(LOG_MSG, "<HELP>: " STR_CTR(WORD_BLUE, "All options below are for debug use."));
for(const auto &option : options){
LOG(LOG_MSG, "<HELP>: " STR_CTR(WORD_GREEN, "%s: %s"), option.first.data(), option.second.first.data());
}
}
}},
{"--show-armor-box", {
"show the aim box.", []() {
show_armor_box = true;
LOGM("Enable show armor box");
}
}},
{"--show-armor-boxes",{
"show the candidate aim boxes.", [](){
show_armor_boxes = true;
LOGM("Enable show armor boxes");
}
}},
{"--show-light-blobs",{
"show the candidate light blobs.", [](){
show_light_blobs = true;
LOGM("Enable show light blobs");
}
}},
{"--show-origin", {
"show the origin image.", [](){
show_origin = true;
LOGM("Enable show origin");
}
}},
{"--run-with-camera", {
"start the program with camera directly without asking.", []() {
run_with_camera = true;
LOGM("Run with camera!");
}
}},
{"--save-video", {
"save the video.", [](){
save_video = true;
LOGM("Enable save video!");
}
}},
{"--save-labelled-boxes",{
"save the candidate boxes with their id labels.", [](){
save_labelled_boxes = true;
LOGM("labelled armor boxes will be saved!");
}
}},
{"--wait-uart", {
"wait uart until ready before running.", [](){
wait_uart = true;
LOGM("Enable wait uart!");
}
}},
{"--run-by-frame",{
"run the code frame by frame.(normally used when run video)", [](){
run_by_frame = true;
LOGM("Enable run frame by frame");
}
}},
{"--show-process", {
"", [](){
show_process = true;
LOGM("Enable show processed image!");
}
}},
{"--save-mark", {
"", [](){
save_mark = true;
LOGM("Write down mark");
}
}},
{"--show-info", {
"", [](){
show_info = true;
LOGM("Show information!");
}
}},
{"--show-all", {
"show all image windows.", [](){
show_armor_box = true;
LOGM("Enable show armor box");
show_armor_boxes = true;
LOGM("Enable show armor boxes");
show_light_blobs = true;
LOGM("Enable show light blobs");
show_origin = true;
LOGM("Enable show origin");
show_process = true;
LOGM("Enable show processed image");
}
}
};
void processOptions(int argc, char **argv) {
if (argc >= 2) {
for (int i = 1; i < argc; i++) {
auto key = options.find(std::string(argv[i])); // 寻找对应选项。
if(key != options.end()){
key->second.second();
}else{
LOGW("Unknown option: %s. Use --help to see options.", argv[i]);
}
}
}
}

342
others/src/serial.cpp Normal file
View File

@@ -0,0 +1,342 @@
#include <serial.h>
#include <options.h>
#include <iostream>
//#define LOG_LEVEL LOG_NONE
#include <log.h>
using namespace std;
#ifdef Windows
Serial::Serial(UINT baud, char parity, UINT databits, UINT stopsbits, DWORD dwCommEvents) :
hComm(INVALID_HANDLE_VALUE),
portNo(3),
parity(parity),
databits(databits),
stopsbits(stopsbits),
dwCommEvents(dwCommEvents){
if (wait_uart) {
LOGM("Waiting for serial COM%d", portNo);
while (InitPort(portNo, baud, parity, databits, stopsbits, dwCommEvents) == false);
LOGM("Port COM%d open success!", portNo);
} else {
if (InitPort(portNo, baud, parity, databits, stopsbits, dwCommEvents)) {
LOGM("Port COM%d open success!", portNo);
} else {
LOGE("Port COM%d open fail!", portNo);
}
}
}
Serial::~Serial() {
ClosePort();
}
void Serial::ErrorHandler() {
if (wait_uart) {
LOGE("Serial COM%d offline, waiting for serial COM%d", portNo, portNo);
while (InitPort(portNo, baud, parity, databits, stopsbits, dwCommEvents) == false);
LOGM("Port COM%d reopen success!", portNo);
}
}
bool Serial::openPort(UINT portNo) {
char szPort[50];
sprintf_s(szPort, "COM%d", portNo);
/** 打开指定的串口 */
hComm = CreateFileA(szPort, /** 设备名,COM1,COM2等 */
GENERIC_READ | GENERIC_WRITE, /** 访问模式,可同时读写 */
0, /** 共享模式,0表示不共享 */
NULL, /** 安全性设置,一般使用NULL */
OPEN_EXISTING, /** 该参数表示设备必须存在,否则创建失败 */
0,
0);
return hComm != INVALID_HANDLE_VALUE;
}
void Serial::ClosePort() {
/** 如果有串口被打开,关闭它 */
if (hComm != INVALID_HANDLE_VALUE) {
CloseHandle(hComm);
hComm = INVALID_HANDLE_VALUE;
}
}
bool Serial::InitPort(UINT portNo, UINT baud, char parity, UINT databits, UINT stopsbits, DWORD dwCommEvents) {
/** 临时变量,将制定参数转化为字符串形式,以构造DCB结构 */
char szDCBparam[50];
sprintf_s(szDCBparam, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopsbits);
if (!openPort(portNo)){
cout << "open error!" << endl;
return false;
}
BOOL bIsSuccess = TRUE;
COMMTIMEOUTS CommTimeouts;
CommTimeouts.ReadIntervalTimeout = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 0;
if (bIsSuccess) {
bIsSuccess = SetCommTimeouts(hComm, &CommTimeouts);
} else {
cout << "SetCommTimeouts error!" << endl;
}
DCB dcb;
if (bIsSuccess) {
/** 获取当前串口配置参数,并且构造串口DCB参数 */
bIsSuccess = GetCommState(hComm, &dcb);
bIsSuccess = BuildCommDCB(szDCBparam, &dcb);
if (!bIsSuccess) {
cout << "Create dcb fail with "<< GetLastError() << endl;
}
/** 开启RTS flow控制 */
dcb.fRtsControl = RTS_CONTROL_ENABLE;
}
if (bIsSuccess) {
/** 使用DCB参数配置串口状态 */
bIsSuccess = SetCommState(hComm, &dcb);
if (!bIsSuccess) {
cout << "SetCommState error!" << endl;
}
}
/** 清空串口缓冲区 */
PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
return bIsSuccess;
}
UINT Serial::GetBytesInCOM() const {
DWORD dwError = 0; /** 错误码 */
COMSTAT comstat; /** COMSTAT结构体,记录通信设备的状态信息 */
memset(&comstat, 0, sizeof(COMSTAT));
UINT BytesInQue = 0;
/** 在调用ReadFile和WriteFile之前,通过本函数清除以前遗留的错误标志 */
if (ClearCommError(hComm, &dwError, &comstat)) {
BytesInQue = comstat.cbInQue; /** 获取在输入缓冲区中的字节数 */
}
return BytesInQue;
}
bool Serial::WriteData(const unsigned char* pData, unsigned int length) {
if (hComm == INVALID_HANDLE_VALUE) {
ErrorHandler();
return false;
}
/** 向缓冲区写入指定量的数据 */
BOOL bResult = TRUE;
DWORD BytesToSend = 0;
bResult = WriteFile(hComm, pData, length, &BytesToSend, NULL);
if (!bResult) {
DWORD dwError = GetLastError();
/** 清空串口缓冲区 */
PurgeComm(hComm, PURGE_RXCLEAR | PURGE_RXABORT);
ErrorHandler();
return false;
}
return true;
}
bool Serial::ReadData(unsigned char *buffer, unsigned int length) {
if (hComm == INVALID_HANDLE_VALUE) {
ErrorHandler();
return false;
}
/** 从缓冲区读取length字节的数据 */
BOOL bResult = TRUE;
DWORD totalRead = 0, onceRead = 0;
while (totalRead < length) {
bResult = ReadFile(hComm, buffer, length-totalRead, &onceRead, NULL);
totalRead += onceRead;
if ((!bResult)) {
/** 获取错误码,可以根据该错误码查出错误原因 */
DWORD dwError = GetLastError();
/** 清空串口缓冲区 */
PurgeComm(hComm, PURGE_RXCLEAR | PURGE_RXABORT);
ErrorHandler();
return false;
}
}
return bResult;
}
#elif defined(Linux) || defined(Darwin)
#include <string.h>
using namespace std;
string get_uart_dev_name() {
FILE *ls = popen("ls /dev/ttyCH341USB* --color=never", "r");
char name[20] = {0};
fscanf(ls, "%s", name);
return name;
}
Serial::Serial(int nSpeed, char nEvent, int nBits, int nStop) :
nSpeed(nSpeed), nEvent(nEvent), nBits(nBits), nStop(nStop) {
if (wait_uart) {
LOGM("Wait for serial be ready!");
while (!InitPort(nSpeed, nEvent, nBits, nStop));
LOGM("Port set successfully!");
} else {
if (InitPort(nSpeed, nEvent, nBits, nStop)) {
LOGM("Port set successfully!");
} else {
LOGE("Port set fail!");
}
}
}
Serial::~Serial() {
close(fd);
fd = -1;
}
bool Serial::InitPort(int nSpeed, char nEvent, int nBits, int nStop) {
string name = get_uart_dev_name();
if (name == "") {
return false;
}
if ((fd = open(name.data(), O_RDWR)) < 0) {
return false;
}
if (set_opt(fd, nSpeed, nEvent, nBits, nStop) < 0) {
return false;
}
return true;
}
//int GetBytesInCOM() const {
//
//}
bool Serial::WriteData(const unsigned char *pData, unsigned int length) {
int cnt = 0, curr = 0;
if (fd <= 0){
if(wait_uart){
InitPort(nSpeed, nEvent, nBits, nStop);
}
return false;
}
while ((curr = write(fd, pData + cnt, length - cnt)) > 0 && (cnt += curr) < length);
if (curr < 0) {
LOGE("Serial offline!");
close(fd);
if (wait_uart) {
InitPort(nSpeed, nEvent, nBits, nStop);
}
return false;
}
return true;
}
bool Serial::ReadData(unsigned char *buffer, unsigned int length) {
int cnt = 0, curr = 0;
while ((curr = read(fd, buffer + cnt, length - cnt)) > 0 && (cnt += curr) < length);
if (curr < 0) {
LOGE("Serial offline!");
close(fd);
if (wait_uart) {
InitPort(nSpeed, nEvent, nBits, nStop);
}
return false;
}
return true;
}
int Serial::set_opt(int fd, int nSpeed, char nEvent, int nBits, int nStop) {
termios newtio{}, oldtio{};
if (tcgetattr(fd, &oldtio) != 0) {
perror("SetupSerial 1");
return -1;
}
bzero(&newtio, sizeof(newtio));
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
switch (nBits) {
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
default:
break;
}
switch (nEvent) {
case 'O': //奇校验
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
case 'E': //偶校验
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break;
case 'N': //无校验
newtio.c_cflag &= ~PARENB;
break;
default:
break;
}
switch (nSpeed) {
case 2400:
cfsetispeed(&newtio, B2400);
cfsetospeed(&newtio, B2400);
break;
case 4800:
cfsetispeed(&newtio, B4800);
cfsetospeed(&newtio, B4800);
break;
case 9600:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
case 115200:
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
break;
default:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
}
if (nStop == 1) {
newtio.c_cflag &= ~CSTOPB;
} else if (nStop == 2) {
newtio.c_cflag |= CSTOPB;
}
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
tcflush(fd, TCIFLUSH);
if ((tcsetattr(fd, TCSANOW, &newtio)) != 0) {
perror("com set error");
return -1;
}
printf("set done!\n");
return 0;
}
#endif /* switch os */

36
others/src/systime.cpp Normal file
View File

@@ -0,0 +1,36 @@
//
// Created by xinyang on 19-7-31.
//
#include <systime.h>
#if defined(Linux) || defined(Darwin)
static systime getsystime(){
timeval tv;
gettimeofday(&tv, nullptr);
return tv.tv_usec / 1000.0 + tv.tv_sec * 1000.0;
}
void getsystime(systime &t) {
static systime time_base = getsystime();
timeval tv;
gettimeofday(&tv, nullptr);
t = tv.tv_usec / 1000.0 + tv.tv_sec * 1000.0 - time_base;
}
#elif defined(Windows)
void getsystime(systime &t){
SYSTEMTIME tv;
GetLocalTime(&tv);
t = tv.wMilliseconds + tv.wSecond * 1000.0;
}
#else
#error "nonsupport platform."
#endif
double getTimeIntervalms(const systime &now, const systime &last) {
return now - last;
}