Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Lego Mindstorms EV3? #6

Open
jabrena opened this issue Aug 9, 2018 · 35 comments
Open

Add support for Lego Mindstorms EV3? #6

jabrena opened this issue Aug 9, 2018 · 35 comments

Comments

@jabrena
Copy link
Contributor

jabrena commented Aug 9, 2018

Hi,

I would like to test your project on EV3.

Any orientation to begin?

Juan Antonio

@jabrena
Copy link
Contributor Author

jabrena commented Aug 9, 2018

What is the usage of the Depth Camera?
Is it necessary to do SLAM?

Juan Antonio

@rlsutton1
Copy link
Owner

The depth camera is not currently required for anything. It didn't have the range I required.

@rlsutton1
Copy link
Owner

rlsutton1 commented Aug 10, 2018

Initial orientation of the ribot is unimportant or are you asking about the lidar

@jabrena
Copy link
Contributor Author

jabrena commented Aug 10, 2018

Good morning @rlsutton1,

Yes, I am interesting to reuse SLAM features with a robot developed with EV3.
This is the purpose.

I would like to see if the classes that model the robot with the Roomba connection has some kind of Factory or something similar in order to provide another implementation in this case an EV3.

@rlsutton1
Copy link
Owner

Sorry, no factory.

There are 2 classes for the roomba, RoombaRobot and Roomba630.

A factory is an excellent idea. You could copy RoombaRobot with minimal changes. You would have to completly rewrite Roomba630 for your platform.

I'll also point out that most of the high level control is run on a separate computer.

There is some ip addresses that will probably need reconfiguring.

I no longer use Pi4j but there is old code in the project for it. I expect you may have problems if it is not removed.

If i get time this weekend I'll try to remove the Pi4j code.

What time zone are you in, I'm GMT +10.

@rlsutton1
Copy link
Owner

I will also add some info to the readme on how to launch the code. I'd like to help you and document the process for others in the readme of this project.

@jabrena
Copy link
Contributor Author

jabrena commented Aug 10, 2018

I will fork the project this weekend. I will say something next week.

Cheers

@rlsutton1
Copy link
Owner

No problem, I've now removed pi4j and a few other libs from the code. haven't tested it though

@jabrena
Copy link
Contributor Author

jabrena commented Aug 11, 2018

I will test it :)

@jabrena
Copy link
Contributor Author

jabrena commented Aug 11, 2018

Good afternoon,

I reviewed ´master´ branch and exist some compilation problems.

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project piBot: Compilation failure: Compilation failure: 
[ERROR] /Users/jabrena/Documents/DATA/2018/RESEARCH/robotics/java/piBot/src/main/java/au/com/rsutton/mapping/particleFilter/RobotPoseSource.java:[32,25] cannot find symbol
[ERROR]   symbol:   class ParticleFilterStatus
[ERROR]   location: interface au.com.rsutton.mapping.particleFilter.RobotPoseSource
[ERROR] /Users/jabrena/Documents/DATA/2018/RESEARCH/robotics/java/piBot/src/main/java/au/com/rsutton/navigation/Navigator.java:[19,34] package au.com.rsutton.depthcamera does not exist
[ERROR] /Users/jabrena/Documents/DATA/2018/RESEARCH/robotics/java/piBot/src/main/java/au/com/rsutton/mapping/particleFilter/ParticleFilterImpl.java:[521,17] cannot find symbol
[ERROR]   symbol:   class ParticleFilterStatus
[ERROR]   location: class au.com.rsutton.mapping.particleFilter.ParticleFilterImpl
[ERROR] /Users/jabrena/Documents/DATA/2018/RESEARCH/robotics/java/piBot/src/main/java/au/com/rsutton/mapping/particleFilter/ParticleFilterImpl.java:[744,16] cannot find symbol
[ERROR]   symbol:   class ParticleFilterStatus
[ERROR]   location: class au.com.rsutton.mapping.particleFilter.ParticleFilterImpl
[ERROR] /Users/jabrena/Documents/DATA/2018/RESEARCH/robotics/java/piBot/src/main/java/au/com/rsutton/robot/lidar/MovingLidarObservationBufferTest.java:[11,45] cannot find symbol
[ERROR]   symbol:   class ParticleFilterStatus
[ERROR]   location: package au.com.rsutton.mapping.particleFilter
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

Basically, we have to review the existence of the class:

import au.com.rsutton.depthcamera.PointCloudUI;

and the existence of the class ParticleFilterStatus

I have just created a PR:
#7

Juan Antonio

@jabrena jabrena changed the title How to use the solution on EV3 brick? How to add support for Lego Mindstorms EV3? Aug 11, 2018
@rlsutton1
Copy link
Owner

Hi @jabrena,

OK, so I've resolved the issues with PointCouldUI and ParticleFilterStatus, they were in the test folder instead of the java folder.

I accidentally committed back the pom.xml with my version of RPLidar, your version seems to be missing the continuous scan method which I had written and used in this project.

You will not be able to run some of the junit tests, this is because I've been a bit lazy and used junit as a convenient way to launch code that interacts with the robot. I would like to change that, but I don't want to create merge conflicts for either of us. I was intending to convert these junits to be launched from the main entry point menu. If you are going to be focusing of the replacement of the Roomba code we shouldn't have any conflicts.

So if its OK with you, I'll find some time to move and refactor these junit tests.

@rlsutton1
Copy link
Owner

@jabrena,

I've just converted the MapBuilder junit to have a launch option from au.com.rsutton.entryPoint.Main.

@jabrena
Copy link
Contributor Author

jabrena commented Aug 11, 2018

I will test everything tomorrow

Thanks mate

@jabrena
Copy link
Contributor Author

jabrena commented Aug 12, 2018

Hi observed the case with the dependency RPLidar.

I think that you are using a local dependency in that case.
Can you do a pull request to my project to publish a new version with the missing methods?
https://github.com/ev3dev-lang-java/RPLidar4J

I will publish in order to continue with the process.

Juan Antonio

@jabrena jabrena changed the title How to add support for Lego Mindstorms EV3? Add support for Lego Mindstorms EV3? Aug 12, 2018
@jabrena
Copy link
Contributor Author

jabrena commented Aug 12, 2018

Or put the library inside of this project. As you like :)

@rlsutton1
Copy link
Owner

Here is my pull request from earlier ev3dev-lang-java/RPLidar4J#3

I may have some subsequent fixes that are not in the pull request, but it certainly includes the continousScan method

@jabrena
Copy link
Contributor Author

jabrena commented Aug 13, 2018

I am going to review now

@jabrena
Copy link
Contributor Author

jabrena commented Aug 13, 2018

Hi mate,

can you send the pull request to this branch?
https://github.com/ev3dev-lang-java/RPLidar4J/tree/master-rlsutton1

@jabrena
Copy link
Contributor Author

jabrena commented Aug 13, 2018

Released a new Snapshot version about the RPLidar4J 0.6.1-SNAPSHOT

I have just created a new PR:
#8

@jabrena
Copy link
Contributor Author

jabrena commented Aug 13, 2018

Hi @rlsutton1, Although I can execute the class: au.com.rsutton.entryPoint.Main how to set the IP for the EV3 Brick to connect?

What is the next steps to upgrade the project to add the initial support for EV3?

Cheers

Juan Antonio

@jabrena
Copy link
Contributor Author

jabrena commented Aug 14, 2018

I observed when the application start that appear a predefined map:

.*********************************************************************************
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...................*****************************************...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*..................**.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*..................**
.*...................*.......................................*...................*
.*...................*.......................................*...................*
.*...................*.......................................*..................**
.*...................*****************************************...................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*...............................................................................*
.*********************************************************************************

Why?

@rlsutton1
Copy link
Owner

the predefined map is for testing without an actual robot attached.

In MapBuilder if you set simulator = false, then it would try to use an actual robot and build a map from scratch

IP addresses are configured in HazelCastInstance.

with that done, you would start the robot (menu 0) on the eva3 and then start MapBuilder on your computer (menu 8).

@jabrena
Copy link
Contributor Author

jabrena commented Aug 14, 2018

Found!

	HazelCastInstance()
	{

		String hostname;
		InetAddress ip;
		try
		{
			ip = InetAddress.getLocalHost();
			hostname = ip.getHostName();
			System.out.println("Your current IP address : " + ip);
			System.out.println("Your current Hostname : " + hostname);

		} catch (UnknownHostException e)
		{

			e.printStackTrace();
		}

		config = new Config();
		config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(true);
		TcpIpConfig tcpIpConfig = config.getNetworkConfig().getJoin().getTcpIpConfig();
		tcpIpConfig.setEnabled(true);
		for (int i = 2; i < 22; i++)
		{
			tcpIpConfig.addMember("192.168.0." + i);
		}
		tcpIpConfig.addMember("10.10.0.41");

		h = Hazelcast.newHazelcastInstance(config);

	}

@jabrena
Copy link
Contributor Author

jabrena commented Aug 14, 2018

In what class, I could change the communication from Roomba to EV3?

@jabrena
Copy link
Contributor Author

jabrena commented Aug 14, 2018

I am going to sleep now.

Tomorrow, I will check your notes.

Cheers

@jabrena
Copy link
Contributor Author

jabrena commented Aug 14, 2018

Note: The project has a good level of complexity. Congrats!!!

@jabrena
Copy link
Contributor Author

jabrena commented Aug 14, 2018

A new question: Do you think that it is possible to save a map and load in a new session?

@jabrena
Copy link
Contributor Author

jabrena commented Aug 14, 2018

Hi @rlsutton1,

I re read again your note about Roomba:

There are 2 classes for the roomba, RoombaRobot and Roomba630.

A factory is an excellent idea. You could copy RoombaRobot with minimal changes. You would have to completly rewrite Roomba630 for your platform.

I checked that package:

package au.com.rsutton.robot.roomba;

and the strategy is to teleoperate the robot from this project. In this sense, I could create something to do the same. I could create a client to wait for commands.

I will create a new package:

package au.com.rsutton.robot.ev3;

Today, I will create a project to provide an interface from the brick to the desktop application

@rlsutton1
Copy link
Owner

Can you run java code on the brick and communicate over wifi?

The code in roomba and roomba630 run on my robot, i would expect that you would implement your own version of roomba630 for the brick. My code already handles sending messages between the robot and a computer via wifi.

You run one copy of the program on the brick and one on your computer.

@rlsutton1
Copy link
Owner

It will be possible to save a map and load it later for another session, but I have not bothered to write that code yet. I am still quite focused on improving the map building capabilities at the moment.

@jabrena
Copy link
Contributor Author

jabrena commented Aug 14, 2018

Hi @rlsutton1,

Can you run java code on the brick and communicate over wifi?

Yes, of course.

I am building the client for EV3.
What is the interface which it is necessary to implement?

Example:

Actuators:

  • LeftMotor tacho (long)
  • RightMotor tacho (long)

Sensors:

  • LIDAR (angle (float), distance (cm or mm??))
  • Battery (voltage (float))

I observed that in the class Roomba360 the code uses this object:

private RoombaJSSC roomba;

To communicate with Roomba platform.
I would like to know what is the minimum methods used to create the map.

Juan Antonio

@rlsutton1
Copy link
Owner

rlsutton1 commented Aug 14, 2018

The minium set of methods that must be implemented by RoombaJSSC are:

this is wrong --> void drive(rightWheelVelocity,leftWheelVelocity) - mm per second
correction --> void drive(velocity,radius) - mm per second, mm
void distanceTraveled() - mm since the last call to this method
double angleTurned() - degrees since the last call to this method
driveDirect(rightWheelVelocity,leftWheelVelocity) - mm per second

There is JavaDoc on these methods in RoombaJSSC and also they are well documented by Roomba OI

all other methods could return fixed values -
batteryVoltage should return 12500
the bumpLeft and bumpRight methods should return false

LIDAR distance is in CM

@jabrena
Copy link
Contributor Author

jabrena commented Aug 15, 2018

What is the difference between drive and directDrive?

@rlsutton1
Copy link
Owner

rlsutton1 commented Aug 15, 2018

My earlier statement about what drive does was incorrect.

Drive specifies a speed and a turn radius.

Here is text directly from the Roomba OI document about drive and direct drive

Drive Opcode: 137 Data Bytes: 4
This command controls Create’s drive wheels. It takes four
data bytes, interpreted as two 16-bit signed values using
two’s complement. The first two bytes specify the average
velocity of the drive wheels in millimeters per second
(mm/s), with the high byte being sent first. The next two
bytes specify the radius in millimeters at which Create will
turn. The longer radii make Create drive straighter, while
the shorter radii make Create turn more. The radius is
measured from the center of the turning circle to the center
of Create. A Drive command with a positive velocity and a
positive radius makes Create drive forward while turning
toward the left. A negative radius makes Create turn toward
the right. Special cases for the radius make Create turn
in place or drive straight, as specified below. A negative
velocity makes Create drive backward.
NOTE: Internal and environmental restrictions may prevent
Create from accurately carrying out some drive commands.
For example, it may not be possible for Create to drive at
full speed in an arc with a large radius of curvature.
• Serial sequence: [137] [Velocity high byte] [Velocity low byte]
[Radius high byte] [Radius low byte]
• Available in modes: Safe or Full
• Changes mode to: No Change
• Drive data byte 1: Velocity (-500 – 500 mm/s)
• Drive data byte 2: Radius (-2000 – 2000 mm)
Special cases:
Straight = 32768 or 32767 = hex 8000 or 7FFF
Turn in place clockwise = hex FFFF
Turn in place counter-clockwise = hex 0001
Example:
To drive in reverse at a velocity of -200 mm/s while
turning at a radius of 500mm, send the following serial
byte sequence:
[137] [255] [56] [1] [244]
Velocity = -200 = hex FF38 = [hex FF] [hex 38] = [255] [56]
Radius = 500 = hex 01F4 = [hex 01] [hex F4] = [1] [244]

Drive Direct Opcode: 145 Data Bytes: 4
This command lets you control the forward and backward
motion of Create’s drive wheels independently. It takes
four data bytes, which are interpreted as two 16-bit signed
values using two’s complement. The first two bytes specify
the velocity of the right wheel in millimeters per second
(mm/s), with the high byte sent first. The next two bytes
specify the velocity of the left wheel, in the same format.
A positive velocity makes that wheel drive forward, while a
negative velocity makes it drive backward.
• Serial sequence: [145] [Right velocity high byte]
[Right velocity low byte] [Left velocity high byte]
[Left velocity low byte]
• Available in modes: Safe or Full
• Changes mode to: No Change
• Drive Direct data byte 1: Right wheel velocity
(-500 – 500 mm/s)
• Drive Direct data byte 1: Left wheel velocity
(-500 – 500 mm/s)

@rlsutton1
Copy link
Owner

I've just committed a couple of fixes which would have impacted this issue.

  • distance traveled was inverted.
  • the addition of a start up menu prevented the rover from starting up.

With regard to the inverted distance, It never ceases to amaze me how tolerant a particle filter is of bad data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants