VCS binding one motor's value to another

Since with V5 these are smart motors, I wonder if there is any special way to bind one motor’s power or RPM value to another?

Would this be the best way (if this even works)?


Motor2.setVelocity(Motor1.velocity(velocityUnits::rpm),velocityUnits::rpm);

As in set a master-slave relationship between motors?

Its worth noting that this might not have the exact behavior you desire. Since each motor is running separate PID loops, you may see different behavior if each is not loaded the same. Also setting the target velocity of one motor to the actual velocity of another likely means that each motor will have different target values and will behave worse than just setting the same target for each.

Two motors on a drive base side, 3 wheels chained together. It seems like it makes the most sense to only account for the center wheel’s encoders and have the second motor mimic the values for the center motor.

I still don’t understand the need for a master/slave relationship here. Why not just set the motors’ velocity together? Like this:


void setDrive(int speed){
    Motor1.setVelocity(speed,velocityUnits::rpm);
    Motor2.setVelocity(speed,velocityUnits::rpm);
}

If you truly want the motor2 to be “following” motor1, receiving the exact same signal, then you would want to pair the motors together at the voltage level, which bypasses control loops. Even then the update rate from the brain to the motor (10 or 20ms IIRC) is far inferior to the speed of the motor’s own control system (1ms IIRC).

Here is the idea of what is trying to be accomplished, and I guess something like this would work. I just wonder if there is a better way. I thought the internal PID might be a problem using a solution like this.

void autonomous( void ) {
    
    RightSide1.setStopping(brakeType::coast);
    LeftSide1.setStopping(brakeType::coast);
    
    RightSide2.spin(directionType::fwd,50,velocityUnits::rpm);
    LeftSide2.spin(directionType::fwd,50,velocityUnits::rpm);
    RightSide1.rotateFor(720,rotationUnits::deg,50,velocityUnits::pct,false);
    LeftSide1.rotateFor(720,rotationUnits::deg,50,velocityUnits::pct);
    
    RightSide2.stop(brakeType::coast);
    LeftSide2.stop(brakeType::coast);
}

At that point I’d want to say Okapi lib in PROS is a better fit for what you want to do.

Do what @sazrocks said and ignore that individual motor commands exist for your drive motors. Encapsulate any motor commands you want to use into functions and only call those functions.

I agree with John, keep it simple, just send the same velocity or other commands to both motors.

I had started working on a “motor group” class a few weeks ago, may or may not include something like this into a future VCS sdk, we don’t want to take all the fun away from teams. However, the beginnings were along these lines.

namespace vex {
  class motor_group  {
    private:
       std::vector<vex::motor> _motors;
 
       void _addMotor() {};
       template <typename... Args>
       void _addMotor(  vex::motor m1, Args... m2 ) {
           _motors.push_back(m1);
           _addMotor( m2... );
       }

    public:
       motor_group() {};
      
       template <typename... Args>
       motor_group(  vex::motor m1, Args... m2 ) {
           _motors.push_back(m1);
           _addMotor( m2... );
       }
      
      ~motor_group() {};
      
      void spin( directionType dir ) {
          for ( auto m: _motors) {
            m.spin( dir );
          }      
      };
      
      void rotateTo( double rotation, rotationUnits units, double velocity, velocityUnits units_v ) {
          // start movement
          for ( auto m: _motors) {
              m.rotateTo( rotation, units, velocity, units_v, false );
          }
          
          // wait for all to finish
          // needs timeout adding.....
          bool isSpinning = true;         
          while( isSpinning == true ) {
            isSpinning = false;
            for ( auto m: _motors) {
              isSpinning |= m.isSpinning();
            }          
            this_thread::sleep_for(10);
          }
      };      
  };
}

you would create motors in the usually way

motor m1( vex::PORT1 );
motor m2( vex::PORT2 );

then create an instance of a motor group


vex::motor_group mg( m1, m2 );

and then use the group in the same way as a motor.

mg.rotateTo( 4, rotationUnits::rev, 50, velocityUnits::rpm );

I only created the two methods, all others would be similar.

anyone want to finish it off ?

I know over in the PROS and Okapilib world there’s a MotorGroup class which I really like to use for simplifying all the controllers I use.