state_fcn last_state; // last state
int32_t act_pos; // actual position
int32_t req_pos; // requested position
+ int32_t req_spd;
+ int32_t req_target;
+ volatile int32_t can_req_spd;
volatile uint32_t can_req_position; // next requested position
int32_t start_pos;
uint32_t can_response; // when the move is done, the value here equals to the req_pos
#define DEAD_ZONE 10
-static bool do_control(struct fsm *fsm)
+static bool do_control(struct fsm *fsm, int P)
{
bool finished;
int e = fsm->req_pos - fsm->act_pos;
- int P = 2;
int action = (P*e) / 10; // ORIGINAL: int action = P*e;
stop();
break;
case EVENT_DO:
- do_control(fsm);
+ do_control(fsm, 2);
if (fsm->can_req_position != last_can_req_pos &&
- fsm->can_req_position != fsm->req_pos) {
+ fsm->can_req_position != fsm->req_target) {
last_can_req_pos = fsm->can_req_position;
- fsm->req_pos = fsm->can_req_position;
+ fsm->req_target = fsm->can_req_position;
+ fsm->req_spd = fsm->can_req_spd;
fsm->current_state = move;
}
break;
}
}
+#define XMIN(a,b) ((a) < (b) ? (a) : (b))
+#define XMAX(a,b) ((a) > (b) ? (a) : (b))
static void move(struct fsm *fsm, enum event event)
{
+ static int counter;
bool finished;
switch (event) {
case EVENT_ENTRY:
+ counter = 0;
DBG_ENTRY();
fsm->time_start = timer_msec;
fsm->start_pos = fsm->act_pos;
+ if(fsm->req_spd == 0)
+ fsm->req_pos = fsm->req_target;
+ else
+ fsm->req_pos = fsm->start_pos;
break;
case EVENT_DO:
- if (timer_msec - fsm->time_start > 1000) {
+ if(fsm->req_spd != 0 && counter++ >= 10)
+ {
+ counter = 0;
+ if(fsm->req_target > fsm->start_pos)
+ fsm->req_pos = XMIN(fsm->req_pos + fsm->req_spd,fsm->req_target);
+ else
+ fsm->req_pos = XMAX(fsm->req_pos - fsm->req_spd,fsm->req_target);
+ }
+ if (timer_msec - fsm->time_start > (fsm->req_spd == 0 ? 1000 : 2000)) {
fsm->flags = CAN_VIDLE_TIMEOUT;
fsm->current_state = wait_for_cmd;
fsm->req_pos = fsm->act_pos;
}
- finished = do_control(fsm);
- if (finished) {
+ finished = do_control(fsm, fsm->req_spd ? 5 : 2);
+ if (finished && fsm->req_pos == fsm->req_target) {
fsm->can_response = fsm->req_pos;
fsm->current_state = wait_for_cmd;
}
fsm->trigger_can_send = true;;
break;
}
-}
+}
\ No newline at end of file
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void CAN_rx(can_msg_t *msg) {
+ uint32_t spd;
can_msg_t rx_msg;
uint32_t req =0;
memcpy(&rx_msg, msg, sizeof(can_msg_t));//make copy of message
case CAN_VIDLE_CMD:
deb_led_on(LEDB);
req = ((rx_msg.data[0]<<8) | (rx_msg.data[1]));
+ spd = rx_msg.data[2];
if (req >= 0x150 && req <= 0x3e0) {
fsm_vidle.flags &= ~CAN_VIDLE_OUT_OF_BOUNDS;
fsm_vidle.can_req_position = req;// save new req position of lift
+ fsm_vidle.can_req_spd = spd;// save new req spd of lift
} else
fsm_vidle.flags |= CAN_VIDLE_OUT_OF_BOUNDS;
break;