Self-moving robot – Embedded C internship

automotive mechanical engineering

Self-moving robot cars at the Embedded C internship for automotive mechanical engineering

Automotive mechanical engineering, Infrared, ultrasonic, microcontrollers, Arduino – do these sound familiar to you? If yes, chances are you know a bit of embedded and you are not so far away from engineering services. The automotive engineering team of AROBS is the most extended, it has an extensive automotive mechanical engineering expertise and it works for the leaders of automotive industry. We help create the cars of the future and we are offering automotive engineering jobs for the future experts in the field.

So, for the cars of the future, we are looking constanly for the future automotive mechanical engineering experts. This is exactly the case of our latest embedded internship graduates. The 6 youngsters today presented the robots they have created.
They were organized into 2 teams, each with its own approach towards how it should be done. The challenge was to create a self-moving robot that recognizes and avoids obstacles.

The embedded challenge

The teams received Arduino microcontrollers and other pieces of hardware. They had 2 months to create a working smart robot that could meet the challenges without using predefined libraries. They did everything from scratch.
Although they have faced multiple challenges the robots were ready and working on the day of the presentation.
They figured out that they had to combine infrared and ultrasonic sensors in a smart way using the benefits of both. Infrared for example does not react great with dark colors and ultrasound doesn’t recognize certain material like sponges.


The embedded interns surprised the mentors with their creativity. They proved their youthful creativity when it came to the robot and also when it came to the presentation.
The presentations were so funny and accurate that these technical youngsters engaged the whole auditorium for the whole presentation.
As we all know in the automotive industry great functionalities are not everything that matters. Design is just as important. So came the idea to one of the teams to create a body that is inspired by Elon Musk’s cybertruck. It was amazing. And it also… worked.
All eyes were on the miniature cybertruck.

The embedded experience for the automotive engineering jobs

One of the most important parts for them, based on their testimonials was the progress. Personal progress alongside professional progress in automotive mechanical engineering. One essential part of their experience was how to handle a tense situation in a team. It is not something you count on when you apply for and embedded C internship. However, it is essential to the output and to the collaborative process.

Here is what Dan, a 4th-year automation and computer science student said about the experience:


When we applied to the internship, we were told that we need to build an obstacle avoiding robot, in the C language, Atmel work environment to be more precise, with a mention: we needed to implement all the drivers from scratch, without the use of pre-existing libraries or modules. I’m not going to lie, when I heard about implementing the drivers from zero, I was not sure whether I would be able to do it since I had no before-hand experience with working on libraries, but I was up for a challenge and I decided to accept. Best decision I could make.

Agile – Git – Jira

We worked as two teams of three with the final goal of implementing a fully functional robot which avoids obstacles. Even though our mentors told us that it would not be a contest between the two teams, we still felt a bit pressured if the other team would be even just a bit ahead with the work than we were.
In the eight weeks we learned about the work environment (we tried working Agile, we used Git for version control which gave us some headaches before we got the hang of it, we used Jira to log our work), we learned to code better but most importantly, we learned the true importance of working in a team.


Our mentors were always there by our side in case we needed any help, even for the smallest of the tasks. This made me consolidate coding skills and I developed new good habits (like using naming conventions, commenting on the code, logging daily work and asking for help whenever I needed it), important for working in a software company.

Watch it for yourself

Watch how the robots handled obstacles. Remember, there is no remote involved. They are utterly alone on their paths.
All these talented young people found their way in AROBS and . We are so glad that you have #puzzledin.

Curious about what it is like to have one of our automotive engineering jobs and work in great projects for the cars of the future? Read more about the humans of automotive.

Looking for experts in automotive mechanical engineering? You found them, at AROBS!

AROBS become a major investor in SoftManager CRM+

softmanager crm+

AROBS becomes the main investor in SoftManager CRM+

AROBS Transilvania Software, a global player on the custom software development market, took over the majority of shares of SoftManager SRL Ploiesti, acquiring SoftManager CRM+ from Arroganet Solutions SRL.

SoftManager CRM+ is an Enterprise solutions product and its acquisition by AROBS is an inherent step that complements the experience of over 20 years in software development of the Cluj-based company.

SoftManager CRM+ has over 300 clients working in businesses related to sales, medical services, constructions, warehouses and more. Developed by an IT company in Ploiesti, SoftManager CRM+ streamlines interactions between companies and institutions’ clients and drew AROBS’ attention by its flexibility, ease of implementation and technical capacity of the team responsible for implementation. Voicu Oprean, Founder and CEO AROBS, trusts the technical team behind SoftManager CRM+, which is very well trained and competent. Thus, AROBS goes on with its growth strategy through Romanian and Eastern European acquisitions thereby consolidating its place on the market and offering increasingly better products and services for over 8000 clients.

SoftManager CRM+ is not just a software product, but a useful tool in implementing business strategies. It is a tool that can be used by any small or medium company. Although it is primarily created for the Romanian market, it may compete with well-known global solutions. The average cost for one user of the CRM+ is only 2 Romanian lei. It goes beyond a regular CRM, offering modules for production, invoicing, marketing, services, analysis, and many more – similar to an ERP system.

In more than 20 years since its establishment, AROBS Transilvania Software created products for both national and international markets (Optimall SFA, TrackGPS and so on) and specialized in offering software development solutions for various global industries such as Automotive Engineering, Travel Software, Hospitality Solutions, Life Sciences, Home Automation Systems, IoT Cloud application development for companies.

At the moment, over 900 employees and collaborators work in the Romanian AROBS offices – Cluj-Napoca, Targu Mures, Baia Mare, Arad, Suceava, Iasi, and Bucharest. Also, the 100% Romanian company, founded in 1998, has international subsidiaries in Germany, Hungary, Republic of Moldova, Indonesia, and, starting from 2018, CoSo by AROBS in Netherlands and Belgium.

The new acquisition is getting a lot of attention from the Romanian national media: 

The hard to swallow pills of test automation

Software testing services

The hard to swallow pills of test automation in software testing services

Topics of this articlesoftware testing services,QA automation, test automation.

About the author: Răzvan Vușcan is a software automation tester in our Travel&Hospitality Division

The idea of this article came to me after several experiences and lessons learned during my time doing test automation in software testing services for the travel industry. Most web applications have a great impact on travel software management. When I first started out, I was eager to learn, explore, but also try to do everything by the book. I figured I had to automate everything, and felt that the programming language and tools used at that time (Java and Selenium Webdriver) were my golden ticket to doing so. Well, since almost everybody was using these. I really felt that these two were foolproof for writing automated tests and that no web application could pose a challenge. And they did work out… for a while.

The process of software testing services

Then times changed. The software testing services became more complex, and the leading travel web applications I worked on starting moving away from their monolithic structure. The one written using conventional programming languages such as Java or .Net. Scripting languages like Javascript started gaining more and more ground. User interfaces were snappier, flashier. The conventional flow that would take users from one page to another was shifting towards single-page applications that were everything to loaded on the same page asynchronously.

Naturally, this complicates things and I felt that the tools I was using were becoming too pretentious for the new UIs. Tests were becoming flaky because they couldn’t handle event loading correctly or async animations and calls. So, initially, I started finding technical solutions to these problems. Since at the time I was doing only test automation for travel management software and no manual testing I could afford to implement all kinds of pieces of logic in order to deal with the technical issues in the test framework. But maintenance was starting to become a nightmare. I started spending way more time in maintaining tests instead of writing new content or running them.  Felt that I was getting nowhere. Afterward, I began to understand the test framework much better and started using the programming language a lot more than just for writing tests. I even built several new frameworks from scratch to experiment with different theories and approaches. Also, I worked a lot more on the Continuous Integration pipelines, trying to speed them up, split them in order for them to become more efficient, and generating better reports with a fast turn around time.

Don't forget your roots

But as I advanced down this developer/DevOps-like path, I was just moving away from my initial role as a tester. My technical solutions were becoming more and more complex, for example focusing too much on how to write logic to bypass a loading problem, instead of just admitting that perhaps the page/code is abnormally slow and bugging the developers to look into the issue and find a common solution.

So that was my wake-up call: I was spending too much finding overcomplicated solutions to obvious usability problems that could be a bother to a user, as well as doing WAY too much maintenance on the test automation framework and Continuous Integration pipelines.

Something had to be done. So I started doing some introspection, started by reviewing my system of values and figuring out why I wanted to be a tester in the first place. I remembered that things should be black and white when it came to testing: it’s either a bug or it’s not. Naturally, the next step was to review the automated tests in the travel management software I was working on. I noticed that these had become too long and too complex, taking too much time to run and, being so long, were prone to failure along the way. This meant that the rest of the steps were not being run and bits were no longer being tested. In short, I figured that oftentimes I would stop at the breaking point in a test invest a lot of time to do the maintenance there, but not spending too much time on the remaining part of the flow which was not run. So I had to figure out a solution of breaking up these tests who had become mammoths back into independent, atomic bits that focus on testing one thing.

Welcome the new in software testing services

Finally, the hardest thing to tackle was admitting that the testing tool and programming language I was using was not suited to the needs mentioned above. Applications User Interfaces were now being transformed through the power of React or Angular. Stuff like GWT or Drupal was being dropped in favor of the first two. So, I also needed to find a testing tool that worked well with the asynchronous calls of JavaScript on a webpage in order to spend less time doing maintenance and more time doing test scripting for the given project of software testing services.

Eventually, I found something that worked for me: NightwatchJs, which is an end-to-end test framework written in NodeJs. The learning curve was not that difficult and the switch from Java and Selenium Webdriver not as painful as I initially expected it. I loved the fact that Nightwatch was easy to integrate with Cucumber and could provide test reports written in a human-readable text which any user would understand. It also supported features being split into descriptive scenarios with clear steps. All in all, a powerful but easy to use and to maintain test framework which allowed me to focus more on writing end-to-end tests for the User Interface, but also had the potential for writing API layer tests because of it being written in NodeJs.

The lesson

I believe my greatest lesson learned was that sometimes you must let go and being anew instead of being stuck about using only one test tool or programming language. The best tool for the job isn’t always what’s being used by the masses. So, don’t be afraid to look for something better suited for your project, as I tried to find the one suitable for travel management software, in my case. If you end up wasting too much time on technical solutions or doing maintenance, then perhaps you should rethink your approach and analyze the direction you’re going before it’s too late.

If you want to read more about test automation and software testing services, find more articles about the subject HERE.

Do you need software testing services?

Write your message!

44-46, Henri Barbusse Street
Cluj-Napoca, 400616

Reactive extensions (Rx)

Reactive extensions

Reactive extensions - Introduction to reactive programming

Topics of this article: Rx, reactive programming, declarative programming, IoT systems, IObservable, IObserver

About the author: Bogdan Dobrea is an experienced .NET developer with a great curiosity towards discovering new technologies.

We all learned in school imperative programming, which has the advantage of being simple to explain and implement. This programming paradigm allows us to write a code where we describe, step by step, what we want to do. Hence, the result will be exactly predictable. It happens what we wanted to happen.
Let’s try to exemplify this using a real situation: an online store, where, through the browser, any user can look at products and place an order.


As an administrator of this online store, we would like to create an algorithm that returns the top /”rich” customers: for example, we want to find out how many customers have in their basket products that total at least 1000 Ron.

In the code, our client will be associated with the Customer class. We only need 2 properties, its name (Name) and the total of its shopping cart, expressed by the OrderAmount property. For simplicity, we will use Romanian lei (Ron) when we refer to the total of the basket.

The following examples are written in C#, but the subject of the article is not limited to this language, as we will find out later.




Our premise is that at one point, in our private virtual space there are 5 clients, each having a name as well as a basket of a certain value:

Our imperative algorithm, whereby we want to find out which of the 5 clients has spent at least 1000 RON could look like this:

In line with the definition of the imperative programming style mentioned at the beginning of the article, I described on each line, step by step, what I wanted to happen.

First, we created a new list of topSpendersList, then we went through the list of customers item by item, only interested in the name of the person whose shopping basket exceeds or is equal to 1000 Ron. At the end of the execution of this algorithm, we will notice that in the topSpendersList list we have 3 members (“Felicia”, “Robert” and “Fred”), because each of the 3 has spent at least 1000 Ron.

Declarative programming

Everything was fine so far, we found out what we needed. Now let’s see how we could rewrite this algorithm using the declarative programming model.
Declarative programming, in contrast to the imperative one, is a programming style in which the logic of a calculation is described, but without presenting the execution mode. Those familiar with .Net (C#, VB) already use this programming mode when writing code using LINQ:

In the lines of code above, the logic of a calculation is expressed (it selects from the customers list only the customers who have a value of the shopping cart at least equal to 1000 Ron, then using their name creates a new list), without having to write the action step by step. The source code for the Where(), Select() and ToList() functions is in the .NET Framework library.
The result of the execution of this algorithm will be the same as for the previous one. Therefore, the topSpendersList list will contain the same 3 members (“Felicia”, “Robert” and “Fred”).

Reactive programming

What does reactive mean? A common dictionary tells us that it is about a reaction to a stimulus.
To explain it more familiarly, I will use the well-known Excel spreadsheet, where we can have static cells as well as dynamic cells (for example, a formula). In the screenshot below, in column A we enter static values, and the first 2 cells in column D have the calculation formula, respectively the average of the first 10 values in column A. As a bonus, we added a 2D Chart with the help of to which we will represent a graph with the values in column A.

Each time we add, modify, or delete a value in a cell in column A, we notice that Sum, Average, and Graph 2D “reacts” to these changes.

Returning to our example, suppose that every time a new client appears on the site, we want the topSpendersList list to update itself with the name of the new client if it meets the condition imposed by us.

The examples written above will no longer work, because they depend on a fixed customer list, while we now have a customer flow.

And here come Reactive Extensions, which is a free library with which we can rewrite our algorithm so that it takes into account the fact that it has to “react” every time we have a new client.

Although there are more lines of code written than in the previous examples, we will find out that they are easy to understand, and we will use this pattern often in the future.

Let’s take them one at a time:

  • customersList is now of the ObservableCollection We need this because this type of list will invoke an event called CollectionChanged every time we change the elements inside it;
  • FromEventPattern creates a data flow from the CollectionChanged event that it listens to and drops us a new value each time we add a new client to the list;
  • SelectMany returns a customer list extracted from the NewItems property of NotifyCollectionChangedEventArgs;
  • Where it is already known to us, it will filter new customers and will only return those who have spent at least 1000 Ron;
  • At this data flow, we must subscribe using the Subscribe In the body of this method, we decide what we do with the new client who respects our condition: we add it to the topSpendersList.

If we run the new algorithm, without having any element in the customersList, we will see that nothing happens. As we add new elements, the algorithm will run and after its execution, topSpendersList will be populated.

After adding the 5 initial customers, in the topSpendersList we will find the names of the last 3 customers.

But now customersList is no longer a fixed list, so after we add the next 5, our algorithm will “react” to this action and add 3 more people (Phil, Anastacia and Aurora) in the topSpendersList:

Therefore, we can say that reactive programming is a model (paradigm) of declarative programming that focuses on data flows and the propagation of change.

The new syntax, which uses Observable and Subscribe keywords, will be accessible after we add the NuGet package called System.Reactive.

IObservable and IObserver

To better understand the example of reactive code, we need to talk a little about the 2 interfaces. Their definition is in the .NET Framework since version 4.0. However, their implementation is not in the framework, but in the System.Reactive library.

The easiest way to explain things is to make an analogy with a real-life situation. This is what we did with the online store, so we will do the same here. Let’s look at IObservable as a treadmill, which receives products at one end, and transports them to the other end. The products can be of different sizes and colors and can reach the treadmill at different time intervals. If the treadmill is working and there is no one at the other end, they will fall on the floor and thus be lost.

Reactive extensions
Reactive extensions

In order to prevent this from happening, we need a human operator to take those packages. In other words, it “subscribes” to the packet flow on the treadmill. The operator (or observer) implements the IObserver interface, which contains 3 methods: OnNext, OnError, and OnCompleted.

The observable(treadmill), from the moment it has a subscriber, will know how to use these methods as follows:

  • Whenever we have a new product on the tape, it will call the OnNext method, and the parameter sent will be the product itself;
  • If a tread failure occurs, it will call the OnError From this moment, the connection between the tread and the operator is eliminated, and even if new products will be produced on the treadmill, the operator will not know about them;
  • After all, packages are sent, the tape will call OnCompleted, and again the connection between the treadmill and the operator will be eliminated. Even if products will appear again, just like OnError, the operator will not know about them.

We notice that there is a close connection between IObservable and IObserver. Moreover, when we call Subscribe, IObservable will return an IDisposable, which is very useful, because when we no longer need this subscription, we simply call Dispose() on its instance. The System.Reactive library comes with another helper class called CompositeDisposable, in which we can add each subscription separately using the Add() method, and in the end, by calling Clear() at the CompositeDisposable instance, we remove all subscriptions, to assure the best memory management.

If we turn now to the reactive programming algorithm, we will realize that it makes more sense. For simplicity, in the body of the Subscribe method, we have written only a lambda expression that handles only the cases in which we have new clients (OnNext). Not cases of an error (OnError), nor is the situation in which the Observable calls OnCompleted when there are no new items.

Reactive extensions are also available for other programming languages, not just C#:

  • Java (RxJava)
  • Javascript (RxJS)
  • C ++ (UniRx)
  • Ruby (Rx.rb)
  • Python (RxPY)
  • PHP (RxPHP)
  • Swift (RxSwift)
  • Dart (RxDart)

See the official site, here.


This was, in short, an introduction to reactive programming. Reactive extensions can help us write easy-to-understand, scalable algorithms. These provide us with a helping hand in memory management (via CompositeDisposable). Last but not least, they can be a real help in asynchronous programming. The examples presented are the basis of this reactive thinking.

Reactive extensions also provide us with some very useful operators. Here is their short definition:

  • Skip() – emits the first n elements of an observable structure
  • Merge() – combines 2 or more observable streams
  • Throttle() – issues a new item only if a certain time has elapsed without another item being issued
  • Map() – transforms the current element, by applying a function to another element
  • Timer() – a much easier way to write classic .Net timers

Useful links:

public class Customer { public string Name { get; set; } public int OrderAmount { get; set; } public Customer(string name, int orderAmount) { Name = name; OrderAmount = orderAmount; } }