Page 1 of 1

Negative position?

Posted: Wed Jun 20, 2018 8:20 am
by rwschumann
I want to use the position commands to control how much movement occurs.

I was planning on using the zero encoder position as my mid point (eg moving backwards would result in a negative encoder count).

When using distance commands and such the encoder behaves as I would expect going positive and negative as I issue distance commands.

However the position command appears to NOT deal with negative positions at all?

Please confirm.

If true do I need to set an artificial mid-point and can I use the set encoder command?

Re: Negative position?

Posted: Thu Jun 21, 2018 10:06 am
by Basicmicro Support
You need to use a signed variable when you read the position value. It will convert the unsigned 32bit value into a signed value properly. It is written this way so you can use it either signed of unsigned positions.

Re: Negative position?

Posted: Thu Jun 21, 2018 1:24 pm
by rwschumann
Correct. When I read the position I am able to accurately see it go negative.

However if I use a position command, such as

66 - Buffered Drive M2 with signed Speed, Accel, Deccel and Position
Move M2 position from the current position to the specified new position and hold the new
position. Accel sets the acceleration value and deccel the decceleration value. QSpeed sets the
speed in quadrature pulses the motor will run at after acceleration and before decceleration.

it does NOT accept a negative value. So while I can read that I have gone negative I cannot actually send the device there.

Basically it comes down to the core problem from this whole thread which is that the handling of the "position" and encoder value is muddled. Sometimes treated as signed and sometimes not.

Re: Negative position?

Posted: Thu Jun 21, 2018 4:52 pm
by Basicmicro Support
Please post your code.

Re: Negative position?

Posted: Fri Jun 22, 2018 1:07 pm
by rwschumann
I have included two files, below
1) Arduino code which executes 'forward' and 'backward' distance and position commands
2) Log file showing results of the calls.

In the log file you can see that:
a) When doing a forward call (either distance or position) it all works fine.
b) When doing a position backward call it works fine until you do one which would bring it to a negative position. In this case it does the position towards '0'. then stops. (You can see this in the duration time and end position.
c) When doing a distance backward call which would go negative it basically runs forever as it is trying to get to some huge count position.

So the position command clearly recognized this as a negative number, or overflow, or something and stops.
THanks,
Rob

Code: Select all

//See BareMinimum example for a list of library functions

//Includes required to use Roboclaw library
#include <SoftwareSerial.h>
#include "RoboClaw.h"

//See limitations of Arduino SoftwareSerial
//SoftwareSerial serial(10,11);	
RoboClaw roboclaw(&Serial2,10000);


#define address 0x80
#define MOTOR_RELAY 12
#define POWER_RELAY 11


//This is the first function arduino runs on reset/power up
void setup() {
  pinMode(MOTOR_RELAY, OUTPUT);
  digitalWrite(MOTOR_RELAY, LOW);
  pinMode(POWER_RELAY, OUTPUT);
  digitalWrite(POWER_RELAY, LOW);

  delay(500);
  
  //Open Serial and roboclaw at 38400bps
  Serial.begin(57600);
  roboclaw.begin(38400);

  // Set our encoder count to zero
  roboclaw.SetEncM2(address, 0x0);

  Serial.println("Starting...");
}


void loop() {
static int32_t cur_pos = 0;

   Serial.printf("cmd: ");
   while(Serial.available() == 0) {
    delay(50);
   }
  char chr = Serial.read();
  Serial.printf("%c\n\r",chr);
  boolean active=false;
  boolean distance = false;
  int32_t mvmt = 0;
  switch(chr) {
    case 'b': 
      mvmt = -1500;
      active = true;
      break; 
    case 'B': 
      mvmt = -1500;
      active = true;
      distance = true;
      break; 
    case 'f':
      mvmt = 1000;
      active = true;
      break;
    case 'F':
      mvmt = 1000;
      active = true;
      distance = true;
      break;    
    default: 
      Serial.printf("Commands are 'b' or 'f' for position or 'B' or 'F' for distance command\n\r");
      break;
  }
  if (active) {
      uint8_t status;
      bool valid;
      uint32_t rc_pos;
      rc_pos = roboclaw.ReadEncM2(address, &status, &valid);
      cur_pos = rc_pos+mvmt;  
      Serial.printf("moving to position: %ld  from position: %ld\n\r",cur_pos,(int32_t)rc_pos);
      if (distance == false) 
        roboclaw.SpeedAccelDeccelPositionM2(address,10000,7000,3000,(uint32_t)cur_pos,1);
      else
        roboclaw.SpeedAccelDistanceM2(address,10000,3000,(uint32_t)mvmt,1);      
      uint8_t depth1, depth2;
      unsigned long start_time = millis();
      do {
         roboclaw.ReadBuffers(address, &depth1, &depth2);
         delay(50);
      } while(depth2 != 0x80);

      roboclaw.ReadBuffers(address, &depth1, &depth2);      
      rc_pos = roboclaw.ReadEncM2(address, &status, &valid);
      Serial.printf("Finished, elapsed time: %ld(ms), ending position: %lu(unsigned)  %ld(signed)\n\r",millis()-start_time, rc_pos,(int32_t)rc_pos);
  };
}
Connecting to COM14...
Connected.

Started with speed: 38400
Starting...
cmd: f
moving to position: 2223 from position: 1223
Finished, elapsed time: 909(ms), ending position: 1973(unsigned) 1973(signed)
cmd: f
moving to position: 3149 from position: 2149
Finished, elapsed time: 962(ms), ending position: 2945(unsigned) 2945(signed)
cmd: b
moving to position: 1503 from position: 3003
Finished, elapsed time: 1173(ms), ending position: 1736(unsigned) 1736(signed)
cmd: b
moving to position: 99 from position: 1599
Finished, elapsed time: 1071(ms), ending position: 295(unsigned) 295(signed)
cmd: b
moving to position: -1373 from position: 127
Finished, elapsed time: 326(ms), ending position: 84(unsigned) 84(signed)
cmd: b
moving to position: -1416 from position: 84
Finished, elapsed time: 61(ms), ending position: 84(unsigned) 84(signed)
cmd: F
moving to position: 1021 from position: 21
Finished, elapsed time: 748(ms), ending position: 1153(unsigned) 1153(signed)
cmd: b
moving to position: 738 from position: 2238
Finished, elapsed time: 1174(ms), ending position: 1008(unsigned) 1008(signed)
cmd: B
moving to position: -753 from position: 747

Connection closed.

Re: Negative position?

Posted: Mon Jun 25, 2018 10:43 am
by Basicmicro Support
Here is a modification of the Position example included in our Roboclaw library.

Code: Select all

//See BareMinimum example for a list of library functions

//Includes required to use Roboclaw library
#include <SoftwareSerial.h>
#include "RoboClaw.h"

//See limitations of Arduino SoftwareSerial
//SoftwareSerial serial(10,11);	
RoboClaw roboclaw(&Serial1,10000);

#define address 0x80

//Display Encoder and Speed for Motor 1
void displayspeed(void)
{
  uint8_t status1,status2;
  bool valid1,valid2;
  int32_t enc1 = roboclaw.ReadEncM2(address, &status1, &valid1);
  int32_t speed1 = roboclaw.ReadSpeedM2(address, &status2, &valid2);
  
  Serial.print("Encoder1:");
  if(valid1){
    Serial.print(enc1,DEC);
    Serial.print(" ");
    Serial.print(status1,HEX);
    Serial.print(" ");
  }
  else{
    Serial.print("failed ");
  }

  Serial.print("Speed1:");
  if(valid2){
    Serial.print(speed1,DEC);
    Serial.print(" ");
  }
  else{
    Serial.print("failed ");
  }
  
  Serial.println();
}

//This is the first function arduino runs on reset/power up
void setup() {
  //Open Serial and roboclaw at 38400bps
  Serial.begin(57600);
  roboclaw.begin(38400);
  
  Serial.println("Starting...");
}

void loop() {
  roboclaw.SpeedAccelDeccelPositionM2(address,0,4000,0,4000,1);
  roboclaw.SpeedAccelDeccelPositionM2(address,0,4000,0,-4000,0);
  long last = millis();
  while(millis()-last<5000){
    displayspeed();
    delay(50);
  }
}
Note you must have set the Min and Max position range to atleast -4000 to 4000(I set mine to -5000 to 5000). Also make sure everything works in IonStudio and you save your settings before testing this example.