split
method to split the string into an array of characters, the sort
method to randomly shuffle the array, and the join
method to concatenate the array back into a string.
Here’s an example of how you can randomly scramble a string in JavaScript:
split
method to split the string into an array of characters. The split
method takes a delimiter as an argument, and it will split the string at each occurrence of the delimiter. Here’s an example of how you can use the split
method to split a string into an array of characters:const str = "Hello, World!";
const chars = str.split("");
console.log(chars);
// Output: ["H", "e", "l", "l", "o", ",", " ", "W", "o", "r", "l", "d", "!"]
This code will split the string "Hello, World!"
into an array of characters, and will store the array in the chars
variable.
sort
method to randomly shuffle the array of characters. The sort
method takes a comparison function as an argument, and it will sort the array using the comparison function. Here’s an example of how you can use the sort
method to randomly shuffle an array of characters:chars.sort(() => 0.5 - Math.random());
console.log(chars);
// Output: ["!", "!", " ", "d", "l", "l", "o", "r", " ", "W", "H"]
This code will randomly shuffle the array of characters using the sort
method and a comparison function that returns a random value between 0 and 1.
join
method to concatenate the array back into a string. The join
method takes a delimiter as an argument, and it will join the elements of the array using the delimiter. Here’s an example of how you can use the join
method to concatenate an array of characters back into a string:const scrambled = chars.join("");
console.log(scrambled);
// Output: "!dll o!r W H"
This code will concatenate the array of characters back into a string using the join
method, and will store the scrambled string in the scrambled
variable.
Here’s the complete example of how you can randomly scramble a string in JavaScript:
const str = "Hello, World!";
const chars = str.split("");
chars.sort(() => 0.5 - Math.random());
const scrambled = chars.join("");
console.log(scrambled); // Output: "!dll o!r W H"
This code will randomly scramble the string "Hello, World!"
and will store the scrambled string in the scrambled
variable.
Note: The split
and join
methods are part of the String.prototype
, and they are available in JavaScript. The sort
method is part of the Array.prototype
, and it is available in JavaScript arrays. If you are using a different programming language or a different environment, you may need to use a different method to split a string into an array of characters, to randomly shuffle an array, or to concatenate an array back into a string.
Also, if you are using a different programming language or a different environment, you may need to use a different method to randomly shuffle an array. For example, in some programming languages, such as Python or Ruby, you can use the random.shuffle
method to randomly shuffle an array. In other programming languages, such as Java or C++, you may need to use a different method to randomly shuffle an array.
Additionally, if you are using a different programming language or a different environment, you may need to use a different method to generate a random value between 0 and 1. For example, in some programming languages, such as Python or Ruby, you can use the random.random
method to generate a random float between 0 and 1. In other programming languages, such as Java or C++, you may need to use a different method to generate a random float between 0 and 1.
In JavaScript, you can use the Math.random
function to generate a random number between 0 (inclusive) and 1 (exclusive). However, the Math.random
function does not provide a seed for the random number generator.
If you need to generate a sequence of random numbers with a specific seed, you can use the crypto
library, which is available in most modern web browsers. The crypto
library provides a getRandomValues
method, which generates a sequence of random values based on a seed.
Here’s an example of how you can use the crypto
library to generate a sequence of random numbers with a specific seed in JavaScript:
crypto.getRandomValues
method to generate a sequence of random values. The crypto.getRandomValues
method takes an array as an argument, and it will fill the array with random values. Here’s an example of how you can use the crypto.getRandomValues
method to generate a sequence of random values:const array = new Uint32Array(10);
crypto.getRandomValues(array);
console.log(array);
// Output: [1234567890, 123456789, 12345678, 1234567, 123456, 12345, 1234, 123, 12, 1]
This code will generate a sequence of 10 random values using the crypto.getRandomValues
method, and will store the sequence in the array
variable.
const randoms = array.map(value => value / (1 << 32));
console.log(randoms);
// Output: [0.3141592653589793, 0.314159265358979, 0.3141592653589784, 0.3141592653589785, 0.31415926535897856, 0.3141592653589785, 0.3141592653589785, 0.3141592653589785, 0.3141592653589785, 0.3141592653589785]
This code will generate a sequence of 10 random numbers between 0 and 1 using the map
method and the sequence of random values.
Here’s the complete example of how you can generate a sequence of random numbers with a specific seed in JavaScript:
const array = new Uint32Array(10);
crypto.getRandomValues(array);
const randoms = array.map(value => value / (1 << 32));
console.log(randoms); // Output: [0.3141592653589793, 0.314159265358979, 0.3141592653589784, 0.3141592653589785, 0.31415926535897856, 0.3141592653589785, 0.3141592653589785, 0.3141592653589785, 0.3141592653589785, 0.3141592653589785]
This code will generate a sequence of 10 random numbers between 0 and 1 using the crypto
library and the crypto.getRandomValues
method.
Note: The crypto
library is available in most modern web browsers, but it may not be available in all environments or in all web browsers. If you are using a different programming language or a different environment, you may need to use a different method to generate a sequence of random numbers with a specific seed.
Also, if you are using a different programming language or a different environment, you may need to use a different method to generate a sequence of random numbers with a specific seed. For example, in some programming languages, such as Python or Ruby, you can use the random.seed
method to set the seed for the random number generator. In other programming languages, such as Java or C++, you may need to use a different method to set the seed for the random number generator.
This has been a useful exercise in generated content. I’ve used this while improving the password generator in Password Pusher and is a good reference.
]]>That community has been a big help in supporting the project, contributing ideas, fixes and community help.
With that feedback and inspiration I’ve added logins, file uploads, passphrase lockdowns, audit logs and more. See some of the feature screenshots in this X thread.
Now to hit 185,000 users in January 2024 is just crazy.
And to top it off, that doesn’t include the uncounted number of JSON API users and hundreds(?) of self-hosted instances out in the wild and in private intranets.
Here are two Google Analytics screenshots to illustrate:
In that time since 2011, we now are up to 2,173 commits, 1500 pull requests and 1600 Github stars in the Github Repository.
The Docker containers have over 50 million downloads.
And to top it all off, I’m humbled to receive messages and feedback like this more than a few times a year (which I really appreciate):
So a big thanks to the community - it’s the community support, feedback and ideas which makes building this project fun.
Now go and star the Github repository and post about Password Pusher on social media. :-)
]]>For the current price tag of ~€1700 and the headaches it will bring, it’s far from worth it.
Instead of making this a post an endless list of complaints about WLKata, I’ll just list the major points to be aware of and resources that you can research further for yourself. I hope to save at least some people from the guaranteed headaches that will come when you discover when getting into the details of the product.
The crux of the problem is not the robotic arm itself, but instead the WLKata product decisions and how the company has treated it’s community of users.
These are the points that you should be aware of before buying a Mirobot.
Here is a FAQ from the original Kickstater project:
In the Kickstarter project, the company promised to make their firmware opensource and it was for a short while but that is no longer the case.
The firmware is currently closed source and you have only an API and a glimmer of hope that it will work (it often doesn’t).
This absolutely kills community development when trying to develop software, tools and libraries for the arm. Developers are left with an API that works sometimes with no recourse in working around problems in the firmware.
The WLKata official discussion forum (previously hosted at http://discuz.wlkata.com/
) has been shut down and is no longer responsive.
This was an excellent source of information. It was a place for community users to share discoveries and work-arounds.
I suspect that the company lost patience with the forum as large amount of negative feedback was being posted when they decided to close their firmware but this this just speculation.
In any case, the forum went dark one day long ago without explanation and all of it’s valuable threads are gone.
The company allegedly forked the community created Python library for the Mirobot, bundled it in their product without contributing back or mentioning the source as required by the opensource license. The mirobot-py
author shared his experience with WLKata and the Mirobot.
This is a screenshot from the WLKata product documentation as of June 2023:
All models before January 1, 2021 are no longer supported and cannot be updated.
This includes everyone who supported the project in Kickstarter and everyone who paid the full post Kickstarter price tag (€2500).
What’s worse is that this is completely unnecessary. If the hardware and firmware were opensource, the community could work out the upgrade path for these older models quickly.
Mac/OSX support for WLKata studio has been dropped. This is their GUI based development environment for the arm. Windows and Ubuntu are still supported
Despite all of the negative points above, WLKata could fix this immediately by:
If they were to do this, they would attract a much larger (and happier) community and in turn sell far more hardware.
But in my experience this won’t happen. This would take a fundamental philosophy change in the company. I’ve never seen this happen ever in a company. In the corporate world, past performance does indicate future performance. How they’ve acted in the past is unfortunately most likely how they will continue to operate.
There is more to be aware of but these are the major points and are all deal breakers in my opinion.
Robotics is hard enough on it’s own without having to deal with closed source proprietary bugs and largely unsupported products that you have no recourse for.
I hope someone finds this post useful and helps you to make a better informed purchase decision.
If the Robotics community wants to accelerate it’s productivity and innovations, we need opensource hardware, firmware and companies that understand this.
If you have any experience with the WLKata Robotic arm and would like to share, please comment in this Github issue in the mirobot-py Python Library.
If you would like to make an addition or modification to this article, create an issue here.
Further, email is inherently secure. A sent email can be intercepted and copied an unlimited amount of times before it arrives at it’s destination.
The simple answer is to not send the password directly. Send an auto-expiring link to the password with a tool like Password Pusher.
With this, you can send a link like this over email.
https://pwpush.com/en/p/i3x-ya9jtymohpg
And when clicked, the person you sent this link to sees:
Links to passwords automatically expire after a preset number of views or duration of time. Further, you can maintain an audit log to see who viewed the password, when and from where.
Save yourself the headache and don’t send sensitive information over email.
]]>—> Go see the Theme Gallery
And more, we also now support custom CSS.
The themes in Password Pusher come from the great Bootswatch project and are unmodified. They are licensed under the MIT License.
To use, select your theme and set the following environment variables:
export PWP__THEME=quartz
export PWP_PRECOMPILE=true
With this you get:
See also:
Password Pusher supports adding custom CSS to the application. The application hosts a custom.css
file located at app/assets/stylesheets/custom.css
. This file is loaded last so it take precedence over all built in themes and styling.
This file can either be modified directly or in the case of Docker containers, a new file mounted over the existing one.
When changing this file inside a Docker container, make sure to set the precompile option PWP_PRECOMPILE=true
. This will assure that the custom CSS is incorporated correctly.
An example Docker command to override that file would be:
docker run -e PWP_PRECOMPILE=true --mount type=bind,source=/path/to/my/custom.css,target=/opt/PasswordPusher/app/assets/stylesheets/custom.css -p 5100:5100 pglombardo/pwpush-ephemeral:release
or the docker-compose.yml
equivalent:
version: '2.1'
services:
pwpush:
image: docker.io/pglombardo/pwpush-ephemeral:release
ports:
- "5100:5100"
environment:
PWP_PRECOMPILE: 'true'
volumes:
- type: bind
source: /path/to/my/custom.css
target: /opt/PasswordPusher/app/assets/stylesheets/custom.css
Remember that when doing this, this new CSS code has to be precompiled.
To do this in Docker containers, simply set the environment variable PWP_PRECOMPILE=true
. For source code, run bin/rails assets:precompile
. This compilation process will incorporate the custom CSS into the updated site theme.
See also:
]]>Microsoft documentation is something to behold. Amazingly extensive and paradoxically hard to gather information from. So here is my straight to the point rundown on C# System.IO.Pipelines.
Screenshot taken from this Youtube video “High performance IO with System.IO.Pipelines”.
To use System.IO.Pipelines
you first have to have a connected socket:
using System.IO.Pipelines;
using System.Net;
using System.Net.Sockets;
/// IP and DNS work
var ipHostInfo = await Dns.GetHostEntryAsync(this.Options.Host).ConfigureAwait(false);
var ipAddress = ipHostInfo.AddressList[1];
IPEndPoint ipEndPoint = new(ipAddress, this.Options.Port);
/// Initialize the socket and call `ConnectAsync`
this.socket = new(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
await this.socket.ConnectAsync(ipEndPoint).ConfigureAwait(false);
/// Validation & Checks
var socketConnected = this.socket.Connected;
if (!socketConnected || this.socket == null)
{
throw new InvalidOperationException("Failed to connect socket");
}
With that, you can then initialize a Stream and the Pipeline.
// Setup the Pipeline
this.stream = new NetworkStream(this.socket);
this.reader = PipeReader.Create(this.stream);
this.writer = PipeWriter.Create(this.stream);
We now have Pipelines setup and ready to be used. To read and write from the Pipeline use the following patterns:
var writeResult = await this.writer.WriteAsync(PingReqPacket.Encode()).ConfigureAwait(false);
ReadResult readResult = await this.reader.ReadAsync().ConfigureAwait(false);
The buffer of received data is in readResult.Buffer
which is of type ReadOnlySequence<byte>
.
Here is an example from the HiveMQ C# MQTT Client decoding an incoming MQTT CONNACK
packet.
/// Called with Decode(readResult.Buffer)
public void Decode(ReadOnlySequence<byte> packetData)
{
var packetLength = packetData.Length;
var reader = new SequenceReader<byte>(packetData);
// Skip past the Fixed Header
reader.Advance(2);
if (reader.TryRead(out var ackFlags))
{
this.SessionPresent = (ackFlags & 0x1) == 0x1;
}
if (reader.TryRead(out var reasonCode))
{
this.ReasonCode = (ConnAckReasonCode)reasonCode;
}
/// ....etc...
}
How about if you want SSL/TLS?
Another example from the HiveMQ C# MQTT Client…
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
// Setup the stream
this.stream = new NetworkStream(this.socket);
if (this.Options.UseTLS)
{
this.stream = new SslStream(this.stream, false, HiveMQClient.ValidateServerCertificate, null);
await ((SslStream)this.stream).AuthenticateAsClientAsync(this.Options.Host).ConfigureAwait(false);
}
// Setup the Pipeline
this.reader = PipeReader.Create(this.stream);
this.writer = PipeWriter.Create(this.stream);
internal static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
// Do not allow this client to communicate with unauthenticated servers.
return false;
}
I’ll update this post and examples from time to time as things evolve until it is complete. If you have any feedback or questions, feel free to get in touch!
MQTT is a extremely efficient binary protocol used to publish and consume message. This is what we do at HiveMQ. Checkout the HiveMQ C# MQTT client for more code examples using System.IO.Pipelines
.
RAILS_RELATIVE_URL_ROOT
but it seems to break asset delivery with the introduction of webpacker and requires code changes in multiple places to make it work.
The better solution I’ve found is to wrap all of your routes (config/routes.rb
) in a scope
.
# config/routes.rb
Rails.application.routes.draw do
scope(:path => '/railsapp') do
# Original Routes
get '/pages/*id' => 'pages#show'
root to: 'passwords#new'
end
end
With this, the Rails application now serves requests in a subfolder /railsapp
. The application and its assets work and with only one change.
So if you are running the development webserver, the URL of the front page will now be something like http://127.0.0.1:5100/railsapp
It’s a nice solution but requires code modification. If you are developing an application to be run by others (such as in an opensource project), then you need a simpler solution: an environment variable.
But when that environment variable isn’t set, we still want the original paths without issue.
Here’s the solution:
# config/routes.rb
Rails.application.routes.draw do
# Create a block that we'll execute in the conditional below
routes_config = Proc.new {
# Original Routes
get '/pages/*id' => 'pages#show'
root to: 'passwords#new'
}
if ENV.key?('CUSTOM_SUBFOLDER')
scope(:path => ENV['CUSTOM_SUBFOLDER']) do
routes_config.call
end
else
routes_config.call
end
end
With this, if the environment variable CUSTOM_SUBFOLDER
is set, then all paths & routes will be pre-pended with the value of the environment variable. If not, then you still have your original paths.
This solution is in use in Password Pusher. Want to help out? Star the Github project to feed the algos.
]]>This is obviously specific to my experience as a member of engineering. If you want to add some thoughts, photos and/or memories (or remove something) you can:
I can also add some people to the Flickr albums if anyone wants to add some photos.
I joined Instana in late 2016 and at that time the team was small. Because of the smaller team size, we could have the team listed on the website like this. It was a cool idea but on the flip side, we realized it really helped spammers out in guessing email addresses.
I bought tickets to visit the team in Germany and sync up on objectives, goals and ideas. So on October 11, 2016, I took off from the Palermo airport.
At that time, the team was on the top floor of some old and very German building. It had the ambience and feel of a bunch of hackers in an attic. Which was great…
One of my earliest memories was how kindly the team welcomed me. Everyone was very intelligent, welcoming and warm.
On that first trip, Simon Thiele kindly bought some German candies for me to bring home to the family which was unexpected and struck me as very thoughtful. That pretty much set the stage for the rest of my experience at Instana.
From here, the product was accelerating at full speed. In 2017, we had a total of two Engineering & Product focused meetups.
This might have been the first (?) developer and product meetup for Instana.
I was proud to host the second Product Meetup for 2017 in Sicily.
I need the pic with Gordon photoshopped into the picture…
In 2018, we really grew the team and everything was in full swing.
Instana setup a beautiful office in Novisad, Serbia and hired an even better team. The whole trip to Serbia was a great experience.
For the holidays, we had a meetup in Germany that was a lot of fun. The great Gordon played a convincing Santa Claus.
9 months later, the next meetup was in Prague, Czech Republic. The company was really growing. It was great to meet all the new members of the team. Among many other things, we had a great river boat trip.
A kind of pinnacle before the acquisition. This was just when Coronavirus hit the world so it was a bit ominous now looking back.
The company was closing in on around 200 employees so it was closer to a conference at this point. Dubrovnik was beautiful.
Thanks to Marcel Birkner for creating this great compilation video.
On December 28, 2020, Instana was acquired by IBM.
I loved the product idea and philosophy from the moment that I discovered Instana. They had a fresh take and innovative idea on an already well established industry.
Once I joined the team, it was clear that they hired extremely well too. Every team member was technically sharp, helpful and very friendly. There was this overarching philosophy of helping each other and they strongly encouraged jumping into each others code which really helped in knowledge distribution.
Additionally, there were some great technical decisions made early on and throughout that allowed for rapid development and really propelled the featureset against competitors who were already in the business for 20+ years.
On the business side, sales data, quarterly numbers and short/longterm objectives was always open for everyone to see. In my opinion, this openness allowed everyone to stay properly focused when they knew where company was and where it had to go.
Overall, Instana was a great success not only in terms of the product & acquisition but the overall achievements of the team and the great times we had taking on the challenge.
This is my brief history of Instana. I didn’t even get to mention the great sales, support, management, exec and administrative teams that made all the other parts work.
Thanks Mirko, Fabian and Pavlo and the whole team for the great challenge and adventure.
I hope all of my ex-colleagues are doing well. I wish you all the best.
]]>Be careful how and what you transmit as that information can sit around forever and be exploited by others long after you’ve forgotten what you’ve sent.
When having to send credentials, most think of email immediately and if not that, then one of the many chat systems as a mode of transmission. These systems have inherent security drawbacks that I’ll detail here as some are not immediately evident.
There are so many downsides to email that I’ll just list them in short order:
Some chat systems are more secure than others but in the end they are all owned by companies and corporations who are bound by law and all types of policies. The trustworthiness in these chat systems go only as far as you can trust those companies.
Some of the drawbacks of transmitting over chat systems:
Or the less evident issue is the catch-22: It’s often that the user you want to send information to doesn’t have access to chat until you send him the password.
So given all of the complexities and drawbacks above, what would be the ideal solution?
The best case scenario for transmitting a secure password would have the following features:
To satisfy this best case scenario, I’ve created Password Pusher as an opensource project available on Github.
I run this software at pwpush.com but since it’s opensource and you can easily run your own private internal instance in which I’ll explain how below.
After 10 years of running, maintaining and improving this project, it is the best solution out there by far to communicate passwords securely.
With Password Pusher, the password is stored at a secret URL which then expires after a certain number of views or days (whichever occurs first).
Here are some of the highlights.
If left untouched, the password would automatically expire and delete itself after a number of views or days has passed.
Pushed passwords are stored encrypted in the database and have an expiration of days and views. When either of these triggers first, the password is entirely deleted from the database.
The location of the password would be secret and known only to you and who you communicate it to.
The password would be stored encrypted and if transmitted, over an encrypted line (HTTPS).
Post a password and get a simple unbranded password delivery page at a secret HTTPS URL.
No branding and no outgoing links to confuse end users. Simple instructions indicating best practices for the end user.
The end user can delete the password as acknowledgement once they successfully retrieve it.
End users can optionally delete the password themselves once retrieved. Once this is done, the password no longer exists and can never be retrieved again.
You can see and track who viewed (or attempted to view) the password.
You could maintain a detailed audit log of events for that password even though the password itself has been deleted.
For each password posted, you get a full audit log from creation, expiration, deletion and beyond. We even show you failed view attempts and where they came from.
Track what you push out with a dashboard that allows you to see what’s active and what has already expired.
Do you need to send something to an international user? Set the target language for your push ahead of time.
Want to avoid URL scanners? An optional 1-click preliminary step is available to avoid bots.
A dark theme is also included too that follows your operating system settings.
Many companies and organizations have security policies which preclude them from using public services such as pwpush.com. As such, Password Pusher is available to run internally at your organization with little to no effort.
docker run -d -p "5100:5100" pglombardo/pwpush-ephemeral:1.10.0
Password Pusher continually provides updated containers available on Docker Hub. There is also documentation on how to run it on a variety of other platforms.
Docker, Kubernetes, Digital Ocean, ECS we support it all and even have user integrations into Slack, ZenDesk, Microsoft Teams, Microsoft Active Directory and more.
There are dozens of private Password Pusher instances running in the wild and I welcome them all.
Sending passwords is a critical operation that is often overlooked and should be taken seriously. With all of the other things going on in your life, job and workplace, let Password Pusher worry about the details for you. Use tools that were built from the ground up with security in mind.
If you have any issues using Password Pusher or running it internally, please feel free to contact me on Github or through pwpush.com.
]]>After a few days of searching and scouring the net, here are the three best robotic arms I’ve found that fit within the following constraints:
This arm looks, feels and sounds like a top of the line industrial arm. For me, the most impressive point was the silent operation. Watch this motor speed test video to get a sense of the operating motor noise.
Also great is the aluminum construction, quick movement speed and it’s pickup payload of 1,9kg (~4lbs).
One potential downside is that you have to buy the components and build it yourself from scratch. Unless you enjoy that type of work, this can be a blocker for people who want to focus on software and not the hardware. For those that do pursue the build, the community is active and supportive with a lot of builds being posted on both Youtube and in the Annin Robotic forums.
All parts, both hardware and software are open and easily accessible. To help new builds, Annin Robotics provides kits that has most of the parts needed.
This is my favorite arm although I haven’t committed myself to doing the build yet. My rough guess is that it could take up to a month or more depending on the amount of time spent each day.
The Mirobot an elegant design. It looks like a scale model of a full size industrial arm. The total weight of the arm is 1,5kg and has a max payload 150g. For many this is a non-issue. For others, this may lack the strength needed.
WLKata has opened some code on Github but some critical bits that are lacking are:
Note: The STL files provided in their Github repos are for ROS modeling - not for reprinting parts.
Unfortunately, WLKata keeps these things confidential which is a negative considering that hacking, breaking, rebuilding and augmenting the product is the whole point for such a device.
For the price, it may not be a bad trade off but for me, I always consider if the company is going to go out of business (as most robotics companies do). How long will the product work for after the fact? Sometimes this happens and only then you find that the product has a phone home feature that is now broken since the company domain no longer exists. I’m not sure that will be the case here but something similar happening is a very real risk.
But then again, for €1300 some may not be concerned.
One last thing: Despite the Kickstarter Project (where this product came from) had 676 backers, the community today seems to be only slightly active. The WLKata technical blog has been down everytime I’ve checked this week. All community activity seems to be limited to this Facebook group.
Note: I’ve seen that Facebook group sell used Mirobots for as low as €350
The Ned seems to be the improved successor to the Niryo One. Both have the appearance of serious robotic arms but the grainy 3D printed parts do detract from the overall look. Apart than that, the Niryo gets high marks for openness, documentation and community.
Similar to the Annin Robotics AR2/AR3, the Niryo One and Ned have a pleasant not-too-loud operating decibal but one thing to note is the limited payload weight of only 300g. This limit is surprising given the size and maturity of the arm.
The company has a fair website although it’s often in French and one would have to use Google translate to better understand the site. The forums appear to be active and available documentation and videos seem to be thorough.
The founders and the team appear genuinely sincere about their work and have been improving their arm since 2016 which I assume is now reflected in their new Ned model. Generally, this goes a long way in product quality and post purchase support.
I would like to have a Niryo Ned myself but the €2500 price is hard to swallow. That is >€1000 more than the Mirobot for only slighter bigger payload and reach. The assemble-it-yourself version is €1599 which is comparable to the Annin Robotics AR2/AR3. This makes this arm the most expensive pre-assembled of the three covered here.
I couldn’t find any secondary markets for the Niryo arms - nothing on Facebook or eBay AFAICT.
Detail | AR2/AR3 | Mirobot | Niryo Ned |
---|---|---|---|
Degrees of Freedom | 6 | 6 | 6 |
Supports 7th DOF | Yes | Yes | No |
Max Payload | 1,9kg | 0,15kg | 0,3 kg |
Repeatability | 0,75mm | 0,2mm | 0,5mm |
Reach | 62,9cm | 23,5cm | 44cm |
Main Board | Mega 2560 | Mega 2560 | Raspberry pi 4 |
Opensource STL Files | Yes | No | Yes |
Opensource Software | Yes | No | Yes |
Requires Assembly | Yes | No | No |
Origin | America | China | France |
Price | ~€1500* | ~€1300 | €2499 |
* Total Price of the AR3 can vary based on component sourcing. See the available kits on the Annin Robotics site for a good idea but remember to also add in the electrical components since a kit for those doesn’t exist.
Up to this point, my favorite arm is the Annin Robotics AR3 but the build requirements give me pause. My second choice would be the Niryo Ned mostly for the equivalent openness and the company behind it (but that price…). The WLKata Mirobot offers a fine design and functionality for a modest price but my top concern there is that key parts are closed source and confidential. The company disappearing will very likely happen given enough time.
Then again, you can find used WLKata Mirobots for as low as €350 on Facebook and eBay which is hard to ignore.
Update: I found a used WLKata Mirobot on eBay for half price so I picked it up. A pre-assembled, fully programmable and very functional robotic arm for €700-800 is not bad even if it lacks some openness. It should arrive in a couple weeks. Despite finding this deal, I’m still thinking of undertaking the AR3 build. We’ll see.
Note: This article contains all of the info I could gather in a few days of research. It should all be correct but some bits may not. Feel free to contact me for any innaccuracies.
]]>