Mr

Mr. Rogers' IB Computer Science - Google Android SmartPhone Programming Project

Mr Rogers Android Project Menu

Home

Projects

2010-2011


   3D Compass

   3D Accelerometer

   Friction Tester

   Drum

   Game 1

   Game 2

 


Southside High School
Greenville, SC

 

Friction Tester

Description
This program calculates the coefficients of friction between the phone and a surface. It does this by using the gyroscopes and accerometers built into the phone. When the phone detects a minimum acceleration, it triggers the recording of the angle it is at and the acceleration down the surface. From that, it can calculate the force that is pulling it down the surface, and then find the coefficients of friction.

Features

  • Uses Accelerometer
  • Uses Gyroscope
  • Finds both static and kinetic COFs


Version
Version 1.0 10/12/10
Current Version 12/15/10

Future Plans
  • Adding a calibration capibilitie
  • Changing the tolerance of the program
  • Changing the mass in the program to attach to phone to other devices or attachments


Instructions
  1. Start the program.
  2. Place the phone on a flat surface.
  3. Press "Start".
  4. Gently tilt the desired surface until the phone slips.
  5. To retest, press "Start".
  6. To quit, press menu "Quit".


Source Code
Friction.java
~\Desktop\workspace android\Friction\src\com\test\friction\Friction.java.html
package com.test.friction;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


/**
 * Calculates coefficients of friction using an android phone.
 * @author Brenden Raulerson
 * @version 3.0 12-15-10
 */
public class Friction extends Activity{
        private Sen gyrol;
        private Sen accell;

        private Sensor gyro;
        private Sensor accel;

        SensorEvent lastEvent;
        SensorManager sm;
        TextView cof_st;
        TextView cof_kt;
        TextView gx;
        TextView gy;
        TextView gz;
        Button start;
        Button done;
        public float highx = 0;
        public float highy = 0;
        private Friction g;

    private float[] gyros = new float[3];

    private double cof_s = 0;
    private double cof_k = 0;
        protected boolean res;

    /** Called when the activity is first created.
     */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        g = this;
        this.cof_st = ((TextView)findViewById(R.id.cofs));
        this.cof_kt = ((TextView)findViewById(R.id.cofk));
        this.gx = ((TextView)findViewById(R.id.gx));
        this.gy = ((TextView)findViewById(R.id.gy));

        this.sm = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        this.accell = new Sen(Sen.ACC, this);
        this.gyrol = new Sen(Sen.GYRO, this);
        this.accel = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        this.gyro = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        this.res = false;

        this.start = (Button)findViewById(R.id.start);
        this.start.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(final View v) {
                                if (!res){
                                        g.sm.registerListener(g.accell, g.accel, SensorManager.SENSOR_DELAY_GAME);
                                        g.sm.registerListener(g.gyrol, g.gyro, SensorManager.SENSOR_DELAY_GAME);
                                        g.cof_s = 0;
                                        g.cof_k = 0;

                                }
                        }
                });
        new CountDownTimer(10000000, 10) {

            public void onTick(long millisUntilFinished) {
                g.t();
            }

            public void onFinish() {
                g.finish();
            }
         }.start();
        g.t();
    }
    /**
     * Called by the timer to display the current angles of the phone.
     */
        public void t(){
                gyros = gyrol.get();
                gx.setText("GX: " + (-gyros[1]));
                gy.setText("GY: " + gyros[2]);

                this.cof_st.setText("S: " + (float)cof_s);
                this.cof_kt.setText("D: " + (float)cof_k);
        }
        /**
         * Called when a minimum acceleration is detected.
         * Calculate the cofs.
         */
        public void slip(){

                this.sm.unregisterListener(this.gyrol);
                this.sm.unregisterListener(this.accell);
                this.res = false;

                float[] gg = gyrol.get();
                float[] aa = accell.get();

                //static

                double g = SensorManager.GRAVITY_EARTH*.158;
                double square = g*g;
                //square = z*z + y*y + x*x;
                double y = g*Math.sin(Math.toRadians(gg[2]));
                double x = g*Math.sin(Math.toRadians(gg[1]));
                double z = Math.sqrt(square - y*y - x*x);
                double total = Math.sqrt(y*y + x*x);
                cof_s = total/z;

                //kenetic
                double total_accel = Math.sqrt(aa[0]*aa[0] + aa[1]*aa[1]);
                cof_k = (total-.158*total_accel)/z;

        }
        /**
         * Create the menu.
         */
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }
    /**
     * Handles menu options.
     */
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.cal:
                this.gyrol.cal();
                return true;
        case R.id.reset:
                this.finish();
                return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

Sen.java
~\Desktop\workspace android\Friction\src\com\test\friction\Sen.java.html
package com.test.friction;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class Sen implements SensorEventListener{
        public float dx = 0;
        public float dy = 0;
        public float dz = 0;
        public float[] values = new float[3];
        private SensorEvent lastevent;
        public final int type;
        private Friction friction;

        public static final int ACC = 0;
        public static final int GYRO = 1;

        private double tolerance;

        public Sen(int type, Friction f){
                this.friction = f;
                this.type = type;
                this.tolerance = -1;
        }
        public void onAccuracyChanged(Sensor sensor, int a){
        }
        public void onSensorChanged(SensorEvent event){
                this.lastevent = event;

                if (type==GYRO){
                        this.values[1] = event.values[1]-dx;
                        this.values[2] = event.values[2]-dy;
                        this.values[0] = event.values[0]-dz;
                }
                if (type==ACC){
                        this.values[0] = event.values[0]-dx;
                        this.values[1] = event.values[1]-dy;
                        this.values[2] = event.values[2]-dz;

                        double total = Math.sqrt((this.values[0]) * (this.values[0])
                                               + (this.values[1]) * (this.values[1])
                                               + (this.values[2]) * (this.values[2])) - SensorManager.GRAVITY_EARTH;


                        if (total <= tolerance)
                                friction.slip();
                }
        }
        public void cal(){
                if (type==GYRO){
                        this.dx = lastevent.values[1];
                        this.dy = lastevent.values[2];
                        this.dz = lastevent.values[0];
                }

                if (type==ACC){
                        this.dx = lastevent.values[0];
                        this.dy = lastevent.values[1];
                        this.dz = lastevent.values[2];
                }
        }
        public void reset(){
                this.dx = 0;
                this.dy = 0;
                this.dz = 0;
        }
        public float[] get(){
                return values;
        }
        public void setT(double t){
                this.tolerance = t;
        }
}

Main.xml
~\Desktop\workspace android\Friction\res\layout\main.xml.html
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView
        android:id="@+id/gx"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="40sp"       
        />
    <TextView
        android:id="@+id/gy"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/gx"
        android:textSize="40sp"
        />
    <Button
        android:id="@+id/start"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/gy"
        android:textSize="40sp"
        android:text="Start"
        />
    <TextView
        android:id="@+id/cofs"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/start"
        android:textSize="40sp"
        />
    <TextView
        android:id="@+id/cofk"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/cofs"
        android:textSize="40sp"
        />
</RelativeLayout>
</ScrollView>

Menu.xml
~\Desktop\workspace android\Friction\res\menu\menu.xml.html
<?xml version="1.0" encoding="utf-8" ?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android">

  <item 
  	android:id="@+id/cal" 
  	android:title="Calibrate">
  	</item>
  
  
  <item 
  	android:id="@+id/reset" 
  	android:title="Quit">
  	</item>


</menu>

Author


My name is Brenden Raulerson. I am a student at Southside High School. I enjoy working with computers and the chance to use android phones.
Mr

Android Developer Site

Mr. Rogers' Twitter Site

Mr. Rogers Teacher's Blog

Southside High School Physics Club

Mr. Rogers T-shirts

Check out other web sites created by Mr. R:

 
Want to learn more about movie physics in Star Trek and find out :
  • what makes Star Trek unique
  • how Star Trek compares to Star Wars
  • why the star ship Enterprise needs to remain in space
  • what should and shouldn't be done in space battles
  • what it takes to blast off and travel the galaxy
  • the basics of orbiting
Insultingly Stupid Movie Physics is one of the most humorous, entertaining, and readable physics books available, yet is filled with all kinds of useful content and clear explanations for high school, 1st semester college physics students, and film buffs.

It explains all 3 of Newton's laws, the 1st and 2nd laws of thermodynamics, momentum, energy, gravity, circular motion and a host of other topics all through the lens of Hollywood movies using Star Trek and numerous other films.

If you want to learn how to think physics and have a lot of fun in the process, this is the book for you!

 

First the web site,

now the book!


Mr. Rogers Home | Common Sylabus | AP Comp Sci I | AP Comp Sci II | AP Physics Mech | AP Physics E&M | AP Statistics | IB Design Tech | Southside

[ Intuitor Home | Physics | Movie Physics | Chess | Forchess | Hex | Intuitor Store |

Copyright 1996-2010 T. K. Rogers, all rights reserved. Forchess is a registered trademark of T. K. Rogers.
No part of this website may be reproduced in any form, electronic or otherwise, without express written approval.