Raspberry Pi is not able to subscribe to ros topic published from base PC but vice-verse is working? - ssh

I am using the ubiquityrobotics Raspberry Pi image for the RPi 3B+, which is Ubuntu Xenial and ROS Kinetic. My base computer is running Ubuntu 18.04 and has ROS Melodic installed.
I created subo_base workspace in the base PC and subo_rpi workspace in the RPi (assessing the RPi via ssh).
Then I created a package in both the base PC and RPi and added the Publisher and Subscriber (http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28python%29) files in each of the packages.
When I run the publisher from the RPi, the base PC is able to subscribe but when I publish from the base PC, the RPi does not show any output and remains stuck (even though the Topic is visible on RPi using rostopic list).
Base PC is able to subscribe to RPi
RPi unable to subscribe to topic from PC
Some of the code is used in base PC
aakash#aakash:~$ mkdir -p ~/subo_base/src
aakash#aakash:~$ cd ~/subo_base/
aakash#aakash:~/subo_base$ catkin_make
aakash#aakash:~/subo_base$ source devel/setup.bash
aakash#aakash:~/subo_base$ echo $ROS_PACKAGE_PATH
aakash#aakash:~/subo_base$ cd ~/subo_base/src/
aakash#aakash:~/subo_base/src$ catkin_create_pkg motion_plan std_msgs rospy roscpp
To connect to RPi
aakash#aakash:~/subo_base/src/motion_plan/scripts$ export ROS_MASTER_URI=http://ubiquityrobot.local:11311
aakash#aakash:~/subo_base/src/motion_plan/scripts$ export ROS_IP='hostname -I'
Further, I am able to transfer files from and to the base PC via ssh scp so I guess netwkr might not be the issue?

The issue is most likely the hostname resolution and/or ROS network variable configuration.
I dislike using the hostname in the variables, so I will give the examples using just IPs.
Also the 'hostname -I' is definitely not suitable for setting your ROS_IP variable in all cases. So that might also be one source of your problem.
From hostname man page
-I, --all-ip-addresses>
Display all network addresses of the host. This option enumerates all configured addresses on all network interfaces. The loop‐back interface and IPv6 link-local addresses are omitted. Contrary to option -i, this option does not depend on name resolution. Do not make any assumptions about the order of
the output.
You will want to use whatever specific ip address you need, so just use that or find a better way to determine which ip to set. echo $ROS_IP or printenv | grep ROS will tell you what your variables are currently set to so you can verify it is set correctly.
For minimal proof that things are working you could try the following:
Lets say your RPi ip is 192.168.0.2 and PC ip is 192.168.0.3
You will need to decide which machine will be the master, for this example I will assume the PC will be the master.
In a terminal on the PC run the following commands:
roscore
in a different terminal run (this is used instead of the subscriber/publisher node to test if things work)
rostopic pub /test/topic std_msgs/String 'Hello World from PC' -r 1
Now on the SSH terminal on the RPi run:
export ROS_MASTER_URI=http://192.168.0.3:11311 && export ROS_IP=192.168.0.2
now you should be able to echo the topic published on the PC from the SSH window.
rostopic echo /test/topic
ctrl+c out of the echo and you can try publishing some message on the RPi like:
rostopic pub /test2/topic std_msgs/String 'Hello World from RPi' -r 1
Now open a new terminal on the PC and try to echo the topic from RPi, any terminal sourced with the ROS installspace, usually source /opt/ros/kinetic/setup.bash, should work:
rostopic echo /test2/topic
ROS wiki page on running ROS on multiple machines
ROS answer regarding setting up multiple machines

ROS1
Machine1 [MASTER]:
Will run roscore, but don't run it yet till configurations are done.
Has an IP of 192.168.1.10.
1- Run the following in the terminal:
1.1- export ROS_MASTER_URI=http://192.168.1.10:11311.
1.2- export ROS_IP=192.168.1.10.
2- Now, run roscore.
Machine2 [SLAVE]
Will NOT run roscore.
Has and IP 192.168.1.15.
1- Run the following in the terminal:
1.1- export ROS_MASTER_URI=http://192.168.1.10:11311.
1.2- export ROS_IP=192.168.1.15.
2- Now, you are connected to the Master.
ROS2
ROS2 will populate the information on the LAN out of the box without any configuration.

Related

Powercli to set "Autostart" on VM on ESXI not working

I am using versions:
ESXI 6.5.0 Update 3 (Build 14990892)
Power CLI VMware PowerCLI 11.0.0 build 10380590.
I have a VM that I am importing (ISO) into an ESXI and trying to set Autostart on the VM to "enabled" programmatically via some scripts, but it is not working. I am using the powercli command:
Set-VMHostStartPolicy (Get-VMHost | Get-VMHostStartPolicy) -Enabled:$true
I've also tried some variants of this command but none seem to work. I see the "event" get logged as "Reconfigure Autostart" under the "Recent Tasks" menu on the ESXI Web GUI as soon as I input the command, so its definitely configurating something, but when I double-check the state of the VM to see if Autostart is enabled, it still lists "Enable" as an option, implying Autostart is NOT enabled. Here's a screenshot:
Can anyone help me please? I just want to have this VM start automatically incase there is a power outage or server crash; But only in these cases, I want it to import powered OFF for the first time (as you can see in screen shot the EPS VM is imported but in a powered down state, which is what I want)
I think what you're doing is setting the host's default policy... You would think that would work. I'm using this code on ESXi 7.0 Update 1 to set the guest's policy:
$vmstartpolicy = Get-VM "$vm_name" | Get-VMStartPolicy
Set-VMStartPolicy -StartPolicy $vmstartpolicy -StartAction PowerOn
It has the same issue that it doesn't show in the web UI, (which somebody will complain about, and I'll have to fix) but it does auto-start the VM after a reboot, so at least it's a start (pun not intended).
Edit: After playing around a bit, I managed to find a solution that updates the UI.
plink -batch -ssh $user#$IP -l "$user" -pw "$password" vim-cmd hostsvc/autostartmanager/update_autostartentry "`$(vim-cmd vmsvc/getallvms | grep `"$vm_name`" | awk '{print `$1}')" "PowerOn" 0 1 "systemDefault" "systemDefault" "systemDefault"
Using plink to ssh into the host and run this vim-cmd, it updates the UI properly. Take note of the back-ticks (`) to escape the dollar signs (except the one with the $vm_name variable) and quotes in the sub command, so that powershell doesn't try to interpret them before sending them through the ssh tunnel. All the sub command does is get the all the VMs, use grep to filter down to the output line with the vm_name you specify, and use awk to print only the 1st column (the vm id required for the outer vim-cmd).

packer vmware iso local and on esxi

I am curious to find out why packer is failing to get ssh access on an ESXi server. The build works just fine for vmware_fusion locally.
As JSON does not seem to display nicely directly here on SF - a link to a gist with the builder configuration: https://gist.github.com/geoHeil/5acf06cb0f3afadfa347d437c2695a7c
When running
packer build -var-file variables.json -only=vmwarevmwareRemote template.json
the kickstart file is loaded, configured and installed. However, in the case of ESXi as the builder the build seems to be stuck on waiting for SSH to become available.
I noticed in the logs that:
/var/log/auth.log
2017-02-08T17:33:20Z sshd[94210]: User 'root' running command 'esxcli --formatter csv network vm list\n'
2017-02-08T17:33:25Z sshd[94210]: User 'root' running command 'esxcli --formatter csv network vm list\n'
displays a lot of the same commands.
Executing this command manually shows
esxcli --formatter csv network vm list
Name,Networks,NumPorts,WorldID,
ubunu-test,"VM Network,",1,87986,
someOther,"VM Network,",1,84833,
What could be wrong here?
edit
packer version is latest 0.12.2, esxi 6.5
edit2
when applying the suggestion of setting a network the same problem persists. But now I see 2 commands in the logs
[root#vm-bd-dev:/var/log] tail -f auth.log
2017-02-09T09:05:56Z sshd[111376]: User 'root' running command 'esxcli --formatter csv network vm list\n'
2017-02-09T09:05:56Z sshd[111376]: User 'root' running command 'esxcli --formatter csv network vm port list -w 111433\n'
The second (new) one has the following output:
ActiveFilters,DVPortID,IPAddress,MACAddress,PortID,Portgroup,TeamUplink,UplinkPortID,vSwitch,
,,0.0.0.0,00:0c:29:47:d5:3d,33554450,VM Network,vmnic2,33554437,vSwitch0,
You probably need some more vmx_data settings for the network, something like:
"vmx_data": {
"ethernet0.networkName": "VM Network",
"ethernet0.present": "true",
"ethernet0.virtualDev": "vmxnet3",
"ethernet0.startConnected": "true",
"ethernet0.addressType": "generated"
}
Switching the network interface to something not hard coded like
network --bootproto=dhcp --ipv6=auto --activate
solved the problem for me.
Apparently different interfaces (no eth0) were available on ESXi.

How to enable X11 forwarding in PyCharm SSH session?

The Question
I'm trying to enable X11 forwarding through the PyCharm SSH Terminal which can be executed via
"Tools -> Start SSH session..."
Unfortunately, It seems there is no way of specifying the flags like I would do in my shell for enabling the X11 Forwarding:
ssh -X user#remotehost
Do you know some clever way of achieving this?
Current dirty solution
The only dirty hack I found is to open an external ssh connection with X11 forwarding and than manually update the environment variable DISPLAY.
For example I can run on my external ssh session:
vincenzo#remotehost:$ echo $DISPLAY
localhost:10.0
And than set on my PyCharm terminal:
export DISPLAY=localhost:10.0
or update the DISPLAY variable in the Run/Debug Configuration, if I want to run the program from the GUI.
However, I really don't like this solution of using an external ssh terminal and manually update the DISPLAY variable and I'm sure there's a better way of achieving this!
Any help would be much appreciated.
P.s. Making an alias like:
alias ssh='ssh -X'
in my .bashrc doesn't force PyCharm to enable X11 forwarding.
So I was able to patch up jsch and test this out and it worked great.
Using X11 forwarding
You will need to do the following to use X11 forwarding in PyCharm:
- Install an X Server if you don't already have one. On Windows this might be the VcXsrv project, on Mac OS X the XQuartz project.
- Download or compile the jsch package. See instructions for compilation below.
- Backup jsch-0.1.54.jar in your pycharm's lib folder and replace it with the patched version. Start Pycharm with a remote environment and make sure to remove any instances of the DISPLAY environment variable you might have set in the run/debug configuration.
Compilation
Here is what you need to do on a Mac OS or Linux system with Maven installed.
wget http://sourceforge.net/projects/jsch/files/jsch/0.1.54/jsch-0.1.54.zip/download
unzip download
cd jsch-0.1.54
sed -e 's|x11_forwarding=false|x11_forwarding=true|g' -e 's|xforwading=false|xforwading=true|g' -i src/main/java/com/jcraft/jsch/*.java
sed -e 's|<version>0.1.53</version>|<version>0.1.54</version>|g' -i pom.xml
mvn clean package
This will create jsch-0.1.54.jar in target folder.
Update 2020:
I found a very easy solution. It may be due to the updated PyCharm version (2020.1).
Ensure that X11Forwarding is enabled on server: In /etc/ssh/sshd_config set
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost no
On client (MacOS for me): In ~/.ssh/config set
ForwardX11 yes
In PyCharm deselect Include system environment variables. This resolves the issue that the DISPLAY variable gets set to the system variable.
EDIT: As seen in the below image it works. For example I used the PyTorch implementation of DeepLab and visualize sample images from PASCAL VOC:
X11 forwarding was implemented in 2021.1 for all IntelliJ-based IDEs. If it still doesn't work, please consider creating a new issue at youtrack.jetbrains.com.
By the way, the piece of advice about patching jsch won't work for any IDE newer than 2019.1.
In parallel, open MobaXTerm and connect while X11 forwarding checkbox is enabled. Now PyCharm will forward the display through MobaXTerm X11 server.
This until PyCharm add this 'simple' feature.
Also, set DISPLAY environment variable in PyCharm run configuration like this:
DISPLAY=localhost:10.0
(the right hand side should be obtained with the command echo $DISPLAY in the server side)
Update 2022: for PyCharm newer than 2022.1: Plotting in SciView works by only setting ForwardX11 yes in .ssh/config (my laptop OS is ubuntu 22.04). I did not set any other parameters either on the server or local side.

reboot VM (run on vbox) into specific (compiled) kernel from shell

Im running ubuntu 14.04 with vbox . In this machine I compiled and run kernel 3.14 which I choose from the grub menu when ubuntu load on vbox.
The host also run on ubuntu 14.04.
I wanted to ask - is there a way to load the guest ubuntu into specific kernel with a command on shell?
I can start running a vm on vbox trough command line with this command :
VBoxManage startvm ubuservloc --type headless
but its not quite exactly what I need.
I don't know of any way to directly communicate from the host to the guest's GRUB, but there are several indirect ways you could go:
mount the /boot filesystem from the host and drop a file there that is read by the guest's grub.cfg.
VBoxManage controlvm keyboardputscancode to type a hotkey which is assigned to the correct kernel in GRUB (shortly after starting the VM)
Configure GRUB to listen to a (virtual) serial port and select the kernel by writing to that file
In case a second reboot is acceptable (first boot into default kernel and then reboot into desired kernel) there are also several ways (you can use the grub-set-default command from guest to choose your desired kernel and issue a reboot). Some I can think of here:
VBoxManage guestcontrol run to call a shell script from host in the guest (after guest additions have been loaded)
VBoxManage guestproperty to set a property from host and VBoxControl guestproperty to read it from an init script and decide from there
Just SSH into the guest and reboot from there :D
Obviously, if you always want to boot that kernel, why not make it default? And in case always you want to alternately boot two different kernels, you can also set the default for next boot to another one direclty from grub.cfg.

Is there a way I can have a VM gain access to my computer?

I would like to have a VM to look at how applications appear and to develop OS-specific applications, however, I want to keep all my code on my Windows machine so if I decide to nuke a VM or anything like that, it's all still there.
If it matters, I'm using VirtualBox.
This is usually handled with network shares. Share your code folder from your host machine and access it from the VMs.
Aside from network shares, another tool to use for this is a version-control system.
You should always be able make a normal network connection between the VM and the hosting OS, as though it were another computer on the same network. Which, in some sense, it is.
I do this all the time.
I have a directory in a Windows drive that I mount in my host ubuntu 12.04.
I run virtualbox ubuntu 13.04 as a guest.
I want the guest to mount the Windows directory with full non-root permissions.
I do almost all my work from a bash shell, so this method is natural for me.
When searching for methods to automatically mount virtualbox shared folders,
reliable and correct methods are hard to distinguish from those that fail.
Failures include getting and setting permissions, as well as other problems.
Methods that fail include:
modifying /etc/fstab
modifying /etc/rc.local
I am fairly certain that rc.local can be used,
but no methods I have tried worked.
I welcome improvements on these guidelines.
On virtualbox 4.2.14 running nautilus (bash terminal) on an ubuntu 13.04 guest,
Below is a working method to mount Common (sharename)
on /home/$USER/Desktop/Common (mountpoint) with full permissions.
(Note the ‘\’ command continuation character in the find command.)
First time only: create your mountpoint, modify your .bashrc file, and run it.
Respond with password when requested.
These are the four command-lines needed:
mkdir $HOME/Desktop/Common
sudo echo “$USER ALL=(ALL) NOPASSWD:ALL” >> /etc/sudoers
find $HOME/Desktop/Common -maxdepth 0 -type d -empty -exec sudo \
mount -t vboxsf -o \
uid=`id -u $USER`,gid=`id -g $USER` Common $HOME/Desktop/Common \;
source ~/.bashrc # Needed if you want to mount Common in this bash.
All other times: simply launch a bash shell.
The find command mounts the shared directory if the mountpoint directory is empty.
If the mountpoint directory is not empty, it does not run the mount command.
I hope this is error-free and sufficiently general.
Please let me know of corrections and improvements.