mirror of
https://github.com/eddyem/BTA_utils.git
synced 2026-08-15 20:49:27 +03:00
Compare commits
3 Commits
e7b345b377
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 11f3553344 | |||
| a996bae853 | |||
| 25d35e2294 |
@@ -47,6 +47,7 @@ $(CLIENT) : $(COBJDIR) $(COBJS)
|
|||||||
|
|
||||||
|
|
||||||
$(SERVER) : DEFINES += -DSERVER
|
$(SERVER) : DEFINES += -DSERVER
|
||||||
|
$(SERVER) : LDFLAGS += -lmodbus
|
||||||
$(SERVER) : $(SOBJDIR) $(SOBJS)
|
$(SERVER) : $(SOBJDIR) $(SOBJS)
|
||||||
@echo -e "\tLD $(SERVER)"
|
@echo -e "\tLD $(SERVER)"
|
||||||
$(CC) $(LDFLAGS) $(SOBJS) -o $(SERVER)
|
$(CC) $(LDFLAGS) $(SOBJS) -o $(SERVER)
|
||||||
@@ -58,16 +59,17 @@ $(COBJDIR):
|
|||||||
@mkdir $(COBJDIR)
|
@mkdir $(COBJDIR)
|
||||||
|
|
||||||
ifneq ($(MAKECMDGOALS),clean)
|
ifneq ($(MAKECMDGOALS),clean)
|
||||||
-include $(DEPS)
|
-include $(SDEPS)
|
||||||
|
-include $(CDEPS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(COBJDIR)/%.o: %.c
|
$(COBJDIR)/%.o: %.c
|
||||||
@echo -e "\tCC $<"
|
@echo -e "\tCC $<"
|
||||||
$(CC) -MD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $<
|
$(CC) -MP -MMD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $<
|
||||||
|
|
||||||
$(SOBJDIR)/%.o: %.c
|
$(SOBJDIR)/%.o: %.c
|
||||||
@echo -e "\t\tCC $<"
|
@echo -e "\t\tCC $<"
|
||||||
$(CC) -MD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $<
|
$(CC) -MP -MMD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@echo -e "\t\tCLEAN"
|
@echo -e "\t\tCLEAN"
|
||||||
|
|||||||
@@ -161,9 +161,10 @@ static sl_sock_hresult_e send_motor_command(SSL *ssl, const char *cmd, value_t *
|
|||||||
// emergency stop motors
|
// emergency stop motors
|
||||||
static void stop_all(SSL *ssl){
|
static void stop_all(SSL *ssl){
|
||||||
int ntries = 0;
|
int ntries = 0;
|
||||||
value_t speed = {.type = ARG_TYPE_DOUBLE, .d = 0.};
|
//value_t speed = {.type = ARG_TYPE_DOUBLE, .d = 0.};
|
||||||
while(ntries < 5){
|
while(ntries < 5){
|
||||||
if(RESULT_OK == send_motor_command(ssl, cmd_speed, &speed, NULL)) break;
|
//if(RESULT_OK == send_motor_command(ssl, cmd_speed, &speed, NULL)) break;
|
||||||
|
if(RESULT_OK == send_motor_command(ssl, cmd_stop, NULL, NULL)) break;
|
||||||
++ntries;
|
++ntries;
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
}
|
}
|
||||||
@@ -328,18 +329,9 @@ static char *time_asc(double t){
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void clientproc(SSL_CTX *ctx, int fd){
|
// open SSL connection for client
|
||||||
FNAME();
|
static SSL *openConn(SSL_CTX *ctx, int fd){
|
||||||
SSL *ssl;
|
SSL *ssl = SSL_new(ctx);
|
||||||
char buf[1024];
|
|
||||||
int bytes;
|
|
||||||
sdat.mode |= 0200; // allow W
|
|
||||||
sdat.atflag = 0; // clear SHM_RDONLY
|
|
||||||
if(!get_shm_block(&sdat, ClientSide)){
|
|
||||||
LOGERR("Can't get SHM block");
|
|
||||||
ERRX("Can't get SHM block");
|
|
||||||
}
|
|
||||||
ssl = SSL_new(ctx);
|
|
||||||
SSL_set_fd(ssl, fd);
|
SSL_set_fd(ssl, fd);
|
||||||
int c = SSL_connect(ssl);
|
int c = SSL_connect(ssl);
|
||||||
if(c < 0){
|
if(c < 0){
|
||||||
@@ -351,6 +343,21 @@ void clientproc(SSL_CTX *ctx, int fd){
|
|||||||
LOGERR("Can't make socket nonblocking");
|
LOGERR("Can't make socket nonblocking");
|
||||||
ERRX("ioctl()");
|
ERRX("ioctl()");
|
||||||
}
|
}
|
||||||
|
return ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// run main client process
|
||||||
|
void clientproc(SSL_CTX *ctx, int fd){
|
||||||
|
FNAME();
|
||||||
|
char buf[1024];
|
||||||
|
SSL *ssl = openConn(ctx, fd);
|
||||||
|
if(!ssl) return;
|
||||||
|
sdat.mode |= 0200; // allow W
|
||||||
|
sdat.atflag = 0; // clear SHM_RDONLY
|
||||||
|
if(!get_shm_block(&sdat, ClientSide)){
|
||||||
|
LOGERR("Can't get SHM block");
|
||||||
|
ERRX("Can't get SHM block");
|
||||||
|
}
|
||||||
while(isrunning){
|
while(isrunning){
|
||||||
if(!process_system(ssl)){
|
if(!process_system(ssl)){
|
||||||
LOGERR("Motors error");
|
LOGERR("Motors error");
|
||||||
@@ -360,7 +367,7 @@ void clientproc(SSL_CTX *ctx, int fd){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// clear receiving buffer (TODO: parse it?)
|
// clear receiving buffer (TODO: parse it?)
|
||||||
bytes = SSL_nbread(ssl, buf, sizeof(buf));
|
int bytes = SSL_nbread(ssl, buf, sizeof(buf)-1);
|
||||||
if(bytes > 0){
|
if(bytes > 0){
|
||||||
buf[bytes] = 0;
|
buf[bytes] = 0;
|
||||||
fprintf(stderr, "Received: \"%s\"\n", buf);
|
fprintf(stderr, "Received: \"%s\"\n", buf);
|
||||||
@@ -373,3 +380,40 @@ void clientproc(SSL_CTX *ctx, int fd){
|
|||||||
DBG("Exit; isrunning=%d", isrunning);
|
DBG("Exit; isrunning=%d", isrunning);
|
||||||
SSL_free(ssl);
|
SSL_free(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// run in terminal mode
|
||||||
|
void terminal(SSL_CTX *ctx, int fd){
|
||||||
|
FNAME();
|
||||||
|
char buf[1024], *lptr = NULL;
|
||||||
|
size_t N = 0;
|
||||||
|
SSL *ssl = openConn(ctx, fd);
|
||||||
|
if(!ssl) return;
|
||||||
|
int printed = FALSE;
|
||||||
|
while(isrunning){
|
||||||
|
if(!printed){
|
||||||
|
printf("> ");
|
||||||
|
fflush(stdout);
|
||||||
|
printed = TRUE;
|
||||||
|
}
|
||||||
|
if(sl_canread(0)){
|
||||||
|
ssize_t L = getline(&lptr, &N, stdin);
|
||||||
|
if(L > (ssize_t)(sizeof(buf)-1)) WARNX("String too long!");
|
||||||
|
else if(L > 0){
|
||||||
|
SSL_write(ssl, lptr, L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int bytes = 0;
|
||||||
|
while((bytes = SSL_nbread(ssl, buf, sizeof(buf)-1))){
|
||||||
|
if(bytes > 0){
|
||||||
|
buf[bytes] = 0;
|
||||||
|
printf("< %s\n", buf);
|
||||||
|
}else{
|
||||||
|
LOGWARN("Server disconnected or other error");
|
||||||
|
ERRX("Disconnected");
|
||||||
|
}
|
||||||
|
usleep(10000);
|
||||||
|
printed = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SSL_free(ssl);
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,3 +21,4 @@
|
|||||||
#include "sslsock.h"
|
#include "sslsock.h"
|
||||||
|
|
||||||
void clientproc(SSL_CTX *ctx, int fd);
|
void clientproc(SSL_CTX *ctx, int fd);
|
||||||
|
void terminal(SSL_CTX *ctx, int fd);
|
||||||
|
|||||||
@@ -46,8 +46,10 @@ glob_pars G = {
|
|||||||
.key = DEFKEY,
|
.key = DEFKEY,
|
||||||
.ca = DEFCA,
|
.ca = DEFCA,
|
||||||
.acc_timeout = 1.,
|
.acc_timeout = 1.,
|
||||||
|
#ifdef CLIENT
|
||||||
.T_sync_lost = 5.,
|
.T_sync_lost = 5.,
|
||||||
.speedchk_interval = 10.,
|
.speedchk_interval = 10.,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -66,12 +68,16 @@ static sl_option_t cmdlnopts[] = {
|
|||||||
{"ca", NEED_ARG, NULL, 'a', arg_string, APTR(&G.ca), _("path to SSL ca - base cert (default:" DEFCA ")")},
|
{"ca", NEED_ARG, NULL, 'a', arg_string, APTR(&G.ca), _("path to SSL ca - base cert (default:" DEFCA ")")},
|
||||||
{"timeout", NEED_ARG, NULL, 't', arg_double, APTR(&G.acc_timeout),_("network timeout, s (default: 1)")},
|
{"timeout", NEED_ARG, NULL, 't', arg_double, APTR(&G.acc_timeout),_("network timeout, s (default: 1)")},
|
||||||
#ifdef SERVER
|
#ifdef SERVER
|
||||||
|
{"emulation",NO_ARGS, NULL, 'e', arg_int, APTR(&G.emulmode), _("run server in emulation mode")},
|
||||||
|
{"serialdev",NEED_ARG, NULL, 'd', arg_string, APTR(&G.serialpath),_("path to RS-485 device")},
|
||||||
|
{"serialspeed",NEED_ARG,NULL, 's', arg_int, APTR(&G.serialspeed),_("speed of serial device")},
|
||||||
#endif
|
#endif
|
||||||
#ifdef CLIENT
|
#ifdef CLIENT
|
||||||
{"mottmout",NEED_ARG, NULL, 'M', arg_double, APTR(&G.speedchk_interval), _("interval of motor's speed checking, s (default: 10)")},
|
{"mottmout",NEED_ARG, NULL, 'M', arg_double, APTR(&G.speedchk_interval), _("interval of motor's speed checking, s (default: 10)")},
|
||||||
{"server", NEED_ARG, NULL, 's', arg_string, APTR(&G.serverhost), _("server node, IP:port")},
|
{"server", NEED_ARG, NULL, 's', arg_string, APTR(&G.serverhost), _("server node, IP:port")},
|
||||||
{"lostsync",NEED_ARG, NULL, 'L', arg_double, APTR(&G.T_sync_lost),_("\"lost synchronization\" timeout, s (default: 5)")},
|
{"lostsync",NEED_ARG, NULL, 'L', arg_double, APTR(&G.T_sync_lost),_("\"lost synchronization\" timeout, s (default: 5)")},
|
||||||
{"emulation",NO_ARGS, NULL, 'e', arg_int, APTR(&G.emulmode), _("run even in emulation mode")},
|
{"emulation",NO_ARGS, NULL, 'e', arg_int, APTR(&G.emulmode), _("run client even in emulation mode")},
|
||||||
|
{"terminal",NO_ARGS, NULL, 'T', arg_int, APTR(&G.terminal), _("run client in terminal mode")},
|
||||||
#endif
|
#endif
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,8 +36,6 @@
|
|||||||
typedef struct{
|
typedef struct{
|
||||||
int emulmode; // emulation mode: don't check server & run in model mode
|
int emulmode; // emulation mode: don't check server & run in model mode
|
||||||
double acc_timeout; // network timeout, s
|
double acc_timeout; // network timeout, s
|
||||||
double T_sync_lost; // "lost synchronization" timeout, s
|
|
||||||
double speedchk_interval;// interval of motors' speed checking (resend command if don't reach yet)
|
|
||||||
char *pidfile; // name of PID file
|
char *pidfile; // name of PID file
|
||||||
char *logfile; // logging to this file
|
char *logfile; // logging to this file
|
||||||
char *cert; // sertificate
|
char *cert; // sertificate
|
||||||
@@ -45,8 +43,15 @@ typedef struct{
|
|||||||
char *port; // port number
|
char *port; // port number
|
||||||
int verbose; // logfile verbose level
|
int verbose; // logfile verbose level
|
||||||
char *ca; // ca
|
char *ca; // ca
|
||||||
|
#ifdef SERVER
|
||||||
|
int serialspeed; // speed of serial device
|
||||||
|
char *serialpath; // path to RS-485 device
|
||||||
|
#endif
|
||||||
#ifdef CLIENT
|
#ifdef CLIENT
|
||||||
|
int terminal; // run client in terminal mode
|
||||||
|
double speedchk_interval;// interval of motors' speed checking (resend command if don't reach yet)
|
||||||
char *serverhost; // server IP address
|
char *serverhost; // server IP address
|
||||||
|
double T_sync_lost; // "lost synchronization" timeout, s
|
||||||
#endif
|
#endif
|
||||||
} glob_pars;
|
} glob_pars;
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ int start_daemon(){
|
|||||||
int port = atoi(G.port);
|
int port = atoi(G.port);
|
||||||
if(port < 1024 || port > 65535){
|
if(port < 1024 || port > 65535){
|
||||||
LOGERR("Wrong port value: %d", port);
|
LOGERR("Wrong port value: %d", port);
|
||||||
|
WARNX("Wrong port value: %d", port);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
FILE *f = fopen(G.cert, "r");
|
FILE *f = fopen(G.cert, "r");
|
||||||
@@ -66,12 +67,14 @@ int start_daemon(){
|
|||||||
f = fopen(G.key, "r");
|
f = fopen(G.key, "r");
|
||||||
if(!f) ERR("Can't open certificate key file %s", G.key);
|
if(!f) ERR("Can't open certificate key file %s", G.key);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
#ifdef EBUG
|
DBG("cert: %s, key: %s\n", G.cert, G.key);
|
||||||
printf("cert: %s, key: %s\n", G.cert, G.key);
|
|
||||||
#endif
|
|
||||||
#ifdef CLIENT
|
#ifdef CLIENT
|
||||||
//DBG("server: %s", G.serverhost);
|
//DBG("server: %s", G.serverhost);
|
||||||
if(!G.serverhost) ERRX("Point server name");
|
if(!G.serverhost) ERRX("Point server name");
|
||||||
|
if(G.terminal){
|
||||||
|
isrunning = TRUE;
|
||||||
|
return open_socket();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if(G.logfile){
|
if(G.logfile){
|
||||||
int lvl = LOGLEVEL_WARN + G.verbose;
|
int lvl = LOGLEVEL_WARN + G.verbose;
|
||||||
|
|||||||
57
BTA_dome_modbus/esq770.h
Normal file
57
BTA_dome_modbus/esq770.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the sslsosk project.
|
||||||
|
* Copyright 2026 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Registers and their fields for ESQ-770 frequency converter
|
||||||
|
|
||||||
|
// command register (rw)
|
||||||
|
#define REG_CMD 0x2000 // 8192
|
||||||
|
// set frequency (rw)
|
||||||
|
#define REG_FREQ_SET 0x3000 // 12288
|
||||||
|
// torque limit (rw)
|
||||||
|
#define REG_TORQUE_LIMIT 0x3006 // 12294
|
||||||
|
#define REG_BRAKE_TORQUE_LIMIT 0x3007 // 12295
|
||||||
|
// status (r)
|
||||||
|
#define REG_STATUS_MAIN 0x6000 // 24576
|
||||||
|
#define REG_STATUS_EXT 0x6001 // 24577
|
||||||
|
// monitoring (r)
|
||||||
|
#define REG_OUTPUT_FREQ 0xA201 // 41473 (freq * 100)
|
||||||
|
#define REG_OUTPUT_CURRENT 0xA204 // 41476 (current * 10)
|
||||||
|
#define REG_MOTOR_SPEED 0xA205 // 41477 (speed, depends on settings)
|
||||||
|
|
||||||
|
// REG_CMD bits
|
||||||
|
#define CMD_FORWARD 1
|
||||||
|
#define CMD_REVERSE 2
|
||||||
|
#define CMD_STOP 5
|
||||||
|
#define CMD_FAST_STOP 6
|
||||||
|
#define CMD_RESET_FAULT 7
|
||||||
|
|
||||||
|
// REG_STATUS_MAIN bits
|
||||||
|
#define STATUS_CW 1
|
||||||
|
#define STATUS_CCW 2
|
||||||
|
#define STATUS_STOP 3
|
||||||
|
#define STATUS_ERR 4
|
||||||
|
#define STATUS_LOW_V 5
|
||||||
|
|
||||||
|
// REG_STATUS_EXT bit
|
||||||
|
#define STATUS_READY_MASK 0x01
|
||||||
|
|
||||||
|
#define FREQ_SCALE 100.
|
||||||
|
#define CURRENT_SCALE 10.
|
||||||
|
|
||||||
@@ -25,11 +25,12 @@
|
|||||||
|
|
||||||
// Handlers in this list MUST be in sortered order (by name)!!!
|
// Handlers in this list MUST be in sortered order (by name)!!!
|
||||||
#define HANDLERS_LIST() \
|
#define HANDLERS_LIST() \
|
||||||
NEW_HANDLER(motcurrent, "motor current") \
|
NEW_HANDLER(motcurrent, "maximal motor current") \
|
||||||
NEW_HANDLER(motnum, "active motor number for status requests") \
|
NEW_HANDLER(motnum, "active motor number for status requests") \
|
||||||
NEW_HANDLER(motspeed, "motor speed") \
|
NEW_HANDLER(motspeed, "motor speed") \
|
||||||
NEW_HANDLER(motstatus, "motor status") \
|
NEW_HANDLER(motstatus, "motor status") \
|
||||||
NEW_HANDLER(speed, "speed setter") \
|
NEW_HANDLER(speed, "speed setter") \
|
||||||
|
NEW_HANDLER(stop, "stop motors") \
|
||||||
|
|
||||||
/*NEW_HANDLER(current, "current setter") \*/
|
/*NEW_HANDLER(current, "current setter") \*/
|
||||||
/*NEW_HANDLER(relay, "relay command") \*/
|
/*NEW_HANDLER(relay, "relay command") \*/
|
||||||
|
|||||||
@@ -24,6 +24,5 @@
|
|||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
sl_init();
|
sl_init();
|
||||||
parse_args(argc, argv);
|
parse_args(argc, argv);
|
||||||
DBG("START");
|
|
||||||
return start_daemon();
|
return start_daemon();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <modbus/modbus.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
#include "motors.h"
|
#include "motors.h"
|
||||||
|
#include "esq770.h"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
ðÒÏÔÏËÏÌ (s - ÓÅÔÔÅÒ, g - getteer):
|
ðÒÏÔÏËÏÌ (s - ÓÅÔÔÅÒ, g - getteer):
|
||||||
@@ -34,19 +36,72 @@ speed=xx - (sg)
|
|||||||
current=xx - (sg) ÕÓÔÁ×ËÁ ÔÏËÁ
|
current=xx - (sg) ÕÓÔÁ×ËÁ ÔÏËÁ
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static modbus_t *modbus_ctx = NULL;
|
||||||
|
static motor_state_t motstates[MOTORS_AMOUNT] = {0};
|
||||||
|
|
||||||
// set points
|
// set points
|
||||||
static double currentSet = 0., speedSet = 0.;
|
static double currentSet = DEFAULT_CURRENT, speedSet = 0.;
|
||||||
|
// flags for main routine
|
||||||
|
static union{
|
||||||
|
struct{
|
||||||
|
uint32_t change_speed : 1;
|
||||||
|
uint32_t change_current : 1;
|
||||||
|
uint32_t stop : 1;
|
||||||
|
};
|
||||||
|
uint32_t all;
|
||||||
|
} flags = {0};
|
||||||
|
|
||||||
|
// emulation mode parameters
|
||||||
|
/*static struct{
|
||||||
|
double tlast;
|
||||||
|
|
||||||
|
} emulpar = {0};*/
|
||||||
|
|
||||||
// current motor for status etc. getters (0..MOTORS_AMOUNT-1)
|
// current motor for status etc. getters (0..MOTORS_AMOUNT-1)
|
||||||
static int motindex = 0;
|
static int motindex = 0;
|
||||||
|
|
||||||
// stop all
|
// close modbus connection
|
||||||
void motors_stop(){
|
static void motors_close_m(){
|
||||||
|
if(modbus_ctx){
|
||||||
|
modbus_close(modbus_ctx);
|
||||||
|
modbus_free(modbus_ctx);
|
||||||
|
modbus_ctx = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void motors_close_e(){ // stub for emulation mode
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// close modbus connection
|
// open modbus @ given speed; return FALSE if failed
|
||||||
void modbus_close(){
|
static int motors_open_m(const char *path, int speed){
|
||||||
;
|
if(speed < 1200 || !path){
|
||||||
|
WARNX("Point path and right speed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if(modbus_ctx) motors_close_m();
|
||||||
|
modbus_ctx = modbus_new_rtu(path, speed, 'N', 8, 1);
|
||||||
|
if(!modbus_ctx){
|
||||||
|
WARNX("Can't open device %s @ %d", path, speed);
|
||||||
|
LOGERR("Can't open device %s @ %d", path, speed);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
modbus_set_response_timeout(modbus_ctx, 0, 50000); // 50ms response timeout
|
||||||
|
if(modbus_connect(modbus_ctx) < 0){
|
||||||
|
WARNX("Can't connect to device %s", path);
|
||||||
|
LOGERR("Can't connect to device %s", path);
|
||||||
|
motors_close_m();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
static int motors_open_e(const char _U_ *path, int _U_ speed){ // stub for emulation mode
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// stop all
|
||||||
|
void motors_stop(){
|
||||||
|
flags.stop = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// current setpoint getter
|
// current setpoint getter
|
||||||
@@ -56,7 +111,9 @@ double motors_get_curntsetpoint(){
|
|||||||
// set setpoint of current
|
// set setpoint of current
|
||||||
int motors_set_curntsetpoint(double val){
|
int motors_set_curntsetpoint(double val){
|
||||||
if(val < 0. || val > MAX_CURRENT) return FALSE;
|
if(val < 0. || val > MAX_CURRENT) return FALSE;
|
||||||
// do something
|
DBG("Change max current to %g", val);
|
||||||
|
currentSet = val;
|
||||||
|
flags.change_current = 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +125,9 @@ double motors_get_speedsetpoint(){
|
|||||||
int motors_set_speedsetpoint(double val){
|
int motors_set_speedsetpoint(double val){
|
||||||
double absval = fabs(val);
|
double absval = fabs(val);
|
||||||
if(absval > MAX_SPEED) return FALSE;
|
if(absval > MAX_SPEED) return FALSE;
|
||||||
// do something
|
DBG("Change speed setpoint to %g", val);
|
||||||
|
speedSet = val;
|
||||||
|
flags.change_speed = 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,18 +143,133 @@ int motors_set_activenum(int N){
|
|||||||
|
|
||||||
// get current value for active motor
|
// get current value for active motor
|
||||||
int motors_get_actcurrent(double *val){
|
int motors_get_actcurrent(double *val){
|
||||||
if(val) *val = 0.;
|
if(val) *val = motstates[motindex].current;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get speed for active motor
|
// get speed for active motor
|
||||||
int motors_get_actspeed(double *val){
|
int motors_get_actspeed(double *val){
|
||||||
if(val) *val = 0.;
|
if(val) *val = motstates[motindex].speed;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get status for active motor
|
// get status for active motor
|
||||||
int motors_get_actstatus(int *val){
|
int motors_get_actstatus(int *val){
|
||||||
if(val) *val = 0;
|
if(val) *val = motstates[motindex].status;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// main motors processing routine
|
||||||
|
static void motors_process_m(){
|
||||||
|
static int curN = 0, errctr = 0;
|
||||||
|
static int error_cnt[MOTORS_AMOUNT] = {0};
|
||||||
|
if(!modbus_ctx || errctr > 100){
|
||||||
|
LOGERR("Modbus not inited or other error!");
|
||||||
|
ERRX("Modbus not inited or other error!");
|
||||||
|
}
|
||||||
|
if(flags.all){
|
||||||
|
if(-1 == modbus_set_slave(modbus_ctx, 0)) goto reg_error;
|
||||||
|
if(flags.stop){
|
||||||
|
speedSet = 0.;
|
||||||
|
// send command stop
|
||||||
|
if(-1 == modbus_write_register(modbus_ctx, REG_CMD, CMD_STOP)) goto reg_error;
|
||||||
|
}
|
||||||
|
if(flags.change_current){
|
||||||
|
// TODO: send command "max current"?
|
||||||
|
}
|
||||||
|
if(flags.change_speed){
|
||||||
|
// send command "set speed"
|
||||||
|
uint16_t dir = (speedSet > 0.) ? CMD_FORWARD : CMD_REVERSE;
|
||||||
|
uint16_t freq = (uint16_t)(fabs(speedSet) * FREQ_SCALE);
|
||||||
|
if(-1 == modbus_write_register(modbus_ctx, REG_FREQ_SET, freq)) goto reg_error;
|
||||||
|
if(-1 == modbus_write_register(modbus_ctx, REG_CMD, dir)) goto reg_error;
|
||||||
|
}
|
||||||
|
flags.all = 0;
|
||||||
|
}
|
||||||
|
// set slave N
|
||||||
|
if(-1 == modbus_set_slave(modbus_ctx, curN)) goto reg_error;
|
||||||
|
// ask for speed/status/current
|
||||||
|
uint16_t regs[2];
|
||||||
|
if(-1 == modbus_read_registers(modbus_ctx, REG_STATUS_MAIN, 2, regs)){
|
||||||
|
if((++error_cnt[curN]) > MAX_ERRORS){ // not answer - set MOT_OFF status
|
||||||
|
motstates[curN].status = MOT_OFF;
|
||||||
|
LOGDBG("Motor %d not responce", curN);
|
||||||
|
}
|
||||||
|
if(++curN >= MOTORS_AMOUNT) curN = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error_cnt[curN] = 0;
|
||||||
|
switch(regs[0]){
|
||||||
|
case STATUS_CW:
|
||||||
|
case STATUS_CCW:
|
||||||
|
motstates[curN].status = MOT_RUN;
|
||||||
|
break;
|
||||||
|
case STATUS_STOP:
|
||||||
|
motstates[curN].status = MOT_SLEEP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
motstates[curN].status = MOT_ERROR;
|
||||||
|
}
|
||||||
|
if(regs[1] & STATUS_READY_MASK) motstates[curN].status = MOT_ERROR;
|
||||||
|
if(motstates[curN].status == MOT_ERROR) modbus_write_register(modbus_ctx, REG_CMD, CMD_RESET_FAULT);
|
||||||
|
if(-1 == modbus_read_registers(modbus_ctx, REG_OUTPUT_FREQ, 1, ®s[0])) regs[0] = 0;
|
||||||
|
if(-1 == modbus_read_registers(modbus_ctx, REG_OUTPUT_CURRENT, 1, ®s[1])) regs[1] = 0;
|
||||||
|
motstates[curN].speed = ((double)regs[0]) / FREQ_SCALE;
|
||||||
|
motstates[curN].current = ((double)regs[1]) / CURRENT_SCALE;
|
||||||
|
if(++curN >= MOTORS_AMOUNT) curN = 0;
|
||||||
|
errctr = 0;
|
||||||
|
return;
|
||||||
|
reg_error:
|
||||||
|
++errctr;
|
||||||
|
}
|
||||||
|
static void motors_process_e(){
|
||||||
|
static double t0 = -1., curspeed = 0.;
|
||||||
|
double curt = sl_dtime(), dt = curt - t0, curcurrent = 0.;
|
||||||
|
int curstatus = motstates[0].status;
|
||||||
|
if(t0 < 0.){
|
||||||
|
t0 = curt;
|
||||||
|
// init state ("turn motors on")
|
||||||
|
for(int i = 0; i < MOTORS_AMOUNT; ++i) motstates[i].status = MOT_SLEEP;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(flags.all){
|
||||||
|
if(flags.stop){
|
||||||
|
speedSet = 0.;
|
||||||
|
if(curstatus != MOT_RUN) curstatus = MOT_SLEEP;
|
||||||
|
}
|
||||||
|
flags.all = 0;
|
||||||
|
}
|
||||||
|
if(fabs(curspeed - speedSet) > SPEED_TOLERANCE){ // need to calculate new speed value
|
||||||
|
double acceleration = (curspeed < speedSet) ? EMUL_ACCEL : -EMUL_ACCEL;
|
||||||
|
double newspeed = curspeed + acceleration * dt / 60.; // acceleration in min^{-2}
|
||||||
|
if(acceleration > 0.){
|
||||||
|
if(newspeed > speedSet) newspeed = speedSet;
|
||||||
|
}else{
|
||||||
|
if(newspeed < speedSet) newspeed = speedSet;
|
||||||
|
}
|
||||||
|
curspeed = newspeed;
|
||||||
|
curcurrent = currentSet;
|
||||||
|
curstatus = MOT_RUN;
|
||||||
|
DBG("Now speed = %g", curspeed);
|
||||||
|
}else{
|
||||||
|
if(fabs(curspeed) < SPEED_TOLERANCE) curstatus = MOT_SLEEP; // stopped
|
||||||
|
else curcurrent = currentSet * 0.6;
|
||||||
|
}
|
||||||
|
t0 = curt;
|
||||||
|
for(int i = 0; i < MOTORS_AMOUNT; ++i){
|
||||||
|
motstates[i].status = curstatus;
|
||||||
|
motstates[i].current = curcurrent;
|
||||||
|
motstates[i].speed = curspeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int (*motors_open)(const char *, int) = motors_open_m;
|
||||||
|
void (*motors_close)() = motors_close_m;
|
||||||
|
void (*motors_process)() = motors_process_m;
|
||||||
|
|
||||||
|
void set_emulation_mode(){
|
||||||
|
LOGMSG("Set emulation mode");
|
||||||
|
motors_open = motors_open_e;
|
||||||
|
motors_close = motors_close_e;
|
||||||
|
motors_process = motors_process_e;
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,14 +18,22 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define MAX_SPEED (700.)
|
// max errors per motor to mean it OFF
|
||||||
#define MAX_CURRENT (15.)
|
#define MAX_ERRORS 5
|
||||||
#define MOTORS_AMOUNT (10)
|
|
||||||
|
#define MAX_SPEED 700.
|
||||||
|
#define SPEED_TOLERANCE 0.01
|
||||||
|
// emulation acceleration, min^-2
|
||||||
|
#define EMUL_ACCEL 20000.
|
||||||
|
#define MAX_CURRENT 15.
|
||||||
|
#define DEFAULT_CURRENT 10.
|
||||||
|
#define MOTORS_AMOUNT 10
|
||||||
// low, medium and high speeds
|
// low, medium and high speeds
|
||||||
#define LSpeed 71
|
#define LSpeed 71
|
||||||
#define MSpeed 350
|
#define MSpeed 350
|
||||||
#define HSpeed 610
|
#define HSpeed 610
|
||||||
|
|
||||||
|
|
||||||
// ID of first motor minus 1
|
// ID of first motor minus 1
|
||||||
#define START_ID (0)
|
#define START_ID (0)
|
||||||
// ID of motor (n=1..MOTORS_AMOUNT)
|
// ID of motor (n=1..MOTORS_AMOUNT)
|
||||||
@@ -45,15 +53,23 @@ typedef struct{
|
|||||||
double current;
|
double current;
|
||||||
} motor_state_t;
|
} motor_state_t;
|
||||||
|
|
||||||
void motors_stop();
|
|
||||||
double motors_get_curntsetpoint();
|
double motors_get_curntsetpoint();
|
||||||
int motors_set_curntsetpoint(double val);
|
int motors_set_curntsetpoint(double);
|
||||||
double motors_get_speedsetpoint();
|
|
||||||
int motors_set_speedsetpoint(double val);
|
|
||||||
int motors_get_activenum();
|
|
||||||
int motors_set_activenum(int N);
|
|
||||||
int motors_get_actcurrent(double *val);
|
|
||||||
int motors_get_actspeed(double *val);
|
|
||||||
int motors_get_actstatus(int *val);
|
|
||||||
|
|
||||||
void modbus_close();
|
double motors_get_speedsetpoint();
|
||||||
|
int motors_set_speedsetpoint(double);
|
||||||
|
|
||||||
|
int motors_get_activenum();
|
||||||
|
int motors_set_activenum(int);
|
||||||
|
|
||||||
|
void motors_stop();
|
||||||
|
int motors_get_actcurrent(double*);
|
||||||
|
int motors_get_actspeed(double*);
|
||||||
|
int motors_get_actstatus(int*);
|
||||||
|
|
||||||
|
extern void (*motors_process)();
|
||||||
|
|
||||||
|
extern int (*motors_open)(const char *, int);
|
||||||
|
extern void (*motors_close)();
|
||||||
|
|
||||||
|
void set_emulation_mode();
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
rm client.log 2>/dev/null
|
rm client.log
|
||||||
./dome_client -a ca/ca/ca_cert.pem -c ca/client/client_cert.pem -k ca/client/private/client_key.pem -vvv -s localhost -l client.log $@
|
./dome_client -a ca/ca/ca_cert.pem -c ca/client/client_cert.pem -k ca/client/private/client_key.pem -vvv -s localhost -l client.log $@
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
rm server.log 2>/dev/null
|
rm server.log
|
||||||
./dome_server -a ca/ca/ca_cert.pem -c ca/server/server_cert.pem -k ca/server/private/server_key.pem -vvvl server.log $@
|
./dome_server -a ca/ca/ca_cert.pem -c ca/server/server_cert.pem -k ca/server/private/server_key.pem -vvvl server.log $@
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ void serverproc(SSL_CTX *ctx, int fd){
|
|||||||
//char buf[64];
|
//char buf[64];
|
||||||
//int P = 0;
|
//int P = 0;
|
||||||
while(isrunning){
|
while(isrunning){
|
||||||
|
motors_process();
|
||||||
/*double tnow = sl_dtime();
|
/*double tnow = sl_dtime();
|
||||||
if(tnow - t0 > 5. && nfd > 1){ // broadcasting message
|
if(tnow - t0 > 5. && nfd > 1){ // broadcasting message
|
||||||
//DBG("send ping");
|
//DBG("send ping");
|
||||||
@@ -207,7 +208,7 @@ void serverproc(SSL_CTX *ctx, int fd){
|
|||||||
}
|
}
|
||||||
for(int i = 0; i < nfd; ++i) SSL_free(ssls[i]);
|
for(int i = 0; i < nfd; ++i) SSL_free(ssls[i]);
|
||||||
motors_stop();
|
motors_stop();
|
||||||
modbus_close();
|
motors_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************** Protocol handlers (return 0 in case of success or error code >0 if failed) ******************/
|
/****************** Protocol handlers (return 0 in case of success or error code >0 if failed) ******************/
|
||||||
@@ -271,6 +272,11 @@ sl_sock_hresult_e speed_handler(int _U_ index, char _U_ value[SL_VAL_LEN]){
|
|||||||
return RESULT_SILENCE;
|
return RESULT_SILENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sl_sock_hresult_e stop_handler(int _U_ index, char _U_ value[SL_VAL_LEN]){
|
||||||
|
motors_stop();
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// binary search handler by name
|
// binary search handler by name
|
||||||
static int search_handler(const char *name){
|
static int search_handler(const char *name){
|
||||||
int low = 0;
|
int low = 0;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "cmdlnopts.h"
|
#include "cmdlnopts.h"
|
||||||
#include "sslsock.h"
|
#include "sslsock.h"
|
||||||
#ifdef SERVER
|
#ifdef SERVER
|
||||||
|
#include "motors.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#else
|
#else
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
@@ -132,14 +133,21 @@ static SSL_CTX* InitCTX(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int open_socket(){
|
int open_socket(){
|
||||||
int fd;
|
FNAME();
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
SSL_CTX *ctx = InitCTX();
|
SSL_CTX *ctx = InitCTX();
|
||||||
fd = OpenConn(atoi(G.port));
|
int fd = OpenConn(atoi(G.port));
|
||||||
#ifdef SERVER
|
#ifdef SERVER
|
||||||
|
if(G.emulmode) set_emulation_mode();
|
||||||
|
if(!motors_open(G.serialpath, G.serialspeed)){
|
||||||
|
LOGERR("Can't open %s @%d", G.serialpath, G.serialspeed);
|
||||||
|
WARNX("Can't open %s @%d", G.serialpath, G.serialspeed);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
serverproc(ctx, fd);
|
serverproc(ctx, fd);
|
||||||
#else
|
#else
|
||||||
clientproc(ctx, fd);
|
if(G.terminal) terminal(ctx, fd);
|
||||||
|
else clientproc(ctx, fd);
|
||||||
#endif
|
#endif
|
||||||
// newer reached
|
// newer reached
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|||||||
Reference in New Issue
Block a user