Skip to content

Commit 1ed82b5

Browse files
authored
Merge branch 'develop' into feature/add_vr_variant
2 parents 26f6b71 + 78d3b01 commit 1ed82b5

41 files changed

Lines changed: 2040 additions & 64 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ android {
3535
applicationIdSuffix = ".nxt"
3636
}
3737

38-
// ev3 {
39-
// applicationIdSuffix = ".ev3"
40-
// }
38+
ev3 {
39+
applicationIdSuffix = ".ev3"
40+
}
4141

4242
// pile {
4343
// applicationIdSuffix = ".pile"
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/**
2+
* Copyright (C) 2011-2017 The PILE Developers <pile-dev@googlegroups.com>
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.pileproject.drive.execution;
17+
18+
import android.support.test.runner.AndroidJUnit4;
19+
20+
import com.pileproject.drive.machine.CarControllerBase;
21+
import com.pileproject.drive.machine.Ev3CarController;
22+
import com.pileproject.drivecommand.machine.device.input.ColorSensor;
23+
import com.pileproject.drivecommand.machine.device.input.Rangefinder;
24+
import com.pileproject.drivecommand.machine.device.input.TouchSensor;
25+
import com.pileproject.drivecommand.machine.device.output.Motor;
26+
import com.pileproject.drivecommand.model.ev3.Ev3Machine;
27+
28+
import org.junit.Before;
29+
import org.junit.Test;
30+
import org.junit.runner.RunWith;
31+
import org.mockito.InjectMocks;
32+
import org.mockito.Mock;
33+
import org.mockito.internal.util.reflection.Whitebox;
34+
35+
import static com.pileproject.drive.machine.CarControllerBase.MotorKind.LeftMotor;
36+
import static com.pileproject.drive.machine.CarControllerBase.MotorKind.RightMotor;
37+
import static junit.framework.Assert.assertEquals;
38+
import static junit.framework.Assert.assertFalse;
39+
import static junit.framework.Assert.assertTrue;
40+
import static org.mockito.Mockito.doReturn;
41+
import static org.mockito.Mockito.mock;
42+
import static org.mockito.Mockito.verify;
43+
44+
@RunWith(AndroidJUnit4.class)
45+
public class Ev3CarControllerTest {
46+
47+
@Mock Ev3Machine machine;
48+
@InjectMocks
49+
Ev3CarController controller;
50+
51+
@Mock TouchSensor touchSensor;
52+
@Mock Rangefinder rangefinder;
53+
@Mock ColorSensor colorSensor;
54+
55+
@Mock Motor leftMotor;
56+
@Mock Motor rightMotor;
57+
58+
@Before
59+
public void setUp() {
60+
machine = mock(Ev3Machine.class);
61+
controller = new Ev3CarController(machine);
62+
63+
touchSensor = mock(TouchSensor.class);
64+
rangefinder = mock(Rangefinder.class);
65+
colorSensor = mock(ColorSensor.class);
66+
67+
leftMotor = mock(Motor.class);
68+
rightMotor = mock(Motor.class);
69+
}
70+
71+
private void setUpMotors() {
72+
Whitebox.setInternalState(controller, "mLeftMotor", leftMotor);
73+
Whitebox.setInternalState(controller, "mRightMotor", rightMotor);
74+
}
75+
76+
77+
// TODO: add tests related to preferences
78+
79+
80+
@Test
81+
public void whenTouchSensorIsNull_thenReturnFalse() throws Exception {
82+
Whitebox.setInternalState(controller, "mTouchSensor", null);
83+
84+
assertFalse(controller.isTouchSensorTouched());
85+
}
86+
87+
@Test
88+
public void whenTouchSensorIsNotNull_andTouchSensorIsTouched_thenReturnTrue() throws Exception {
89+
Whitebox.setInternalState(controller, "mTouchSensor", touchSensor);
90+
doReturn(true).when(touchSensor).isTouched();
91+
92+
assertTrue(controller.isTouchSensorTouched());
93+
}
94+
95+
@Test
96+
public void whenTouchSensorIsNotNull_andTouchSensorIsNotTouched_thenReturnFalse() throws Exception {
97+
Whitebox.setInternalState(controller, "mTouchSensor", touchSensor);
98+
doReturn(false).when(touchSensor).isTouched();
99+
100+
assertFalse(controller.isTouchSensorTouched());
101+
}
102+
103+
@Test
104+
public void whenRangefinderIsNull_thenReturnNegative() throws Exception {
105+
Whitebox.setInternalState(controller, "mRangefinder", null);
106+
107+
assertEquals(controller.getRangefinderDistance(), -1);
108+
}
109+
110+
@Test
111+
public void whenRangefinderIsNotNull_thenReturnProperValue() throws Exception {
112+
Whitebox.setInternalState(controller, "mRangefinder", rangefinder);
113+
doReturn(10).when(rangefinder).getDistance();
114+
115+
assertEquals(10, controller.getRangefinderDistance());
116+
}
117+
118+
@Test
119+
public void whenColorSensorIsNull_thenReturnNegative() throws Exception {
120+
Whitebox.setInternalState(controller, "mColorSensor", null);
121+
122+
assertEquals(controller.getColorSensorIlluminance(), -1);
123+
}
124+
125+
@Test
126+
public void whenColorSensorIsNotNull_thenReturnProperValue() throws Exception {
127+
Whitebox.setInternalState(controller, "mColorSensor", colorSensor);
128+
doReturn(20).when(colorSensor).getIlluminance();
129+
130+
assertEquals(20, controller.getColorSensorIlluminance());
131+
}
132+
133+
@Test
134+
public void whenMachineMovesForward_thenMotorsMoveCorrectly() throws Exception {
135+
setUpMotors();
136+
137+
controller.moveForward();
138+
139+
verify(leftMotor).forward();
140+
verify(rightMotor).forward();
141+
}
142+
143+
@Test
144+
public void whenMachineMovesBackward_thenMotorsMoveCorrectly() throws Exception {
145+
setUpMotors();
146+
147+
controller.moveBackward();
148+
149+
verify(leftMotor).backward();
150+
verify(rightMotor).backward();
151+
}
152+
153+
@Test
154+
public void whenMachineTurnLeft_thenMotorsMoveCorrectly() throws Exception {
155+
setUpMotors();
156+
157+
controller.turnLeft();
158+
159+
verify(leftMotor).backward();
160+
verify(rightMotor).forward();
161+
}
162+
163+
@Test
164+
public void whenMachineTurnRight_thenMotorsMoveCorrectly() throws Exception {
165+
setUpMotors();
166+
167+
controller.turnRight();
168+
169+
verify(leftMotor).forward();
170+
verify(rightMotor).backward();
171+
}
172+
173+
@Test
174+
public void whenMachineHalt_thenMotorsStopCorrectly() throws Exception {
175+
setUpMotors();
176+
177+
controller.halt();
178+
179+
verify(leftMotor).stop();
180+
verify(rightMotor).stop();
181+
}
182+
183+
@Test
184+
public void whenMotorSpeedsAreNotInitialized_thenMovesForwardWithDefaultValue() throws Exception {
185+
setUpMotors();
186+
187+
controller.moveForward();
188+
189+
verify(leftMotor).setSpeed(CarControllerBase.MotorProperty.INIT_MOTOR_POWER);
190+
verify(rightMotor).setSpeed(CarControllerBase.MotorProperty.INIT_MOTOR_POWER);
191+
}
192+
193+
@Test
194+
public void whenSetMotorPowerCalled_thenMovesForwardWithTheValue() throws Exception {
195+
setUpMotors();
196+
197+
controller.setMotorPower(LeftMotor, 10);
198+
controller.setMotorPower(RightMotor, 10);
199+
200+
controller.moveForward();
201+
202+
verify(leftMotor).setSpeed(10);
203+
verify(rightMotor).setSpeed(10);
204+
}
205+
206+
@Test
207+
public void whenSetMotorPowerCalledWithOverUpperBoundValue_thenMovesForwardWithUpperBoundValue() throws Exception {
208+
setUpMotors();
209+
210+
controller.setMotorPower(LeftMotor, 200);
211+
controller.setMotorPower(RightMotor, 200);
212+
213+
controller.moveForward();
214+
215+
verify(leftMotor).setSpeed(100);
216+
verify(rightMotor).setSpeed(100);
217+
}
218+
219+
@Test
220+
public void whenSetMotorPowerCalledWithUnderLowerBoundValue_thenMovesForwardWithLowerBoundValue() throws Exception {
221+
setUpMotors();
222+
223+
controller.setMotorPower(LeftMotor, -10);
224+
controller.setMotorPower(RightMotor, -10);
225+
226+
controller.moveForward();
227+
228+
verify(leftMotor).setSpeed(0);
229+
verify(rightMotor).setSpeed(0);
230+
}
231+
232+
@Test
233+
public void whenControllerCloses_thenMachineDisconnects() throws Exception {
234+
controller.close();
235+
236+
verify(machine).disconnect();
237+
}
238+
}

app/src/androidTest/java/com/pileproject/drive/execution/NxtCarControllerTest.java renamed to app/src/androidTestNxt/java/com/pileproject/drive/execution/NxtCarControllerTest.java

File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
12
<!--
23
34
Copyright (C) 2011-2017 The PILE Developers <pile-dev@googlegroups.com>
@@ -15,13 +16,10 @@
1516
limitations under the License.
1617
1718
-->
18-
<menu xmlns:android="http://schemas.android.com/apk/res/android"
19-
xmlns:app="http://schemas.android.com/apk/res-auto"
20-
xmlns:tools="http://schemas.android.com/tools"
21-
tools:context=".MainActivity">
22-
<item
23-
android:id="@+id/action_settings"
24-
android:orderInCategory="100"
25-
android:title="@string/action_settings"
26-
app:showAsAction="never"/>
27-
</menu>
19+
<manifest
20+
package="com.pileproject.drive"
21+
xmlns:android="http://schemas.android.com/apk/res/android">
22+
23+
<application
24+
android:theme="@style/AppThemeEv3.NoActionBar" />
25+
</manifest>
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* Copyright (C) 2011-2017 The PILE Developers <pile-dev@googlegroups.com>
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.pileproject.drive.machine;
17+
18+
import com.pileproject.drive.preferences.MachinePreferences;
19+
import com.pileproject.drivecommand.model.ev3.Ev3Machine;
20+
import com.pileproject.drivecommand.model.ev3.port.Ev3InputPort;
21+
import com.pileproject.drivecommand.model.ev3.port.Ev3OutputPort;
22+
23+
import java.util.Arrays;
24+
import java.util.List;
25+
26+
import static com.pileproject.drive.app.DriveApplication.getContext;
27+
import static com.pileproject.drive.machine.CarControllerBase.InputDevice.COLOR;
28+
import static com.pileproject.drive.machine.CarControllerBase.InputDevice.RANGEFINDER;
29+
import static com.pileproject.drive.machine.CarControllerBase.InputDevice.TOUCH;
30+
31+
/**
32+
* An implementation of {@link CarControllerBase} that controls LEGO MINDSTORMS EV3.
33+
*/
34+
public class Ev3CarController extends CarControllerBase {
35+
/**
36+
* An internal class that contains sensor properties.
37+
*/
38+
public static final class SensorProperty {
39+
public static final List<String> ALL_SENSORS = Arrays.asList(
40+
TOUCH,
41+
COLOR,
42+
RANGEFINDER
43+
);
44+
45+
public static final class ColorSensor {
46+
public static final int PCT_MIN = 0;
47+
public static final int PCT_MAX = 100;
48+
}
49+
50+
public static final class Rangefinder {
51+
public static final int CM_MIN = 0;
52+
public static final int CM_MAX = 255;
53+
}
54+
}
55+
56+
/**
57+
* Binds each sensor and motor to their ports by using <code>MachinePreferences</code> which is based on
58+
* {@link com.pileproject.drive.preferences.MachinePreferencesSchema}.
59+
*
60+
* @param machine an {@link Ev3Machine} to be manipulated
61+
*/
62+
public Ev3CarController(Ev3Machine machine) {
63+
mMachine = machine;
64+
65+
MachinePreferences preferences = MachinePreferences.get(getContext());
66+
67+
// connect motors
68+
connectOutputPort(preferences.getOutputPortA(), Ev3OutputPort.PORT_A);
69+
connectOutputPort(preferences.getOutputPortB(), Ev3OutputPort.PORT_B);
70+
connectOutputPort(preferences.getOutputPortC(), Ev3OutputPort.PORT_C);
71+
connectOutputPort(preferences.getOutputPortD(), Ev3OutputPort.PORT_D);
72+
73+
// connect sensors
74+
connectInputPort(preferences.getInputPort1(), Ev3InputPort.PORT_1);
75+
connectInputPort(preferences.getInputPort2(), Ev3InputPort.PORT_2);
76+
connectInputPort(preferences.getInputPort3(), Ev3InputPort.PORT_3);
77+
connectInputPort(preferences.getInputPort4(), Ev3InputPort.PORT_4);
78+
}
79+
80+
@Override
81+
public List<String> getAllInputDevices() {
82+
return SensorProperty.ALL_SENSORS;
83+
}
84+
85+
@Override
86+
public int getColorSensorIlluminance() {
87+
if (mColorSensor == null) return -1;
88+
return mColorSensor.getIlluminance();
89+
}
90+
91+
@Override
92+
public int getRangefinderDistance() {
93+
if (mRangefinder == null) return -1;
94+
return mRangefinder.getDistance();
95+
}
96+
97+
@Override
98+
public boolean isTouchSensorTouched() {
99+
if (mTouchSensor == null) return false;
100+
return mTouchSensor.isTouched();
101+
}
102+
103+
@Override
104+
public List<String> getAllOutputDevices() {
105+
// NOTE: add more devices if we want to use them (e.g., Buzzer)
106+
return CarControllerBase.MotorProperty.ALL_MOTORS;
107+
}
108+
109+
}

0 commit comments

Comments
 (0)