初次提交
This commit is contained in:
commit
45e634bd7c
1
AbilitySDK
Submodule
1
AbilitySDK
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit e20893b78a520157efeb28aeadb5914c5435d8f8
|
||||||
46
ConveyorBeltAbility/include/conveyorBeltAbility.hpp
Normal file
46
ConveyorBeltAbility/include/conveyorBeltAbility.hpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "ability_sdk/AbilityStub.hpp"
|
||||||
|
#include "conveyorBeltGrpcServer.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ConveyorBeltAbility : public ability_sdk::AbilityInterface {
|
||||||
|
public:
|
||||||
|
ConveyorBeltStatus status;
|
||||||
|
|
||||||
|
void OnStart() override{
|
||||||
|
cout << "OnStart" << endl;
|
||||||
|
g_GLOBAL_STATUS = STATUS_STANDBY;
|
||||||
|
sendStateMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnConnect() override {
|
||||||
|
cout << "OnConnect" << endl;
|
||||||
|
thread t_abilityserver(&AbilityTemplate::create_ability_server, this);
|
||||||
|
t_abilityserver.detach();
|
||||||
|
g_GLOBAL_STATUS = STATUS_RUNNING;
|
||||||
|
sendStateMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDisconnect() override {
|
||||||
|
cout << "OnDisconnect" << endl;
|
||||||
|
ability_server->Shutdown();
|
||||||
|
ability_cq->Shutdown();
|
||||||
|
g_GLOBAL_STATUS = STATUS_SUSPEND;
|
||||||
|
g_abilityPort = 0;
|
||||||
|
sendStateMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTerminate() override {
|
||||||
|
cout << "OnTerminate" << endl;
|
||||||
|
g_GLOBAL_STATUS = STATUS_TERMINATE;
|
||||||
|
sendStateMsg();
|
||||||
|
// exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取端口
|
||||||
|
int abilityPort() const override {
|
||||||
|
return g_abilityPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GRPC 服务端
|
||||||
|
void create_ability_server();
|
||||||
|
};
|
||||||
57
ConveyorBeltAbility/include/conveyorBeltGrpcServer.h
Normal file
57
ConveyorBeltAbility/include/conveyorBeltGrpcServer.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef CONVEYOR_BELT_GRPC_SERVER_H_
|
||||||
|
#define CONVEYOR_BELT_GRPC_SERVER_H_
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "conveyorBelt.grpc.pb.h"
|
||||||
|
#include "conveyorBelt.pb.h"
|
||||||
|
#include "conveyorBeltControlUnit.h"
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <grpcpp/grpcpp.h>
|
||||||
|
|
||||||
|
using grpc::Server;
|
||||||
|
using grpc::ServerBuilder;
|
||||||
|
using grpc::ServerContext;
|
||||||
|
using grpc::Status;
|
||||||
|
|
||||||
|
using ConveyorBelt::ConveyorBeltService;
|
||||||
|
|
||||||
|
typedef int RunningState;
|
||||||
|
|
||||||
|
class ConveyorBeltServer : public ConveyorBeltService::Service {
|
||||||
|
private:
|
||||||
|
/* data */
|
||||||
|
public:
|
||||||
|
::grpc::Status open(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::SpeedInfo* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) override;
|
||||||
|
::grpc::Status close(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::DeviceID* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) override;
|
||||||
|
::grpc::Status setSpeed(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::SpeedInfo* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) override;
|
||||||
|
::grpc::Status setDirection(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::DirectionInfo* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) override;
|
||||||
|
::grpc::Status getWorkState(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::DeviceID* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) override;
|
||||||
|
ConveyorBeltServer();
|
||||||
|
~ConveyorBeltServer();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
35
ConveyorBeltAbility/protos/abilityProto.proto
Normal file
35
ConveyorBeltAbility/protos/abilityProto.proto
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
package abilityUnit;
|
||||||
|
option java_package = "ability.proto";
|
||||||
|
option java_outer_classname = "AbilityProto";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
|
||||||
|
service Ability{
|
||||||
|
rpc Start(StartInfo) returns (Response){}
|
||||||
|
rpc Connect (ConnectInfo) returns (Response) {}
|
||||||
|
rpc Disconnect(DisconnectInfo) returns (Response){}
|
||||||
|
rpc Terminate(TerminateInfo) returns (Response){}
|
||||||
|
}
|
||||||
|
|
||||||
|
message Response{
|
||||||
|
int32 code = 1;
|
||||||
|
string msg = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartInfo{
|
||||||
|
int32 timestamp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ConnectInfo{
|
||||||
|
string ip = 1;
|
||||||
|
int32 port = 2;
|
||||||
|
int32 timestamp = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DisconnectInfo{
|
||||||
|
int32 timestamp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TerminateInfo{
|
||||||
|
int32 timestamp = 1;
|
||||||
|
}
|
||||||
29
ConveyorBeltAbility/protos/conveyorBelt.proto
Normal file
29
ConveyorBeltAbility/protos/conveyorBelt.proto
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
package ConveyorBelt;
|
||||||
|
option java_multiple_files = true;
|
||||||
|
option java_package = "ConveyorBelt.proto";
|
||||||
|
|
||||||
|
service ConveyorBeltService {
|
||||||
|
rpc open(SpeedInfo) returns (Response) {}
|
||||||
|
rpc close(DeviceID) returns (Response) {}
|
||||||
|
rpc setSpeed(SpeedInfo) returns (Response) {}
|
||||||
|
rpc setDirection(DirectionInfo) returns (Response) {}
|
||||||
|
rpc getWorkState(DeviceID) returns (Response) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
message Response{
|
||||||
|
int32 code = 1;
|
||||||
|
string msg = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SpeedInfo{
|
||||||
|
float speed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeviceID{
|
||||||
|
int32 conveyorBeltId = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DirectionInfo{
|
||||||
|
int32 direction = 1;
|
||||||
|
}
|
||||||
13
ConveyorBeltAbility/protos/makefile
Normal file
13
ConveyorBeltAbility/protos/makefile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
all: abilityProto.grpc.pb.cc abilityProto.grpc.pb.h conveyorBelt.grpc.pb.cc conveyorBelt.grpc.pb.h abilityProto.pb.cc abilityProto.pb.h conveyorBelt.pb.cc conveyorBelt.pb.h
|
||||||
|
abilityProto.grpc.pb.cc abilityProto.grpc.pb.h:
|
||||||
|
protoc -I . --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` abilityProto.proto
|
||||||
|
conveyorBelt.grpc.pb.cc conveyorBelt.grpc.pb.h:
|
||||||
|
protoc -I . --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` conveyorBelt.proto
|
||||||
|
|
||||||
|
abilityProto.pb.cc abilityProto.pb.h:
|
||||||
|
protoc -I . --cpp_out=. abilityProto.proto
|
||||||
|
conveyorBelt.pb.cc conveyorBelt.pb.h:
|
||||||
|
protoc -I . --cpp_out=. conveyorBelt.proto
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm abilityProto.grpc.pb.cc abilityProto.grpc.pb.h conveyorBelt.grpc.pb.cc conveyorBelt.grpc.pb.h abilityProto.pb.cc abilityProto.pb.h conveyorBelt.pb.cc conveyorBelt.pb.h
|
||||||
21
ConveyorBeltAbility/src/conveyorBeltAbility.cpp
Normal file
21
ConveyorBeltAbility/src/conveyorBeltAbility.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "conveyorBeltAbility.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// GRPC 服务端
|
||||||
|
void ConveyorBeltAbility::create_ability_server() {
|
||||||
|
ConveyorBeltServer service_ability;
|
||||||
|
ServerBuilder builder;
|
||||||
|
builder.AddListeningPort("0.0.0.0:0", grpc::InsecureServerCredentials(), &g_abilityPort);
|
||||||
|
cout << "add listening port" << endl;
|
||||||
|
builder.RegisterService(&service_ability);
|
||||||
|
cout << "register service" << endl;
|
||||||
|
ability_cq = builder.AddCompletionQueue();
|
||||||
|
ability_server = builder.BuildAndStart();
|
||||||
|
std::cout << "Server listening on port: " << g_abilityPort << std::endl;
|
||||||
|
sendStateMsg();
|
||||||
|
ability_server->Wait();
|
||||||
|
std::cout << "finish ipc server" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
97
ConveyorBeltAbility/src/conveyorGrpcServer.cpp
Normal file
97
ConveyorBeltAbility/src/conveyorGrpcServer.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include "conveyorBeltGrpcServer.h"
|
||||||
|
|
||||||
|
ConveyorBeltControlUnit controlUnit;
|
||||||
|
|
||||||
|
::grpc::Status ConveyorBeltServer::open(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::SpeedInfo* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) {
|
||||||
|
std::cout << "grpc call open start" << std::endl;
|
||||||
|
if (controlUnit.getWorkState() == 0) {
|
||||||
|
response->set_code(-1);
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
float speed = request->speed();
|
||||||
|
if (speed > 0.16) {
|
||||||
|
response->set_code(-1);
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
controlUnit.init();
|
||||||
|
int ret = controlUnit.setSpeed(speed);
|
||||||
|
if (ret < 0) {
|
||||||
|
response->set_code(-1);
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
controlUnit.startConveyorBelt();
|
||||||
|
std::thread workThread(&ConveyorBeltControlUnit::conveyorBeltWorkingProcess, &controlUnit);
|
||||||
|
workThread.detach();
|
||||||
|
std::cout << "grpc call open finish" << std::endl;
|
||||||
|
response->set_code(0);
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
::grpc::Status ConveyorBeltServer::close(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::DeviceID* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) {
|
||||||
|
std::cout << "grpc call close start" << std::endl;
|
||||||
|
if (controlUnit.getWorkState() < 0) {
|
||||||
|
response->set_code(-1);
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
controlUnit.stopConveyorBelt();
|
||||||
|
std::cout << "grpc call close finish" << std::endl;
|
||||||
|
response->set_code(0);
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
::grpc::Status ConveyorBeltServer::setSpeed(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::SpeedInfo* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) {
|
||||||
|
std::cout << "grpc call set speed start" << std::endl;
|
||||||
|
int ret = controlUnit.setSpeed(request->speed());
|
||||||
|
if (ret < 0) {
|
||||||
|
response->set_code(-1);
|
||||||
|
::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
std::cout << "grpc call set speed finish" << std::endl;
|
||||||
|
response->set_code(0);
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
::grpc::Status ConveyorBeltServer::setDirection(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::DirectionInfo* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) {
|
||||||
|
std::cout << "grpc call set direction start" << std::endl;
|
||||||
|
int ret = controlUnit.setDirection(request->direction());
|
||||||
|
if (ret < 0) {
|
||||||
|
response->set_code(-1);
|
||||||
|
::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
std::cout << "grpc call set direction finish" << std::endl;
|
||||||
|
response->set_code(0);
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
::grpc::Status ConveyorBeltServer::getWorkState(
|
||||||
|
::grpc::ServerContext* context,
|
||||||
|
const ::ConveyorBelt::DeviceID* request,
|
||||||
|
::ConveyorBelt::Response* response
|
||||||
|
) {
|
||||||
|
std::cout << "grpc call get state start" << std::endl;
|
||||||
|
response->set_code(controlUnit.getWorkState());
|
||||||
|
std::cout << "grpc call get state finish" << std::endl;
|
||||||
|
return ::grpc::Status::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConveyorBeltServer::ConveyorBeltServer() {}
|
||||||
|
|
||||||
|
ConveyorBeltServer::~ConveyorBeltServer() {}
|
||||||
17
ConveyorBeltAbility/src/main.cpp
Normal file
17
ConveyorBeltAbility/src/main.cpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include "conveyorBeltAbility.hpp"
|
||||||
|
|
||||||
|
using grpc::Server;
|
||||||
|
using grpc::ServerBuilder;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int selected_port;
|
||||||
|
ConveyorBeltAbility service("conveyorBelt");
|
||||||
|
ServerBuilder builder;
|
||||||
|
builder.AddListeningPort("0.0.0.0:0", grpc::InsecureServerCredentials(), &selected_port);
|
||||||
|
builder.RegisterService(&service);
|
||||||
|
std::unique_ptr<Server> server(builder.BuildAndStart());
|
||||||
|
std::cout << "Server listening on :" << selected_port << std::endl;
|
||||||
|
service.setIpcPort(selected_port);
|
||||||
|
service.runServer();
|
||||||
|
server->Wait();
|
||||||
|
}
|
||||||
14
ConveyorBeltAbility/xmake.lua
Normal file
14
ConveyorBeltAbility/xmake.lua
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
add_rules("mode.debug", "mode.release")
|
||||||
|
add_languages("c++20")
|
||||||
|
|
||||||
|
-- 添加包含路径
|
||||||
|
add_includedirs("include")
|
||||||
|
add_includedirs("../ConveyorBeltControlUnit/include")
|
||||||
|
|
||||||
|
-- 添加源文件
|
||||||
|
add_files("src/*.cpp")
|
||||||
|
add_files("protos/*.proto", {proto_rootdir = "protos", proto_grpc_cpp_plugin = true})
|
||||||
|
|
||||||
|
-- 添加依赖
|
||||||
|
add_requires("glog", "grpc", "protobuf-cpp")
|
||||||
|
add_packages("glog", "grpc", "protobuf-cpp")
|
||||||
29
ConveyorBeltControlUnit/include/color.h
Normal file
29
ConveyorBeltControlUnit/include/color.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef UTILS_COLOR_H_
|
||||||
|
#define UTILS_COLOR_H_
|
||||||
|
|
||||||
|
#define EMPTY "\e[0m"
|
||||||
|
#define BLACK "\e[0;30m"
|
||||||
|
#define L_BLACK "\e[1;30m"
|
||||||
|
#define RED "\e[0;31m"
|
||||||
|
#define L_RED "\e[1;31m"
|
||||||
|
#define GREEN "\e[0;32m"
|
||||||
|
#define L_GREEN "\e[1;32m"
|
||||||
|
#define BROWN "\e[0;33m"
|
||||||
|
#define YELLOW "\e[1;33m"
|
||||||
|
#define BLUE "\e[0;34m"
|
||||||
|
#define L_BLUE "\e[1;34m"
|
||||||
|
#define PURPLE "\e[0;35m"
|
||||||
|
#define L_PURPLE "\e[1;35m"
|
||||||
|
#define CYAN "\e[0;36m"
|
||||||
|
#define L_CYAN "\e[1;36m"
|
||||||
|
#define GRAY "\e[0;37m"
|
||||||
|
#define WHITE "\e[1;37m"
|
||||||
|
#define BOLD "\e[1m"
|
||||||
|
#define UNDERLINE "\e[4m"
|
||||||
|
#define BLINK "\e[5m"
|
||||||
|
#define REVERSE "\e[7m"
|
||||||
|
#define HIDE "\e[8m"
|
||||||
|
#define CLEAR "\e[2J"
|
||||||
|
#define CLRLINE "\r\e[K"
|
||||||
|
|
||||||
|
#endif // UTILS_COLOR_H_
|
||||||
75
ConveyorBeltControlUnit/include/conveyorBeltControlUnit.h
Normal file
75
ConveyorBeltControlUnit/include/conveyorBeltControlUnit.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "color.h"
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
#include <shared_mutex>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <time.h>
|
||||||
|
extern "C" {
|
||||||
|
#include <modbus/modbus.h>
|
||||||
|
#include <wiringPi.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
// 传送带控制单元
|
||||||
|
|
||||||
|
class ConveyorBeltControlUnit {
|
||||||
|
private:
|
||||||
|
// 所有的输入端口配置为内部上拉,低有效
|
||||||
|
// 悬空时为高,视为逻辑0
|
||||||
|
// 外部拉低时,视为逻辑1
|
||||||
|
const int IN_LOGIC_0 = 1;
|
||||||
|
const int IN_LOGIC_1 = 0;
|
||||||
|
|
||||||
|
// 输出端口为Push-Pull模式
|
||||||
|
// 逻辑开时输出高电平
|
||||||
|
// 逻辑低时输出低电平
|
||||||
|
const int OUT_ON = 1;
|
||||||
|
const int OUT_OFF = 0;
|
||||||
|
|
||||||
|
const int BTN_DIRSWITCH = 26; // 运行方向切换按钮
|
||||||
|
const int BTN_START = 23; // 启动按钮
|
||||||
|
const int BTN_STOP = 24; // 停止按钮
|
||||||
|
const int BTN_ESTOP = 11; // 急停
|
||||||
|
|
||||||
|
int INPUT_FSENSOR = 28; // 正转边沿传感器
|
||||||
|
int INPUT_RSENSOR = 29; // 反转边沿传感器
|
||||||
|
int OUT_FRUN = 14; // 正向运行输出
|
||||||
|
int OUT_RRUN = 10; // 反向运行输出
|
||||||
|
|
||||||
|
// 定义事件
|
||||||
|
const int EVENT_ESTOP_PUSH = 0; // 急停按下(电平触发)
|
||||||
|
const int EVENT_STOP_PUSH = 1; // 停止按下(电平触发)
|
||||||
|
const int EVENT_FSENSOR_OBSTRUCT = 2; // 正转传感器触发(电平触发)
|
||||||
|
const int EVENT_RSENSOR_OBSTRUCT = 3; // 反转传感器触发(电平触发)
|
||||||
|
const int EVENT_DIRSWITCH_RISING = 4; // 切换运转方向(逻辑上升沿触发)
|
||||||
|
const int EVENT_START_RISING = 5; // 开始运行(逻辑上升沿触发)
|
||||||
|
|
||||||
|
// 定义unit工作状态
|
||||||
|
const int RUNNING = 1;
|
||||||
|
const int STANDBY = 0;
|
||||||
|
|
||||||
|
int current_start_signal;
|
||||||
|
int current_stop_signal;
|
||||||
|
int currentMode;
|
||||||
|
float speed;
|
||||||
|
int workState;
|
||||||
|
std::map<int, std::map<int, int>> modeSwitchMap;
|
||||||
|
void action(int event);
|
||||||
|
std::string modeToString();
|
||||||
|
int getWaitCount();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void conveyorBeltWorkingProcess();
|
||||||
|
int init();
|
||||||
|
int setSpeed(float speed);
|
||||||
|
int setDirection(int direction);
|
||||||
|
int startConveyorBelt();
|
||||||
|
int stopConveyorBelt();
|
||||||
|
int getWorkState();
|
||||||
|
ConveyorBeltControlUnit(/* args */);
|
||||||
|
~ConveyorBeltControlUnit();
|
||||||
|
};
|
||||||
216
ConveyorBeltControlUnit/src/conveyorBeltControlUnit.cpp
Normal file
216
ConveyorBeltControlUnit/src/conveyorBeltControlUnit.cpp
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
#include "conveyorBeltControlUnit.h"
|
||||||
|
// 定义状态
|
||||||
|
const int MODE_INIT = 0; // 初始状态
|
||||||
|
const int MODE_FRUN = 1; // 正转运行状态
|
||||||
|
const int MODE_RRUN = 2; // 反转运行状态
|
||||||
|
const int MODE_CLOSING_STEP1 = 3; // 进入关闭状态步骤1
|
||||||
|
const int MODE_CLOSING_STEP2 = 4; // 进入关闭状态步骤2
|
||||||
|
const int MODE_STOP = 5;
|
||||||
|
int ConveyorBeltControlUnit::getWaitCount() {
|
||||||
|
return 2 * (0.8 / speed) / 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ConveyorBeltControlUnit::modeToString() {
|
||||||
|
switch (currentMode) {
|
||||||
|
case MODE_INIT: return "MODE_INIT";
|
||||||
|
case MODE_FRUN: return "MODE_FRUN";
|
||||||
|
case MODE_RRUN: return "MODE_RRUN";
|
||||||
|
case MODE_CLOSING_STEP1: return "MODE_CLOSING_STEP1";
|
||||||
|
case MODE_CLOSING_STEP2: return "MODE_CLOSING_STEP2";
|
||||||
|
case MODE_STOP: return "MODE_STOP";
|
||||||
|
default: return "INVALID";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConveyorBeltControlUnit::action(int event) {
|
||||||
|
int destMode = modeSwitchMap[currentMode][event];
|
||||||
|
if (destMode == currentMode) { return; }
|
||||||
|
|
||||||
|
switch (destMode) {
|
||||||
|
case MODE_INIT:
|
||||||
|
digitalWrite(OUT_FRUN, OUT_OFF);
|
||||||
|
digitalWrite(OUT_RRUN, OUT_OFF);
|
||||||
|
break;
|
||||||
|
case MODE_FRUN:
|
||||||
|
digitalWrite(OUT_FRUN, OUT_ON);
|
||||||
|
digitalWrite(OUT_RRUN, OUT_OFF);
|
||||||
|
break;
|
||||||
|
case MODE_RRUN:
|
||||||
|
digitalWrite(OUT_FRUN, OUT_OFF);
|
||||||
|
digitalWrite(OUT_RRUN, OUT_ON);
|
||||||
|
break;
|
||||||
|
case MODE_CLOSING_STEP1: break;
|
||||||
|
case MODE_CLOSING_STEP2:
|
||||||
|
digitalWrite(OUT_FRUN, OUT_OFF);
|
||||||
|
digitalWrite(OUT_RRUN, OUT_ON);
|
||||||
|
break;
|
||||||
|
case MODE_STOP:
|
||||||
|
digitalWrite(OUT_FRUN, OUT_OFF);
|
||||||
|
digitalWrite(OUT_RRUN, OUT_OFF);
|
||||||
|
workState = STANDBY;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
currentMode = destMode;
|
||||||
|
DLOG(INFO) << GREEN << "now mode is " << modeToString() << EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConveyorBeltControlUnit::conveyorBeltWorkingProcess() {
|
||||||
|
workState = RUNNING;
|
||||||
|
int waitCount = 0;
|
||||||
|
int count = 0;
|
||||||
|
while (workState == RUNNING) {
|
||||||
|
waitCount = getWaitCount();
|
||||||
|
if (currentMode == MODE_CLOSING_STEP1 || currentMode == MODE_CLOSING_STEP2) {
|
||||||
|
count--;
|
||||||
|
if (count < 0) { action(EVENT_RSENSOR_OBSTRUCT); }
|
||||||
|
}
|
||||||
|
else { count = waitCount; }
|
||||||
|
|
||||||
|
if (current_start_signal == 1) {
|
||||||
|
DLOG(INFO) << YELLOW << "find a start signal" << EMPTY;
|
||||||
|
current_start_signal = 0;
|
||||||
|
action(EVENT_START_RISING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (digitalRead(INPUT_FSENSOR) == IN_LOGIC_1) {
|
||||||
|
// DLOG(INFO) << YELLOW << "find a Fsensor signal" << EMPTY;
|
||||||
|
action(EVENT_FSENSOR_OBSTRUCT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (digitalRead(INPUT_RSENSOR) == IN_LOGIC_1) {
|
||||||
|
// DLOG(INFO) << YELLOW << "find a Rsensor signal" << EMPTY;
|
||||||
|
action(EVENT_RSENSOR_OBSTRUCT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_stop_signal == 1) {
|
||||||
|
DLOG(INFO) << YELLOW << "find a stop signal" << EMPTY;
|
||||||
|
DLOG(INFO) << YELLOW << "wait count is " << waitCount << " last wait count left "
|
||||||
|
<< count << EMPTY;
|
||||||
|
current_stop_signal = 0;
|
||||||
|
action(EVENT_STOP_PUSH);
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltControlUnit::init() {
|
||||||
|
current_start_signal = 0;
|
||||||
|
current_stop_signal = 0;
|
||||||
|
currentMode = MODE_INIT;
|
||||||
|
speed = 0;
|
||||||
|
workState = STANDBY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltControlUnit::setSpeed(float speed) {
|
||||||
|
// if (workState == RUNNING)
|
||||||
|
// {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
int regValue = speed * 62500;
|
||||||
|
modbus_t* ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 2);
|
||||||
|
modbus_set_slave(ctx, 1);
|
||||||
|
if (modbus_connect(ctx) == -1) {
|
||||||
|
fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno));
|
||||||
|
modbus_free(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
DLOG(INFO) << YELLOW << "set speed:" << speed << " set register:" << regValue << EMPTY;
|
||||||
|
int result = modbus_write_register(ctx, 4096, regValue);
|
||||||
|
if (result == -1) {
|
||||||
|
fprintf(stderr, "write failed:%s\n", modbus_strerror(errno));
|
||||||
|
modbus_free(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
DLOG(INFO) << YELLOW << "get result from com" << ":" << result << EMPTY;
|
||||||
|
uint16_t* speedBuffer = (uint16_t*)malloc(sizeof(uint16_t));
|
||||||
|
int getBytes = modbus_read_registers(ctx, 4096, 2, speedBuffer);
|
||||||
|
DLOG(INFO) << YELLOW << "get result from com : " << getBytes << " register:" << *speedBuffer
|
||||||
|
<< EMPTY;
|
||||||
|
this->speed = speed;
|
||||||
|
modbus_free(ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltControlUnit::setDirection(int direction) {
|
||||||
|
if (workState == RUNNING) { return -1; }
|
||||||
|
|
||||||
|
if (direction == 0) {
|
||||||
|
DLOG(INFO) << YELLOW << "set direction to foreward" << EMPTY;
|
||||||
|
INPUT_FSENSOR = 28;
|
||||||
|
INPUT_RSENSOR = 29;
|
||||||
|
OUT_FRUN = 14;
|
||||||
|
OUT_RRUN = 10;
|
||||||
|
}
|
||||||
|
else if (direction == 1) {
|
||||||
|
DLOG(INFO) << YELLOW << "set direction to reversal" << EMPTY;
|
||||||
|
INPUT_FSENSOR = 29;
|
||||||
|
INPUT_RSENSOR = 28;
|
||||||
|
OUT_FRUN = 10;
|
||||||
|
OUT_RRUN = 14;
|
||||||
|
}
|
||||||
|
else { return -1; }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltControlUnit::startConveyorBelt() {
|
||||||
|
current_start_signal = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltControlUnit::stopConveyorBelt() {
|
||||||
|
current_stop_signal = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltControlUnit::getWorkState() {
|
||||||
|
if (workState == RUNNING) { return 0; }
|
||||||
|
else { return -1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
ConveyorBeltControlUnit::ConveyorBeltControlUnit(/* args */) {
|
||||||
|
modeSwitchMap[MODE_INIT]
|
||||||
|
= {{EVENT_START_RISING, MODE_FRUN},
|
||||||
|
{EVENT_FSENSOR_OBSTRUCT, MODE_INIT},
|
||||||
|
{EVENT_RSENSOR_OBSTRUCT, MODE_INIT},
|
||||||
|
{EVENT_STOP_PUSH, MODE_INIT}};
|
||||||
|
modeSwitchMap[MODE_FRUN]
|
||||||
|
= {{EVENT_START_RISING, MODE_FRUN},
|
||||||
|
{EVENT_FSENSOR_OBSTRUCT, MODE_RRUN},
|
||||||
|
{EVENT_RSENSOR_OBSTRUCT, MODE_FRUN},
|
||||||
|
{EVENT_STOP_PUSH, MODE_CLOSING_STEP1}};
|
||||||
|
modeSwitchMap[MODE_RRUN]
|
||||||
|
= {{EVENT_START_RISING, MODE_RRUN},
|
||||||
|
{EVENT_FSENSOR_OBSTRUCT, MODE_RRUN},
|
||||||
|
{EVENT_RSENSOR_OBSTRUCT, MODE_FRUN},
|
||||||
|
{EVENT_STOP_PUSH, MODE_CLOSING_STEP2}};
|
||||||
|
modeSwitchMap[MODE_CLOSING_STEP1]
|
||||||
|
= {{EVENT_START_RISING, MODE_CLOSING_STEP1},
|
||||||
|
{EVENT_FSENSOR_OBSTRUCT, MODE_CLOSING_STEP2},
|
||||||
|
{EVENT_RSENSOR_OBSTRUCT, MODE_STOP},
|
||||||
|
{EVENT_STOP_PUSH, MODE_CLOSING_STEP1}};
|
||||||
|
modeSwitchMap[MODE_CLOSING_STEP2]
|
||||||
|
= {{EVENT_START_RISING, MODE_CLOSING_STEP2},
|
||||||
|
{EVENT_FSENSOR_OBSTRUCT, MODE_CLOSING_STEP2},
|
||||||
|
{EVENT_RSENSOR_OBSTRUCT, MODE_STOP},
|
||||||
|
{EVENT_STOP_PUSH, MODE_CLOSING_STEP2}};
|
||||||
|
wiringPiSetup();
|
||||||
|
pinMode(BTN_START, INPUT);
|
||||||
|
pinMode(BTN_DIRSWITCH, INPUT);
|
||||||
|
pinMode(BTN_STOP, INPUT);
|
||||||
|
pinMode(INPUT_FSENSOR, INPUT);
|
||||||
|
pinMode(INPUT_RSENSOR, INPUT);
|
||||||
|
pullUpDnControl(BTN_START, PUD_UP);
|
||||||
|
pullUpDnControl(BTN_DIRSWITCH, PUD_UP);
|
||||||
|
pullUpDnControl(BTN_STOP, PUD_UP);
|
||||||
|
pullUpDnControl(INPUT_FSENSOR, PUD_UP);
|
||||||
|
pullUpDnControl(INPUT_RSENSOR, PUD_UP);
|
||||||
|
pinMode(OUT_RRUN, OUTPUT);
|
||||||
|
pinMode(OUT_FRUN, OUTPUT);
|
||||||
|
digitalWrite(OUT_FRUN, OUT_OFF);
|
||||||
|
digitalWrite(OUT_RRUN, OUT_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConveyorBeltControlUnit::~ConveyorBeltControlUnit() {}
|
||||||
44
ConveyorBeltController/include/conveyorBeltController.h
Normal file
44
ConveyorBeltController/include/conveyorBeltController.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef BELT_CONTROLLER_H_
|
||||||
|
#define BELT_CONTROLLER_H_
|
||||||
|
#include "color.h"
|
||||||
|
#include "conveyorBeltGrpcClient.hpp"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <httplib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <shared_mutex>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
typedef int ConveyorBeltStatus;
|
||||||
|
|
||||||
|
class ConveyorBeltController {
|
||||||
|
private:
|
||||||
|
std::string ip;
|
||||||
|
ConveyorBeltStatus status;
|
||||||
|
std::shared_mutex mutex_;
|
||||||
|
int IPCPort;
|
||||||
|
int abilityPort;
|
||||||
|
std::map<int, std::string> ipMap;
|
||||||
|
int stateSwitch(ConveyorBeltStatus destState, std::string cmd);
|
||||||
|
int grpcConnect(float speed, int direction);
|
||||||
|
int grpcDisconnect();
|
||||||
|
int grpcCheck();
|
||||||
|
int synchState(std::string json);
|
||||||
|
bool simpleStateCheck();
|
||||||
|
|
||||||
|
public:
|
||||||
|
int handleOpen(float speed, int direction);
|
||||||
|
int handleClose();
|
||||||
|
int handleCheck();
|
||||||
|
void init();
|
||||||
|
void setServerIp(std::string serverIp);
|
||||||
|
ConveyorBeltStatus getCurrentStatus();
|
||||||
|
ConveyorBeltController(/* args */);
|
||||||
|
~ConveyorBeltController();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
82
ConveyorBeltController/include/conveyorBeltGrpcClient.hpp
Normal file
82
ConveyorBeltController/include/conveyorBeltGrpcClient.hpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#ifndef CONVEYOR_BELT_GRPC_CLIENT_H_
|
||||||
|
#define CONVEYOR_BELT_GRPC_CLIENT_H_
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "conveyorBelt.grpc.pb.h"
|
||||||
|
#include "conveyorBelt.pb.h"
|
||||||
|
#include "conveyorBeltControlUnit.h"
|
||||||
|
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <grpc/grpc.h>
|
||||||
|
#include <grpcpp/channel.h>
|
||||||
|
#include <grpcpp/client_context.h>
|
||||||
|
#include <grpcpp/create_channel.h>
|
||||||
|
#include <grpcpp/grpcpp.h>
|
||||||
|
#include <grpcpp/security/credentials.h>
|
||||||
|
|
||||||
|
using grpc::Channel;
|
||||||
|
using grpc::ClientContext;
|
||||||
|
using grpc::ClientReader;
|
||||||
|
using grpc::ClientWriter;
|
||||||
|
using grpc::Status;
|
||||||
|
|
||||||
|
class ConveyorBeltGrpcClient {
|
||||||
|
private:
|
||||||
|
std::unique_ptr<ConveyorBelt::ConveyorBeltService::Stub> stub_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int startWithSpeedAndDirection(float speed, int direction) {
|
||||||
|
DLOG(INFO) << GRAY << "start connect to belt" << EMPTY;
|
||||||
|
ConveyorBelt::SpeedInfo speedInfo;
|
||||||
|
speedInfo.set_speed(speed);
|
||||||
|
ConveyorBelt::DirectionInfo directionInfo;
|
||||||
|
directionInfo.set_direction(direction);
|
||||||
|
ConveyorBelt::Response response;
|
||||||
|
ClientContext context_direction;
|
||||||
|
grpc::Status ret = stub_->setDirection(&context_direction, directionInfo, &response);
|
||||||
|
if (!ret.ok()) {
|
||||||
|
DLOG(INFO) << GRAY << "grpc server cannot connect" << EMPTY;
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
if (response.code() < 0) { return -1; }
|
||||||
|
ClientContext context_start;
|
||||||
|
stub_->open(&context_start, speedInfo, &response);
|
||||||
|
if (response.code() < 0) { return -1; }
|
||||||
|
DLOG(INFO) << GRAY << "finish connect to belt" << EMPTY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int close() {
|
||||||
|
DLOG(INFO) << GRAY << "start connect to belt" << EMPTY;
|
||||||
|
ConveyorBelt::DeviceID id;
|
||||||
|
id.set_conveyorbeltid(0);
|
||||||
|
ClientContext context_close;
|
||||||
|
ConveyorBelt::Response response;
|
||||||
|
stub_->close(&context_close, id, &response);
|
||||||
|
if (response.code() < 0) { return -1; }
|
||||||
|
DLOG(INFO) << GRAY << "start connect to belt" << EMPTY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getWorkState() {
|
||||||
|
DLOG(INFO) << GRAY << "start connect to belt" << EMPTY;
|
||||||
|
ConveyorBelt::DeviceID id;
|
||||||
|
id.set_conveyorbeltid(0);
|
||||||
|
ClientContext context_get;
|
||||||
|
ConveyorBelt::Response response;
|
||||||
|
stub_->getWorkState(&context_get, id, &response);
|
||||||
|
DLOG(INFO) << GRAY << "start connect to belt" << EMPTY;
|
||||||
|
return response.code();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConveyorBeltGrpcClient(std::shared_ptr<Channel> channel)
|
||||||
|
: stub_(ConveyorBelt::ConveyorBeltService::NewStub(channel)) {}
|
||||||
|
|
||||||
|
~ConveyorBeltGrpcClient() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
27
ConveyorBeltController/include/http_server.h
Normal file
27
ConveyorBeltController/include/http_server.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef HTTP_SERVER_H_
|
||||||
|
#define HTTP_SERVER_H_
|
||||||
|
|
||||||
|
#include <httplib.h>
|
||||||
|
#include "color.h"
|
||||||
|
#include "conveyorBeltController.h"
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
class HttpServer {
|
||||||
|
public:
|
||||||
|
void Init();
|
||||||
|
void Run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// http服务器
|
||||||
|
std::shared_ptr<httplib::Server> server;
|
||||||
|
// 控制器
|
||||||
|
std::shared_ptr<ConveyorBeltController> controller;
|
||||||
|
std::map<int, int> directionMap;
|
||||||
|
std::map<int, std::string> ipMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HTTP_SERVER_H_
|
||||||
35
ConveyorBeltController/protos/abilityProto.proto
Normal file
35
ConveyorBeltController/protos/abilityProto.proto
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
package abilityUnit;
|
||||||
|
option java_package = "ability.proto";
|
||||||
|
option java_outer_classname = "AbilityProto";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
|
||||||
|
service Ability{
|
||||||
|
rpc Start(StartInfo) returns (Response){}
|
||||||
|
rpc Connect (ConnectInfo) returns (Response) {}
|
||||||
|
rpc Disconnect(DisconnectInfo) returns (Response){}
|
||||||
|
rpc Terminate(TerminateInfo) returns (Response){}
|
||||||
|
}
|
||||||
|
|
||||||
|
message Response{
|
||||||
|
int32 code = 1;
|
||||||
|
string msg = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartInfo{
|
||||||
|
int32 timestamp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ConnectInfo{
|
||||||
|
string ip = 1;
|
||||||
|
int32 port = 2;
|
||||||
|
int32 timestamp = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DisconnectInfo{
|
||||||
|
int32 timestamp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TerminateInfo{
|
||||||
|
int32 timestamp = 1;
|
||||||
|
}
|
||||||
29
ConveyorBeltController/protos/conveyorBelt.proto
Normal file
29
ConveyorBeltController/protos/conveyorBelt.proto
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
package ConveyorBelt;
|
||||||
|
option java_multiple_files = true;
|
||||||
|
option java_package = "ConveyorBelt.proto";
|
||||||
|
|
||||||
|
service ConveyorBeltService {
|
||||||
|
rpc open(SpeedInfo) returns (Response) {}
|
||||||
|
rpc close(DeviceID) returns (Response) {}
|
||||||
|
rpc setSpeed(SpeedInfo) returns (Response) {}
|
||||||
|
rpc setDirection(DirectionInfo) returns (Response) {}
|
||||||
|
rpc getWorkState(DeviceID) returns (Response) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
message Response{
|
||||||
|
int32 code = 1;
|
||||||
|
string msg = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SpeedInfo{
|
||||||
|
float speed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeviceID{
|
||||||
|
int32 conveyorBeltId = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DirectionInfo{
|
||||||
|
int32 direction = 1;
|
||||||
|
}
|
||||||
13
ConveyorBeltController/protos/makefile
Normal file
13
ConveyorBeltController/protos/makefile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
all: abilityProto.grpc.pb.cc abilityProto.grpc.pb.h conveyorBelt.grpc.pb.cc conveyorBelt.grpc.pb.h abilityProto.pb.cc abilityProto.pb.h conveyorBelt.pb.cc conveyorBelt.pb.h
|
||||||
|
abilityProto.grpc.pb.cc abilityProto.grpc.pb.h:
|
||||||
|
protoc -I . --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` abilityProto.proto
|
||||||
|
conveyorBelt.grpc.pb.cc conveyorBelt.grpc.pb.h:
|
||||||
|
protoc -I . --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` conveyorBelt.proto
|
||||||
|
|
||||||
|
abilityProto.pb.cc abilityProto.pb.h:
|
||||||
|
protoc -I . --cpp_out=. abilityProto.proto
|
||||||
|
conveyorBelt.pb.cc conveyorBelt.pb.h:
|
||||||
|
protoc -I . --cpp_out=. conveyorBelt.proto
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm abilityProto.grpc.pb.cc abilityProto.grpc.pb.h conveyorBelt.grpc.pb.cc conveyorBelt.grpc.pb.h abilityProto.pb.cc abilityProto.pb.h conveyorBelt.pb.cc conveyorBelt.pb.h
|
||||||
245
ConveyorBeltController/src/conveyorBeltController.cpp
Normal file
245
ConveyorBeltController/src/conveyorBeltController.cpp
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
#include "conveyorBeltController.h"
|
||||||
|
|
||||||
|
|
||||||
|
const ConveyorBeltStatus OFFLINE = 0;
|
||||||
|
const ConveyorBeltStatus READY = 1;
|
||||||
|
const ConveyorBeltStatus RUNNING = 2;
|
||||||
|
ConveyorBeltController::ConveyorBeltController(/* args */) {}
|
||||||
|
|
||||||
|
ConveyorBeltController::~ConveyorBeltController() {}
|
||||||
|
|
||||||
|
void ConveyorBeltController::setServerIp(std::string conveyorBeltIp) {
|
||||||
|
this->ip = conveyorBeltIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConveyorBeltController::init() {
|
||||||
|
std::unique_lock<std::shared_mutex> w_lock(mutex_);
|
||||||
|
DLOG(INFO) << WHITE << "init controller state" << EMPTY;
|
||||||
|
status = OFFLINE;
|
||||||
|
abilityPort = 0;
|
||||||
|
IPCPort = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltController::handleCheck() {
|
||||||
|
std::unique_lock<std::shared_mutex> w_lock(mutex_);
|
||||||
|
if (simpleStateCheck()) { return 0; }
|
||||||
|
else { return -1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltController::getCurrentStatus() {
|
||||||
|
std::shared_lock<std::shared_mutex> r_lock(mutex_);
|
||||||
|
if (status == RUNNING) {
|
||||||
|
if (grpcCheck() < 0) { return READY; }
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltController::handleOpen(float speed, int direction) {
|
||||||
|
std::unique_lock<std::shared_mutex> w_lock(mutex_);
|
||||||
|
int result = 0;
|
||||||
|
if (simpleStateCheck() == false) { return -1; }
|
||||||
|
switch (status) {
|
||||||
|
case RUNNING:
|
||||||
|
if (grpcCheck() < 0) {
|
||||||
|
result = grpcConnect(speed, direction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DLOG(INFO) << WHITE << "ConveyorBelt is already running, do not open twice" << EMPTY;
|
||||||
|
break;
|
||||||
|
case READY:
|
||||||
|
DLOG(INFO) << WHITE << "ConveyorBelt is ready, start handle open request" << EMPTY;
|
||||||
|
result = stateSwitch(RUNNING, "connect");
|
||||||
|
if (result < 0) { break; }
|
||||||
|
result = grpcConnect(speed, direction);
|
||||||
|
break;
|
||||||
|
case OFFLINE:
|
||||||
|
DLOG(INFO) << WHITE << "ConveyorBelt is offline, start handle open request" << EMPTY;
|
||||||
|
result = stateSwitch(READY, "start");
|
||||||
|
if (result < 0) { break; }
|
||||||
|
result = stateSwitch(RUNNING, "connect");
|
||||||
|
if (result < 0) { break; }
|
||||||
|
result = grpcConnect(speed, direction);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltController::handleClose() {
|
||||||
|
std::unique_lock<std::shared_mutex> w_lock(mutex_);
|
||||||
|
int result = 0;
|
||||||
|
if (simpleStateCheck() == false) { return -1; }
|
||||||
|
switch (status) {
|
||||||
|
case READY:
|
||||||
|
case OFFLINE:
|
||||||
|
DLOG(INFO) << WHITE << "ConveyorBelt has not been opened, do not close twice" << EMPTY;
|
||||||
|
break;
|
||||||
|
case RUNNING:
|
||||||
|
DLOG(INFO) << WHITE << "ConveyorBelt is now running, start handle ConveyorBelt close"
|
||||||
|
<< EMPTY;
|
||||||
|
result = grpcDisconnect();
|
||||||
|
if (result < 0) { break; }
|
||||||
|
result = stateSwitch(READY, "disconnect");
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConveyorBeltController::simpleStateCheck() {
|
||||||
|
DLOG(INFO) << WHITE << "start simple check" << EMPTY;
|
||||||
|
httplib::Client client(ip, 8080);
|
||||||
|
int mStatus;
|
||||||
|
auto res = client.Get("/api/AbilityRunning");
|
||||||
|
if (res) {
|
||||||
|
DLOG(INFO) << WHITE << "GET response:" << res->status << EMPTY;
|
||||||
|
mStatus = synchState(res->body);
|
||||||
|
if (mStatus == status) {
|
||||||
|
DLOG(INFO) << WHITE
|
||||||
|
<< "simple check pass current status is correct with abilityFrameWork"
|
||||||
|
<< EMPTY;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DLOG(INFO) << WHITE << "simple check failed incorrect state" << EMPTY;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DLOG(ERROR) << "FIRST STEP: can not connect with abilityFrameWork" << EMPTY;
|
||||||
|
DLOG(INFO) << WHITE << "now ConveyorBelt is OFFLINE" << EMPTY;
|
||||||
|
status = OFFLINE;
|
||||||
|
abilityPort = 0;
|
||||||
|
IPCPort = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltController::synchState(std::string json) {
|
||||||
|
Json::Reader reader;
|
||||||
|
Json::Value states;
|
||||||
|
if (reader.parse(json, states)) {
|
||||||
|
for (int i = 0; i < states.size(); i++) {
|
||||||
|
DLOG(INFO) << WHITE << "IPCPort:" << states[i]["IPCPort"].asString()
|
||||||
|
<< " abilityName:" << states[i]["abilityName"].asString() << "status"
|
||||||
|
<< states[i]["status"].asString() << EMPTY;
|
||||||
|
if (states[i]["IPCPort"].asInt() == IPCPort
|
||||||
|
|| (IPCPort == 0 && states[i]["abilityName"].asString().compare("conveyorBelt") == 0
|
||||||
|
)) {
|
||||||
|
if (states[i]["status"].asString() == "RUNNING") {
|
||||||
|
// std::unique_lock<std::shared_mutex> w_lock(mutex_);
|
||||||
|
DLOG(INFO) << WHITE << "now ConveyorBelt is RUNNING" << EMPTY;
|
||||||
|
status = RUNNING;
|
||||||
|
IPCPort = states[i]["IPCPort"].asInt();
|
||||||
|
abilityPort = states[i]["abilityPort"].asInt();
|
||||||
|
if (abilityPort == 0) { return READY; }
|
||||||
|
else { return RUNNING; }
|
||||||
|
}
|
||||||
|
else if (states[i]["status"].asString() == "STANDBY"
|
||||||
|
|| states[i]["status"].asString() == "SUSPEND") {
|
||||||
|
// std::unique_lock<std::shared_mutex> w_lock(mutex_);
|
||||||
|
DLOG(INFO) << WHITE << "now ConveyorBelt is READY" << EMPTY;
|
||||||
|
status = READY;
|
||||||
|
IPCPort = states[i]["IPCPort"].asInt();
|
||||||
|
abilityPort = 0;
|
||||||
|
// w_lock.unlock();
|
||||||
|
return READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// std::unique_lock<std::shared_mutex> w_lock(mutex_);
|
||||||
|
DLOG(INFO) << WHITE << "now ConveyorBelt is OFFLINE" << EMPTY;
|
||||||
|
status = OFFLINE;
|
||||||
|
abilityPort = 0;
|
||||||
|
IPCPort = 0;
|
||||||
|
// w_lock.unlock();
|
||||||
|
return OFFLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ConveyorBeltController::stateSwitch(ConveyorBeltStatus destState, std::string cmd) {
|
||||||
|
httplib::Client client(ip, 8080);
|
||||||
|
httplib::Params params;
|
||||||
|
ConveyorBeltStatus mStatus;
|
||||||
|
// 发出请求
|
||||||
|
params.emplace("abilityName", "conveyorBelt");
|
||||||
|
params.emplace("IPCPort", std::to_string(IPCPort));
|
||||||
|
params.emplace("cmd", cmd);
|
||||||
|
params.emplace("connectIP", "0.0.0.0");
|
||||||
|
params.emplace("connectPort", "0");
|
||||||
|
auto res = client.Post("/api/AbilityRequest", params);
|
||||||
|
if (res) { DLOG(INFO) << WHITE << "POST response:" << res->status << EMPTY; }
|
||||||
|
else {
|
||||||
|
DLOG(ERROR) << "SECOND STEP: can not connect with abilityFrameWork" << EMPTY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
params.clear();
|
||||||
|
// 查询当前状态
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
res = client.Get("/api/AbilityRunning");
|
||||||
|
if (res) {
|
||||||
|
DLOG(INFO) << WHITE << "GET response:" << res->status << EMPTY;
|
||||||
|
mStatus = synchState(res->body);
|
||||||
|
if (mStatus == destState) {
|
||||||
|
DLOG(INFO) << WHITE << "switch state success" << EMPTY;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DLOG(ERROR) << "THIRD STEP: can not connect with abilityFrameWork" << EMPTY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
}
|
||||||
|
DLOG(ERROR) << "ability state change failed" << EMPTY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltController::grpcConnect(float speed, int direction) {
|
||||||
|
if (abilityPort == 0) { return -1; }
|
||||||
|
|
||||||
|
std::string url;
|
||||||
|
url.append(ip);
|
||||||
|
url.append(":");
|
||||||
|
url.append(std::to_string(abilityPort));
|
||||||
|
DLOG(INFO) << WHITE << url << EMPTY;
|
||||||
|
int result;
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
ConveyorBeltGrpcClient client(grpc::CreateChannel(url, grpc::InsecureChannelCredentials()));
|
||||||
|
result = client.startWithSpeedAndDirection(speed, direction);
|
||||||
|
if (result != -2) { break; }
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltController::grpcDisconnect() {
|
||||||
|
if (abilityPort == 0) { return -1; }
|
||||||
|
std::string url;
|
||||||
|
url.append(ip);
|
||||||
|
url.append(":");
|
||||||
|
url.append(std::to_string(abilityPort));
|
||||||
|
DLOG(INFO) << WHITE << url << EMPTY;
|
||||||
|
ConveyorBeltGrpcClient client(grpc::CreateChannel(url, grpc::InsecureChannelCredentials()));
|
||||||
|
if (client.close() == -1) {
|
||||||
|
DLOG(ERROR) << "grpc call failed" << EMPTY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConveyorBeltController::grpcCheck() {
|
||||||
|
if (abilityPort == 0) { return -1; }
|
||||||
|
std::string url;
|
||||||
|
url.append(ip);
|
||||||
|
url.append(":");
|
||||||
|
url.append(std::to_string(abilityPort));
|
||||||
|
DLOG(INFO) << WHITE << url << EMPTY;
|
||||||
|
ConveyorBeltGrpcClient client(grpc::CreateChannel(url, grpc::InsecureChannelCredentials()));
|
||||||
|
if (client.getWorkState() == -1) {
|
||||||
|
DLOG(ERROR) << "grpc work state is false" << EMPTY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
116
ConveyorBeltController/src/http_server.cpp
Normal file
116
ConveyorBeltController/src/http_server.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include "http_server.h"
|
||||||
|
|
||||||
|
void HttpServer::Init() {
|
||||||
|
FLAGS_logtostderr = 1;
|
||||||
|
DLOG(INFO) << L_GREEN << "init http server" << EMPTY;
|
||||||
|
// 初始化 http 服务器
|
||||||
|
this->server = std::make_shared<httplib::Server>();
|
||||||
|
// 初始化控制器
|
||||||
|
this->controller = std::make_shared<ConveyorBeltController>();
|
||||||
|
// 初始化控制器
|
||||||
|
this->controller->init();
|
||||||
|
ipMap[108] = "192.168.1.217";
|
||||||
|
ipMap[109] = "192.168.1.218";
|
||||||
|
directionMap[108] = 0;
|
||||||
|
directionMap[109] = 0;
|
||||||
|
|
||||||
|
this->server->Get(
|
||||||
|
"/api/processGet",
|
||||||
|
[this](const httplib::Request& req, httplib::Response& res) {
|
||||||
|
DLOG(INFO) << L_BLUE << "httpserver receive: method: GET URL: /api/processGet"
|
||||||
|
<< EMPTY;
|
||||||
|
std::string conveyorBeltId;
|
||||||
|
int result = 200;
|
||||||
|
Json::Value response;
|
||||||
|
try {
|
||||||
|
conveyorBeltId = req.get_param_value("id");
|
||||||
|
DLOG(INFO) << YELLOW << "GET param id:" << conveyorBeltId << EMPTY;
|
||||||
|
}
|
||||||
|
catch (const std::exception&) {
|
||||||
|
res.status = 400; // Bad Request
|
||||||
|
response["status"] = 400;
|
||||||
|
response["processStatus"] = this->controller->getCurrentStatus();
|
||||||
|
res.set_content(response.toStyledString(), "application/json");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::map<int, std::string>::iterator it = ipMap.find(std::stoi(conveyorBeltId));
|
||||||
|
if (it != ipMap.end()) { this->controller->setServerIp(it->second); }
|
||||||
|
else {
|
||||||
|
response["status"] = 400;
|
||||||
|
response["processStatus"] = this->controller->getCurrentStatus();
|
||||||
|
res.set_content(response.toStyledString(), "application/json");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->controller->handleCheck() < 0) { result = 400; }
|
||||||
|
response["status"] = result;
|
||||||
|
response["processStatus"] = this->controller->getCurrentStatus();
|
||||||
|
res.set_content(response.toStyledString(), "application/json");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this->server->Post(
|
||||||
|
"/api/processPost",
|
||||||
|
[this](const httplib::Request& req, httplib::Response& res) {
|
||||||
|
DLOG(INFO) << L_BLUE << "httpserver receive: method: POST URL: /api/processPost"
|
||||||
|
<< EMPTY;
|
||||||
|
DLOG(INFO) << YELLOW << req.get_header_value("Content-Type") << EMPTY;
|
||||||
|
Json::Value root;
|
||||||
|
int status = 200;
|
||||||
|
if (req.get_header_value("Content-Type").find("application/json")
|
||||||
|
!= std::string::npos) {
|
||||||
|
Json::Reader reader;
|
||||||
|
bool success = reader.parse(req.body, root);
|
||||||
|
if (!success) {
|
||||||
|
DLOG(ERROR) << "json parse error";
|
||||||
|
res.status = 400;
|
||||||
|
status = 400;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DLOG(INFO) << YELLOW << "id:" << root["id"].asInt()
|
||||||
|
<< " action:" << root["action"].asInt()
|
||||||
|
<< " speed:" << root["speed"].asFloat() << EMPTY;
|
||||||
|
Json::Value result;
|
||||||
|
std::map<int, std::string>::iterator it = ipMap.find(root["id"].asInt());
|
||||||
|
if (it != ipMap.end()) { this->controller->setServerIp(it->second); }
|
||||||
|
else {
|
||||||
|
result["status"] = 400;
|
||||||
|
result["processStatus"] = this->controller->getCurrentStatus();
|
||||||
|
res.set_content(result.toStyledString(), "application/json");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (root["action"].asInt() == 1) {
|
||||||
|
DLOG(INFO) << YELLOW << "http server try to handle open" << EMPTY;
|
||||||
|
std::thread openThread(
|
||||||
|
&ConveyorBeltController::handleOpen,
|
||||||
|
this->controller,
|
||||||
|
root["speed"].asFloat(),
|
||||||
|
directionMap[root["id"].asInt()]
|
||||||
|
);
|
||||||
|
openThread.detach();
|
||||||
|
}
|
||||||
|
else if (root["action"].asInt() == 0) {
|
||||||
|
DLOG(INFO) << YELLOW << "http server try to handle close" << EMPTY;
|
||||||
|
std::thread closeThread(
|
||||||
|
&ConveyorBeltController::handleClose, this->controller
|
||||||
|
);
|
||||||
|
closeThread.detach();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DLOG(INFO) << YELLOW << "invalid action code" << EMPTY;
|
||||||
|
status = 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { status = 400; }
|
||||||
|
Json::Value result;
|
||||||
|
result["status"] = status;
|
||||||
|
result["processStatus"] = this->controller->getCurrentStatus();
|
||||||
|
res.set_content(result.toStyledString(), "application/json");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpServer::Run() {
|
||||||
|
DLOG(INFO) << L_GREEN << "http server start" << EMPTY;
|
||||||
|
this->server->listen("0.0.0.0", 8001);
|
||||||
|
}
|
||||||
9
ConveyorBeltController/src/main.cpp
Normal file
9
ConveyorBeltController/src/main.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "http_server.h"
|
||||||
|
|
||||||
|
// 控制器在http服务器中启动
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
google::InitGoogleLogging(argv[0]);
|
||||||
|
HttpServer server;
|
||||||
|
server.Init();
|
||||||
|
server.Run();
|
||||||
|
}
|
||||||
1
Package/crds/ConveyorBeltAbility.crd.yaml
Normal file
1
Package/crds/ConveyorBeltAbility.crd.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
version: 0.1.0
|
||||||
1
conveyor-belt-cpp-old-待删除
Submodule
1
conveyor-belt-cpp-old-待删除
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit bcd2e16ad2c44769c056f4b774e1697c7e52be5e
|
||||||
Loading…
Reference in New Issue
Block a user