Files
Loongson_2k0300_SmartCar/udp_receive/udp_receive.cpp
T

176 lines
4.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* @Author: ilikara 3435193369@qq.com
* @Date: 2025-03-11 02:38:15
* @LastEditors: ilikara 3435193369@qq.com
* @LastEditTime: 2025-03-29 01:39:17
* @FilePath: /2k300_smartcar/udp_receive/udp_receive.cpp
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstdint>
#include <string.h>
#include <opencv2/opencv.hpp>
#include <thread>
#include "MotorController.h"
#include "PwmController.h"
#include "GPIO.h"
#include <iomanip>
cv::VideoCapture cap;
std::string directory = "./image";
int saved_frame_count;
void streamCapture(void)
{
cv::Mat frame;
while (1)
{
cap.read(frame);
if (frame.empty())
{
std::cerr << "Save Error: Frame is empty." << std::endl;
continue;
}
// 构建文件名
std::ostringstream filename;
filename << directory << "/image_" << std::setw(5) << std::setfill('0') << saved_frame_count << ".jpg";
saved_frame_count++;
// 保存图像
cv::imwrite(filename.str(), frame);
}
return;
}
GPIO mortorEN(73);
MotorController *motorController[2] = {nullptr, nullptr};
PwmController servo(1, 0);
void Init()
{
mortorEN.setDirection("out");
mortorEN.setValue(1);
const int pwmchip[2] = {8, 8};
const int pwmnum[2] = {2, 1};
const int gpioNum[2] = {12, 13};
const int encoder_pwmchip[2] = {0, 3};
const int encoder_gpioNum[2] = {75, 72};
const int encoder_dir[2] = {1, -1};
const unsigned int period_ns = 50000; // 20 kHz
for (int i = 0; i < 2; ++i)
{
motorController[i] = new MotorController(pwmchip[i], pwmnum[i], gpioNum[i], period_ns,
0, 0, 0, 0,
encoder_pwmchip[i], encoder_gpioNum[i], encoder_dir[i]);
motorController[i]->updateduty(0);
}
servo.setPeriod(3040000);
servo.setDutyCycle(1520000);
servo.enable();
}
int main()
{
// 打开默认摄像头(设备编号 0
cap.open(0);
// 检查摄像头是否成功打开
if (!cap.isOpened())
{
printf("无法打开摄像头\n");
return -1;
}
cap.set(cv::CAP_PROP_FRAME_WIDTH, 320); // 宽度
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 240); // 高度
cap.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G')); // 视频流格式
cap.set(cv::CAP_PROP_AUTO_EXPOSURE, -1); // 设置自动曝光
std::thread camworker = std::thread(streamCapture);
Init();
const int PORT = 8888;
const int BUFFER_SIZE = 2 * sizeof(float);
// 创建UDP Socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
std::cerr << "Socket creation failed" << std::endl;
return -1;
}
// 绑定地址和端口
sockaddr_in server_addr{};
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
if (bind(sockfd, (sockaddr *)&server_addr, sizeof(server_addr)))
{
std::cerr << "Bind failed" << std::endl;
close(sockfd);
return -1;
}
// 接收数据
sockaddr_in client_addr{};
socklen_t client_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
while (true)
{
ssize_t bytes_received = recvfrom(
sockfd,
buffer,
BUFFER_SIZE,
0,
(sockaddr *)&client_addr,
&client_len);
if (bytes_received == BUFFER_SIZE)
{
// 解析第一个float
uint32_t temp1;
memcpy(&temp1, buffer, 4);
temp1 = ntohl(temp1);
float val1;
memcpy(&val1, &temp1, 4);
// 解析第二个float
uint32_t temp2;
memcpy(&temp2, buffer + 4, 4);
temp2 = ntohl(temp2);
float val2;
memcpy(&val2, &temp2, 4);
std::cout << "收到数据: "
<< "滑块1=" << val1
<< ", 滑块2=" << val2
<< std::endl;
double servoduty_ns = (val1) / 100 * servo.readPeriod() + 1520000;
servo.setDutyCycle(servoduty_ns);
motorController[0]->updateduty(val2);
motorController[1]->updateduty(val2);
}
else
{
std::cerr << "Invalid data size" << std::endl;
}
}
close(sockfd);
return 0;
}