
Raspberry Pi 4 Model B Rev 1.2
https://velog.io/@mouse0429/openCVVisual-Studio-OpenCV-%EC%84%A4%EC%B9%98 참고
sudo apt install libopencv-dev
g++ test.cpp -o test `pkg-config --cflags --libs opencv4`
git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
./build
g++ motor_test.cpp -o motor_test -lwiringPi
테스트는 편의상 사설 네트워크에서 진행.
TCP 통신, 차후 필요에 따라 UDP로 변경 예정
#include <iostream>
#include <vector>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <opencv2/opencv.hpp>
#pragma comment(lib, "ws2_32.lib")
#define PORT 5006
#define BUFFER_SIZE 65536
// Receive precisely sized data
bool receiveExact(SOCKET sock, char* buffer, int size) {
int totalReceived = 0;
while (totalReceived < size) {
int bytesReceived = recv(sock, buffer + totalReceived, size - totalReceived, 0);
if (bytesReceived <= 0) {
return false;
}
totalReceived += bytesReceived;
}
return true;
}
int main() {
WSADATA wsaData;
SOCKET serverSocket, clientSocket;
struct sockaddr_in serverAddress, clientAddress;
int clientLen = sizeof(clientAddress);
// Init WinSock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "WSAStartup failed with error: " << WSAGetLastError() << std::endl;
return -1;
}
// Create TCP socket
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET) {
std::cerr << "Socket creation failed with error: " << WSAGetLastError() << std::endl;
WSACleanup();
return -1;
}
// Set server address
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = INADDR_ANY;
serverAddress.sin_port = htons(PORT);
// Bind socket
if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR) {
std::cerr << "Bind failed with error: " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return -1;
}
// Wait for client
if (listen(serverSocket, 1) == SOCKET_ERROR) {
std::cerr << "Listen failed with error: " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return -1;
}
std::cout << "Waiting for connection..." << std::endl;
// Accept client
clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientLen);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "Accept failed with error: " << WSAGetLastError() << std::endl;
closesocket(serverSocket);
WSACleanup();
return -1;
}
std::cout << "Client connected!" << std::endl;
while (true) {
// Get data size
uint32_t frameSize = 0;
if (!receiveExact(clientSocket, (char*)&frameSize, sizeof(frameSize))) {
std::cerr << "Failed to receive data size" << std::endl;
break;
}
frameSize = ntohl(frameSize); // Network-byte order into host order
// Receive one frame
std::vector<char> buffer(frameSize);
if (!receiveExact(clientSocket, buffer.data(), frameSize)) {
std::cerr << "Failed to receive frame data" << std::endl;
break;
}
// Decode one frame into JPEG
std::vector<uchar> data(buffer.begin(), buffer.end());
cv::Mat frame = cv::imdecode(data, cv::IMREAD_COLOR);
if (frame.empty()) {
std::cerr << "Failed to decode frame" << std::endl;
continue;
}
cv::imshow("Received Video", frame);
// Exit for ESC
if (cv::waitKey(1) == 27) {
break;
}
}
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
return 0;
}
#include <iostream>
#include <vector>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
#include <opencv2/opencv.hpp>
#define SERVER_IP "192.168.0.27"
#define PORT 5006
#define BUFFER_SIZE 65536
int main() {
int sockfd;
struct sockaddr_in serverAddress;
// Create Socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("Socket creation failed");
return -1;
}
// Set server address
memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(PORT);
// Convert server address into IP address
if (inet_pton(AF_INET, SERVER_IP, &serverAddress.sin_addr) <= 0) {
perror("Invalid address/ Address not supported");
close(sockfd);
return -1;
}
// Connect server
if (connect(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
perror("Connection failed");
close(sockfd);
return -1;
}
std::cout << "Connected to the server!" << std::endl;
// Set camera
cv::VideoCapture cap(0); // Camera0
if (!cap.isOpened()) {
std::cerr << "Error: Unable to open camera" << std::endl;
close(sockfd);
return -1;
}
std::cout << "Streaming video to server..." << std::endl;
while (true) {
cv::Mat frame;
cap >> frame; // Capture frame
if (frame.empty()) {
std::cerr << "Error: Captured empty frame" << std::endl;
break;
}
// Encode frame into JPEG
std::vector<uchar> buffer;
// std::vector<int> compressionParams = {cv::IMWRITE_JPEG_QUALITY, 50}; // 압축 품질 50%
if (!cv::imencode(".jpg", frame, buffer)) {
std::cerr << "Error: Failed to encode frame" << std::endl;
continue;
}
// 데이터 크기 전송 (4바이트)
uint32_t dataSize = htonl(buffer.size());
if (send(sockfd, &dataSize, sizeof(dataSize), 0) < 0) {
perror("Failed to send data size");
break;
}
// 데이터 전송
if (send(sockfd, buffer.data(), buffer.size(), 0) < 0) {
perror("Failed to send frame data");
break;
}
// ESC 키로 종료
if (cv::waitKey(1) == 27) {
break;
}
}
// 자원 해제
cap.release();
close(sockfd);
return 0;
}
#include <wiringPi.h>
#include <softPwm.h>
#include <iostream>
#include <unistd.h> // for sleep()
#include <csignal> // for signal()
// BCM Pin numbers -> WiringPi Pin number
#define PWMA 1 // GPIO 18
#define AIN1 3 // GPIO 22
#define AIN2 2 // GPIO 27
#define PWMB 4 // GPIO 23
#define BIN1 6 // GPIO 25
#define BIN2 5 // GPIO 24
void cleanupMotors() {
softPwmWrite(PWMA, 0);
softPwmWrite(PWMB, 0);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
std::cout << "Motors stopped and GPIO cleaned up." << std::endl;
}
void signalHandler(int signum) {
std::cout << "\nInterrupt signal (" << signum << ") received. Stopping motors..." << std::endl;
cleanupMotors();
exit(signum);
}
int main() {
// Init WiringPi
if (wiringPiSetup() == -1) {
std::cerr << "WiringPi initialization failed!" << std::endl;
return 1;
}
// Set pin modes
pinMode(PWMA, PWM_OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(PWMB, PWM_OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
// Generate software PWM
softPwmCreate(PWMA, 0, 100); // PWM pin, Init 0, Max 100
softPwmCreate(PWMB, 0, 100);
// Register sighandle for SIGINT(ctrl + c)
signal(SIGINT, signalHandler);
try {
while (true) {
// Set forward
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
softPwmWrite(PWMA, 100); // 왼쪽 모터 100% 출력
softPwmWrite(PWMB, 100); // 오른쪽 모터 100% 출력
sleep(1);
// 정지 설정
softPwmWrite(PWMA, 0);
softPwmWrite(PWMB, 0);
sleep(1);
}
} catch (...) {
std::cerr << "An error occurred. Cleaning up..." << std::endl;
cleanupMotors();
}
return 0;
}