1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  3. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  4. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

Smc3 safety filter ?

Discussion in 'DIY Motion Simulator Projects' started by Gadget999, Aug 17, 2020.

  1. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,897
    Location:
    London
    Balance:
    11,610Coins
    Ratings:
    +458 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    My son was racing a F1 car a few days ago and he managed to crash and go into a barrel roll

    It was pretty scary and shook him up

    He was twisting so fast he was not able to hit the safety shutdown button

    Can anyone think of a simple way to filter out sudden changes or excessive motion.

    I was thinking of fitting an accelerometer in the seat but there must be a simple way to do it in the smc3 code

    Any suggestions ? He is a bit scared to get back on the sim
    Last edited: Aug 18, 2020
  2. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,897
    Location:
    London
    Balance:
    11,610Coins
    Ratings:
    +458 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    i added an average value and a range

    if the range exceeds the average value it just uses the average value instead

    .......................................................................................................................


    // MJG 18/8/2020 - code to remove a large jump or spike in data
    // uses a moving average and a range value
    // if the range is greater than the moving average it just uses the moving average instead


    SampleLoop++ ;
    if (SampleLoop > Sample) {SampleLoop = 0;}

    AvgTarget1[SampleLoop] = Target1;
    AvgTarget2[SampleLoop] = Target2;

    TmpTarget1 = 0;
    TmpTarget2 = 0;

    for (int i = 0; i <= Sample; i++) {
    TmpTarget1 = TmpTarget1 + AvgTarget1 ;
    TmpTarget2 = TmpTarget1 + AvgTarget2 ;
    }

    TmpTarget1 = TmpTarget1 / Sample ;
    TmpTarget2 = TmpTarget2 / Sample ;

    if (Target1 > TmpTarget1 + Target1Range){
    Target1 = TmpTarget1;
    }

    if (Target1 < TmpTarget1 - Target1Range){
    Target1 = TmpTarget1;
    }


    if (Target2 > TmpTarget2 + Target2Range){
    Target2 = TmpTarget2;
    }

    if (Target2 < TmpTarget2 - Target2Range){
    Target2 = TmpTarget2;
    }
  3. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,897
    Location:
    London
    Balance:
    11,610Coins
    Ratings:
    +458 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    The code above did not work that sucessfully, the dam thing moves too fast

    I will try a different approach where the motor strength is reduced and then restored after a period of time
  4. BlazinH

    BlazinH Well-Known Member

    Joined:
    Oct 19, 2013
    Messages:
    2,145
    Location:
    Oklahoma City, USA
    Balance:
    16,574Coins
    Ratings:
    +1,831 / 32 / -1
    I was about to post limiting power would probably be an easy way but then you posted your code which I hoped would work out. But a simple way would be to set PWMmax1. 2 and 3 temporarily to a lower number then raise them back when the event is over. I use PWMmax to control the motors on the soft start routine I added.
  5. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,897
    Location:
    London
    Balance:
    11,610Coins
    Ratings:
    +458 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    Hi @BlazinH,

    I coded the pwmmax to keep cutting in half till then after the event is over wait 5 secs and bring it back.

    However, today I programmed a g sensor that outputs when a shock is detected, i can use that to s
    I programmed it to keep halving the pwm max till the event is over, after 5 secs the full pwm is restored

    However today i programmed a simple g sensor i can fit to the rig

    Similar to this -- https://www.arduino.cc/en/Tutorial/ADXL3xx


    Basically it outputs a digital pin that i can detect on the smc3 board and use that to reduce motion

    I will fit it to the rig and see what sort of forces it records.
    • Creative Creative x 1
  6. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,897
    Location:
    London
    Balance:
    11,610Coins
    Ratings:
    +458 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    the codes uses a mma7361 Accelerometer and a Nano

    it ouputs pin 13 high if it detects over 1g of force

    after 5 seconds the pin is released

    this pin can be used to trigger the SMC3 into a stall mode


    /***********************************************************/
    /****************** Accelerometer ****************ar******/
    /***********************************************************/
    int x, y, z; //raw analog values
    float x_avg, y_avg, z_avg; //smoothed values
    float rx, ry, rz; //smoothed value in number of gs (one g = 9.8 m/s^2)

    float tiltAngle;

    float vref;
    float vzerog;
    float sensitivity;

    void initAcc()
    {
    vref = 5.0; //voltage reference
    vzerog = 1.65; //voltage at zero g, as specified by accelerometer datasheet
    sensitivity = 0.8; //output voltage produced by a certain force, as specified in datasheet
    }

    /***********************************************************/

    void setup()
    {
    delay(1000);

    initAcc();
    Serial.begin(9600);

    pinMode(12, INPUT_PULLUP);
    }

    void loop()
    {
    updateAcc();
    delay(50);
    }

    void updateAcc()
    {
    //raw accelerometer values
    x = analogRead(A0);
    y = analogRead(A1);
    z = analogRead(A2);

    // Serial.print(x);
    // Serial.print('\t');
    // Serial.print(y);
    // Serial.print('\t');
    // Serial.print(z);
    // Serial.print('\t');
    // Serial.println();
    //
    // Serial.print(rx);
    // Serial.print('\t');
    // Serial.print(ry);
    // Serial.print('\t');
    // Serial.print(rz);
    // Serial.print('\t');
    // Serial.println();

    //smoothed values
    //x_avg = expMovingAvg(x, 0.1, x_avg);
    //y_avg = expMovingAvg(y, 0.1, y_avg);
    //z_avg = expMovingAvg(z, 0.1, z_avg);

    //smoothed values in number of gs (one g = 9.8 m/s^2)
    // rx = (x_avg*vref/1023-vzerog) / sensitivity;
    // ry = (y_avg*vref/1023-vzerog) / sensitivity;
    // rz = (z_avg*vref/1023-vzerog) / sensitivity;

    rx = (x*vref/1023-vzerog) / sensitivity;
    ry = (y*vref/1023-vzerog) / sensitivity;
    rz = (z*vref/1023-vzerog) / sensitivity;


    Serial.print(rx);
    Serial.print('\t');
    Serial.print(ry);
    Serial.print('\t');
    Serial.print(rz);
    Serial.print('\t');
    Serial.println();


    if ((rx > 1) || (rx < -1)){

    Serial.println("Excess X Force");

    Serial.print(rx);
    Serial.print('\t');
    Serial.print(ry);
    Serial.print('\t');
    Serial.print(rz);
    Serial.print('\t');
    Serial.println();
    digitalWrite(13, HIGH);
    delay(5000);
    digitalWrite(13, LOW);


    }


    if ((ry > 1) || (ry < -1)){

    Serial.println("Excess Y Force");

    Serial.print(rx);
    Serial.print('\t');
    Serial.print(ry);
    Serial.print('\t');
    Serial.print(rz);
    Serial.print('\t');
    Serial.println();
    digitalWrite(13, HIGH);
    delay(5000);
    digitalWrite(13, LOW);

    }


    if ((rz > 1) || (rz < -1)){

    Serial.println("Excess Z Force");

    Serial.print(rx);
    Serial.print('\t');
    Serial.print(ry);
    Serial.print('\t');
    Serial.print(rz);
    Serial.print('\t');
    Serial.println();
    digitalWrite(13, HIGH);
    delay(5000);
    digitalWrite(13, LOW);

    }


    //angle accelerometer is tilted from vertical, in radians (exact only if it is at rest)
    //tiltAngle = acos( (rx*0 + ry*0 + rz*-1) / (sqrt(sq(rx) + sq(ry) + sq(rz)) * sqrt(sq(0) + sq(0) + sq(-1))) );

    //Serial.print("tilt angle: ");
    //Serial.println(tiltAngle);
    }

    //Exponential moving average, weight on new value
    float expMovingAvg(float new_val, float weight_on_new, float avg)
    {
    return avg + weight_on_new*(new_val - avg);
    }
  7. Thanos

    Thanos Building the Future one AC Servo at a time... or 6

    Joined:
    Jul 6, 2017
    Messages:
    1,347
    Occupation:
    Electronics Engineer
    Location:
    United States
    Balance:
    2,699Coins
    Ratings:
    +1,043 / 9 / -0
    My Motion Simulator:
    AC motor, Motion platform, 4DOF, 6DOF
    What about adding a capacitive sensor on the seat? If the driver is ejected from his seat, it would slow down the motion... :p
    • Funny Funny x 2
  8. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,897
    Location:
    London
    Balance:
    11,610Coins
    Ratings:
    +458 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    @BlazinH

    I looked at your softstart code and it looks like you have a park routine

    i can use this with the accelerometer :)

    does the park just drop power to the motors till the pin(8) is released ?
  9. BlazinH

    BlazinH Well-Known Member

    Joined:
    Oct 19, 2013
    Messages:
    2,145
    Location:
    Oklahoma City, USA
    Balance:
    16,574Coins
    Ratings:
    +1,831 / 32 / -1
    Sorry but my code is soft start only. It could be reversed however.
    Needless to say I don't know where you got info regarding pin(8).

    Using an accelerometer is a novel ideal but thats like putting the horse before the buggy I think. Yes normally thats correct but that method uses the result of power after being applied vs before; like after the horses pulling has affected the buggy. But with use of current and previous set point variables I think the horses affect on the buggy should be able to be calculated prior to actual movement resulting in more precise control with less latency.
  10. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,897
    Location:
    London
    Balance:
    11,610Coins
    Ratings:
    +458 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    Hi BlazinH

    The park on pin 8 must have been my own work. I did look at it some time ago and forgot to rename the sketch.

    Yes I know what you mean about trapping the event before the sim gets a hard kick.

    I have used a moving average and a step amount. If the sim trys to move to fast it can drop the power off.

    I will start again and code it based on your softstart sketch :)