[Win11 builds miniconda’s pytorch1.12 environment]

Please don’t question the fact that I’ve been writing articles because my computer has been formatted and my needs have changed. This must be more in line with the times!
To lay the foundation for my GRCNN crawling, I used to run it on Ubuntu: [Robotic arm visual grabbing from theory to practice], yes, now I am running it on WIN11, there will be corresponding demonstration videos later Oh

1. Download miniconda

Official website address: https://docs.conda.io/projects/miniconda/en/latest/


Click Miniconda3 Windows 64-bit to download
If you want to experience the full functionality, you can download the full version: https://www.anaconda.com/download

2. Install miniconda

Run as administrator

Click next

Click I agree

Click next

Select the appropriate installation path and click Next

Click to select all. The second item must be checked. Here is to add environment variables to facilitate Vscode to find it later. Click to install.

Click Finish

Select application in the menu, search for miniconda, and open the miniconda terminal

# Check which virtual environments there are
conda env list
# Check which packages a certain virtual environment has
conda list
  

It is worth noting. If you use the conda environment to configure subsequent environments, you need to pay attention to the corresponding relationship between the python version and the versions of Pytorch, Tensorflow, etc.! The following installation and configuration are based on the system environment, not the conda environment.

3. miniconda source change

Replace conda with the domestic Tsinghua image source in the windows environment
or
step1 Enter the following command under Anaconda Prompt to generate the .condarc file

conda config --set show_channel_urls yes

step2 Find the .condarc file. Generally, the file is in the directory C:\Users\username.

step3 Open .condarc with Notepad and modify the content as follows:

channels:
  -defaults
show_channel_urls: true
default_channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
custom_channels:
  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch-lts: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  deepmodeling: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/

step4 Run conda clean -i to clear the index cache and ensure that the index provided by the mirror station is used.

conda clean -i

step5 Enter the following command to display the conda configuration information. The source change is successful! !

conda config --show

4. Install pytorch

Enter the following command.

nvidia-smi

As shown in the infographic below, you can see that the driver version is 528.02; the highest supported CUDA version is version 12.0. After getting the highest supported CUDA version of the graphics card, we can install the environment based on this information.

You need to choose the appropriate version according to your own development environment, please refer to: https://github.com/pytorch/vision

The following is the corresponding torchvision versions and supported Python
versions.

torch torchvision Python
main / nightly main / nightly >=3.8, <=3.11
2.1 0.16 >=3.8, <=3.11
2.0 0.15 >=3.8, <=3.11
1.13 0.14 >=3.7.2, <=3.10

older versions

torch torchvision Python
1.12 0.13 >=3.7 , <=3.10
1.11 0.12 >=3.7, <=3.10
1.10 0.11 >=3.6, <=3.9
1.9 0.10 >=3.6, <=3.9
1.8 0.9 >=3.6, <=3.9
1.7 0.8 >=3.6, <=3.9
1.6 0.7 >=3.6, <= 3.8
1.5 0.6 >=3.5, <=3.8
1.4 0.5 ==2.7, >=3.5, <=3.8
1.3 0.4.2 / 0.4.3 ==2.7, >=3.5, <=3.7
1.2 0.4.1 ==2.7, >=3.5, <=3.7
1.1 0.3 ==2.7, >=3.5, <=3.7
<=1.0 0.2 ==2.7, > =3.5, <=3.7

Considering that yolov8 is needed for later development, we created a python3.8.10 virtual environment `torch`= `1.12`, `torchvision` =`0.13`

# Create a new environment
conda create -n mytorch python==3.8.10
#Activate environment
conda activate mytorch
# Delete environment
conda remove -n mytorch --all
#Exit the current environment
conda deactivate

Enter y

Enter the mytorch environment

# Activate environment
conda activate mytorch

According to the one-click installation provided by the official website

#3. Install cuda. Note that 30 series requires cudatoolkit11 or above.

#CUDA 10.2
conda install pytorch==1.12.0 torchvision==0.13.0 torchaudio==0.12.0 cudatoolkit=10.2 -c pytorch
#CUDA 11.3
conda install pytorch==1.12.0 torchvision==0.13.0 torchaudio==0.12.0 cudatoolkit=11.3 -c pytorch
#CUDA 11.6
conda install pytorch==1.12.0 torchvision==0.13.0 torchaudio==0.12.0 cudatoolkit=11.6 -c pytorch -c conda-forge
# CPU Only
conda install pytorch==1.12.0 torchvision==0.13.0 torchaudio==0.12.0 cpuonly -c pytorch

5. Test whether the installation is successful

After activating the environment in the terminal, enter python and enter the following commands:

import torch
import torchvision

# This command displays the pytorch version
print(torch.__version__)

# If cuda is installed, true will be displayed
torch.cuda.is_available()

return

Sometimes you can use pip to temporarily change the image source.
When using the pip command to install packages in China, sometimes the installation speed is too slow due to foreign servers. If you use domestic mirror sources to install packages, the speed will be very fast. The following are domestic mirror sources:

Tsinghua: https://pypi.tuna.tsinghua.edu.cn/simple
Alibaba Cloud: http://mirrors.aliyun.com/pypi/simple/
Douban: http://pypi.douban.com/simple/
Just add the -i parameter after pip and the above mirror source. The example is as follows:

pip install requests -i http://mirrors.aliyun.com/pypi/simple/

6. Question:

If anaconda cannot be used, you can consider adding environment variables
illustrate
After installing Anaconda normally on the Win11 system, in the cmd command line window:

Set environment variables
1. This computer-"Properties-"Advanced system settings-"Environment variables

2. Find Path in the system variables and add the following two variables to Path

3. Test

At this point, OK! ! !

7. Summary

No matter how the environment is updated, as long as you grasp its essence, everything will take care of itself.

import os
import time

import matplotlib.pyplot as plt
import numpy as np
import torch

from UR_Robot_real import UR_Robot_real
from inference.post_process import post_process_output
from utils.data.camera_data import CameraData
from utils.dataset_processing.grasp import detect_grasps
from utils.visualisation.plot import plot_grasp
import cv2
from PIL import Image
import torchvision.transforms as transforms
importyaml
import pyrealsense2 as rs
from ultralytics.yolo.utils.torch_utils import select_device, time_sync
# from utils.general import (
# check_img_size, non_max_suppression, apply_classifier, scale_coords,
# xyxy2xywh, strip_optimizer, set_logging)
from ultralytics.yolo.utils.checks import check_imgsz
from ultralytics.yolo.utils.ops import non_max_suppression, scale_coords
from ultralytics.yolo.utils import LOGGER
from ultralytics import YOLO
from ultralytics.yolo.data.dataloaders.v5loader import LoadStreams, LoadImages, letterbox
# from models.experimental import attempt_load,
from ultralytics.nn.tasks import attempt_load_weights, attempt_load_one_weight
from ultralytics import YOLO
tool_xyz = np.asarray([-0.1, 0.25, 0.34])
tool_orientation = np.asarray([-np.pi,0,0])
hole_xyz = np.asarray([-0.105, -0.305, 0.345])
hole_orientation = np.asarray([np.pi/2,np.pi,0])
camera_target_position = np.asarray([[0],[0],[0],[1]])
target_position = np.asarray([-0.105, -0.305, 0.345])
image_wide_size = 640
image_high_size = 480
#PyTorch
#YoloV5-PyTorch



BH_yaml_path = 'weights/yolov8n.yaml'
with open(BH_yaml_path, 'r', encoding='utf-8') as f:
    yolov8 = yaml.load(f.read(), Loader=yaml.SafeLoader)

color_dict = {<!-- -->} # Create an empty dictionary to store the correspondence between numbers and colors

# Generate colors for each category
for class_id in range(yolov8['nc']):
    color = [np.random.randint(0, 255) for _ in range(3)] # Generate a random color
    color_dict[class_id] = color # Add numbers and colors to the dictionary



class PlaneGraspClass:
    def __init__(self, saved_model_path=None,use_cuda=True,visualize=False,include_rgb=True,include_depth=True,output_size=300):
        if saved_model_path==None:
             saved_model_path = 'logs\230802_1421_training_jacquard\epoch_30_iou_1.00'
            # saved_model_path = 'trained-models/jacquard-rgbd-grconvnet3-drop0-ch32/epoch_48_iou_0.93'
        self.model = torch.load(saved_model_path)
        # Path to YOLOV5 model configuration file (YAML format) yolov5_yaml_path
        self.model1 = YOLO("weights/best1.pt")
        # model = YoloV8(yolov8_yaml_path='ultralytics/models/v8/yolov8.yaml')
        print("[INFO] YoloV8 model loading completed")
        self.device = "cuda:0" if use_cuda else "cpu"
        self.visualize = visualize

        self.cam_data = CameraData(include_rgb=include_rgb,include_depth=include_depth,output_size=output_size)

        # Load camera pose and depth scale (from running calibration)
        self.ur_robot = UR_Robot_real(tcp_host_ip="192.168.56.10", tcp_port=30003, workspace_limits=None, is_use_robotiq85=True,
                            is_use_camera=True)
        self.cam_pose = self.ur_robot.cam_pose
        self.cam_depth_scale = self.ur_robot.cam_depth_scale
        self.intrinsic = self.ur_robot.cam_intrinsics

        if self.visualize:
            self.fig = plt.figure(figsize=(6, 6))
        else:
            self.fig = None

    def get_aligned_images(self):
        # frames = pipeline.wait_for_frames() # Wait to get image frames
        # aligned_frames = align.process(frames) # Get aligned frames
        # aligned_depth_frame = aligned_frames.get_depth_frame() # Get the depth frame in the aligned frame
        # color_frame = aligned_frames.get_color_frame() # Get the color frame in the aligned frame
        aligned_depth_frame, color_frame= self.ur_robot.get_camera_data1() # meter

        ############### Obtaining camera parameters #######################
        intr = color_frame.profile.as_video_stream_profile().intrinsics # Get camera intrinsic parameters
        depth_intrin = aligned_depth_frame.profile.as_video_stream_profile(
        ).intrinsics # Get depth parameters (used to convert pixel coordinate system to camera coordinate system)
        '''camera_parameters = {'fx': intr.fx, 'fy': intr.fy,
                            'ppx': intr.ppx, 'ppy': intr.ppy,
                            'height': intr.height, 'width': intr.width,
                            'depth_scale': profile.get_device().first_depth_sensor().get_depth_scale()
                            }'''

        # Save internal parameters to local
        # with open('./intrinsics.json', 'w') as fp:
        # json.dump(camera_parameters, fp)
        ################################################ #####

        depth_image = np.asanyarray(aligned_depth_frame.get_data()) # Depth image (default 16 bits)
        depth_image_8bit = cv2.convertScaleAbs(depth_image, alpha=0.03) # Depth image (8 bits)
        depth_image_3d = np.dstack(
            (depth_image_8bit, depth_image_8bit, depth_image_8bit)) # 3-channel depth map
        color_image = np.asanyarray(color_frame.get_data()) # RGB image

        # Return camera internal parameters, depth parameters, color images, depth images, and depth frames in all frames
        return intr, depth_intrin, color_image, depth_image, aligned_depth_frame


    def camera_xyz_list_function(self):
        # Wait for a coherent pair of frames: depth and color
        intr, depth_intrin, color_image, depth_image, aligned_depth_frame = self.get_aligned_images() # Get aligned images and camera internal parameters
        time.sleep(4)
        intr, depth_intrin, color_image, depth_image, aligned_depth_frame = self.get_aligned_images() # Get aligned images and camera internal parameters
        # Convert images to numpy arrays
        # Apply colormap on depth image (image must be converted to 8-bit per pixel first)
        depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(
            depth_image, alpha=0.03), cv2.COLORMAP_JET)
        # Stack both images horizontally
        images = np.hstack((color_image, depth_colormap))

        # Show images
        camera_xyz_list = []
        t_start = time.time() # Start timing
        #YoloV8 Object Detection
        results = self.model1.predict(color_image)
        xyxy_list = results[0].boxes.xyxy
        conf_list = results[0].boxes.conf
        class_id_list = results[0].boxes.cls
        canvas = np.copy(color_image)

        t_end = time.time() # End timing
        for i in range(len(xyxy_list)):
            if conf_list[i] > 0.6:
                x_min = int(xyxy_list[i][0])
                y_min = int(xyxy_list[i][1])
                x_max = int(xyxy_list[i][2])
                y_max = int(xyxy_list[i][3])
                if x_min < image_wide_size and y_min < image_high_size and x_max < image_wide_size and y_max < image_high_size:
                    dis_min = aligned_depth_frame.get_distance(x_min, y_min)
                    dis_max = aligned_depth_frame.get_distance(x_max, y_max)
                    dis = (dis_min + dis_max) / 2
                    ux = int((x_min + x_max) / 2)
                    uy = int((y_min + y_max) / 2)
                    camera_xyz = rs.rs2_deproject_pixel_to_point(
                        depth_intrin, (ux, uy), dis) # Calculate the xyz of the camera coordinate system
                    camera_xyz = np.round(np.array(camera_xyz), 3) # Convert to 3 decimal places
                    camera_xyz = camera_xyz.tolist()
                    camera_xyz_list.append(camera_xyz)

                    num_cls = int(class_id_list[i].item())
                    label = '%s ' % (yolov8['class_name'][num_cls])
                    color = color_dict[num_cls]

                    cv2.putText(canvas, label + str(round(conf_list[i].item(), 2)),
                                (int(xyxy_list[i][0]), int(xyxy_list[i][1])), cv2.FONT_HERSHEY_SIMPLEX, 1,
                                (255, 255, 255),
                                2)
                    cv2.rectangle(canvas, (int(xyxy_list[i][0]), int(xyxy_list[i][1])),
                                    (int(xyxy_list[i][2]), int(xyxy_list[i][3])), color, 2)

                    cv2.circle(canvas, (ux, uy), 4, (255, 255, 255), 5) # Mark the center point
                    cv2.putText(canvas, str(camera_xyz), (ux + 20, uy + 10), 0, 1,
                                [225, 255, 255], thickness=2, lineType=cv2.LINE_AA) # Mark the coordinates
                    fps = int(1.0 / (t_end - t_start))
                    cv2.putText(canvas, text="FPS: {}".format(fps), org=(50, 50),
                                fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, thickness=2,
                                lineType=cv2.LINE_AA, color=(0, 0, 0))
                    cv2.namedWindow('detection', flags=cv2.WINDOW_NORMAL |
                                                        cv2.WINDOW_KEEPRATIO | cv2.WINDOW_GUI_EXPANDED)
                    cv2.imshow('detection', canvas)
        return camera_xyz_list, t_end, t_start, canvas

    def generate(self):
        target1_position= [0,0,0]
        destination1=np.append(hole_xyz,hole_orientation)
        self.ur_robot.move_j_p(destination1)
        xyz_list, t_end, t_start, canvas = self.camera_xyz_list_function()
        xyz_list = np.asarray(xyz_list)
        index=xyz_list.shape[0]
        print(xyz_list)
        # target1_position[0] = hole_xyz[0] + xyz_list[0,0]-0.043
        # target1_position[1] = hole_xyz[1]- xyz_list[0,2] + 0.28
        # target1_position[2] = hole_xyz[2] + xyz_list[0,1] + 0.075
        # target1_position= np.asarray(target1_position)
        # target1_position = np.append(target1_position,hole_orientation)
        # print(target1_position)
        # self.ur_robot.move_j_p(target1_position)
        for i in range(index):

        # time.sleep(1.5)
        # # Add fps display

            self.ur_robot.move_j([-(0 / 360.0) * 2 * np.pi, -(90 / 360.0) * 2 * np.pi,
                             (0 / 360.0) * 2 * np.pi, -(90 / 360.0) * 2 * np.pi,
                             -(0 / 360.0) * 2 * np.pi, 0.0])# return home
        # time.sleep(1.5)

        ## if you want to use RGBD from camera,use me
        # Get RGB-D image from camera
            grasp_home = np.append(tool_xyz,tool_orientation)
            self.ur_robot.move_j_p(grasp_home)
            time.sleep(1.5)
            rgb, depth= self.ur_robot.get_camera_data() # meter
            depth = depth *self.cam_depth_scale
            depth[depth >1]=0 # distance > 1.2m,remove it

            ## if you don't have realsense camera, use me
            # num =2 # change me num=[1:6],and you can see the result in '/result' file
            # rgb_path = f"./cmp{num}.png"
            # depth_path = f"./hmp{num}.png"
            # rgb = np.array(Image.open(rgb_path))
            # depth = np.array(Image.open(depth_path)).astype(np.float32)
            # depth = depth * self.cam_depth_scale
            # depth[depth > 1.2] = 0 # distance > 1.2m,remove it
            depth= np.expand_dims(depth, axis=2)
            x, depth_img, rgb_img = self.cam_data.get_data(rgb=rgb, depth=depth)
            time.sleep(1.5)
            x, depth_img, rgb_img = self.cam_data.get_data(rgb=rgb, depth=depth)
            rgb = cv2.cvtColor(rgb,cv2.COLOR_BGR2RGB)

            with torch.no_grad():
                xc = x.to(self.device)
                pred = self.model.predict(xc)
            q_img, ang_img, width_img = post_process_output(pred['pos'], pred['cos'], pred['sin'], pred['width'])

            grasps = detect_grasps(q_img, ang_img, width_img)
            # np.save(self.grasp_pose, grasp_pose)
            if self.visualize:
                plot_grasp(fig=self.fig, rgb_img=self.cam_data.get_rgb(rgb, False), grasps=grasps, save=True)

            if len(grasps) ==0:
                print("Detect 0 grasp pose!")
                if self.visualize:
                    plot_grasp(fig=self.fig, rgb_img=self.cam_data.get_rgb(rgb, False), grasps=grasps, save=True)
                return False
            ## For real UR robot
            # Get grasp position from model output
            pos_z = depth[grasps[0].center[0] + self.cam_data.top_left[0], grasps[0].center[1] + self.cam_data.top_left[1]]
            pos_x = np.multiply(grasps[0].center[1] + self.cam_data.top_left[1] - self.intrinsic[0][2],
                                pos_z / self.intrinsic[0][0])
            pos_y = np.multiply(grasps[0].center[0] + self.cam_data.top_left[0] - self.intrinsic[1][2],
                                pos_z / self.intrinsic[1][1])
            if pos_z == 0:
                return False

            target = np.asarray([pos_x, pos_y, pos_z])
            target.shape = (3, 1)

            # Convert camera to robot coordinates
            camera2tool = self.cam_pose
            target_position = self.ur_robot.target1_position(camera2tool, tool_orientation, tool_xyz, target)
            # print(target_position)
            # Convert camera to robot angle
            angle = np.asarray([0, 0, grasps[0].angle])
            angle.shape = (3, 1)
            target_angle = self.ur_robot.target1_angle(camera2tool, tool_orientation, angle)
            angle.shape = (1,3)
            # print(target_angle)
            # target_angle = np.dot(camera2robot[0:3, 0:3], angle)

            # compute gripper width
            width = grasps[0].length # mm
            if width < 25: # detect error
                width=70
            elif width <40:
                width =45
            elif width > 85:
                width=85

            # Concatenate grasp pose with grasp angle
            grasp_pose = np.append(target_position, target_angle[2])
            print('grasp_pose: ', grasp_pose)
            print('grasp_width: ',grasps[0].length)
            destination=np.append([grasp_pose[0],grasp_pose[1],grasp_pose[2]],tool_orientation)
            print(destination)
            # self.ur_robot.move_j_p(destination)
            # hole targrt destination
            target1_position[0] = hole_xyz[0] + xyz_list[i,0]-0.037
            target1_position[1] = hole_xyz[1]- xyz_list[i,2] + 0.18
            target1_position[2] = hole_xyz[2] + xyz_list[i,1] + 0.066
            target1_position= np.asarray(target1_position)
            target1_position = np.append(target1_position,hole_orientation)
            print(target1_position)
            # self.ur_robot.move_j_p(target1_position)
            # target_position[0] = hole_xyz[0] + xyz_list[i,0]
            # target_position[1] = hole_xyz[1]- xyz_list[i,2] + 0.25
            # target_position[2] = hole_xyz[2] + xyz_list[i,1]
            # target_position = np.append(target_position,hole_orientation)
            # self.ur_robot.move_j_p(target_position)
            success = self.ur_robot.plane_grasp_hole([grasp_pose[0],grasp_pose[1],grasp_pose[2]],target1_position, yaw=grasp_pose[3], open_size=width/100)
            if success==True:
                print("success:",i + 1)
            elif success==False:
                print("unsuccess")
                break
        print("Grasp and full success:",i + 1)
        self.ur_robot.move_j([-(0 / 360.0) * 2 * np.pi, -(90 / 360.0) * 2 * np.pi,
                             (0 / 360.0) * 2 * np.pi, -(90 / 360.0) * 2 * np.pi,
                             -(0 / 360.0) * 2 * np.pi, 0.0])# return home

        ## For having not real robot
        # if self.visualize:
        # plot_grasp(fig=self.fig, rgb_img=self.cam_data.get_rgb(rgb, False), grasps=grasps, save=True)
        # return True


if __name__ == '__main__':
    g = PlaneGraspClass(
        # saved_model_path='/home/robot/UR_grasping_net/robotic-grasping-explosives/logs/230801_0934_training_jacquard/epoch_34_iou_1.00',
        # saved_model_path='/home/robot/UR_grasping_net/robotic-grasping-explosives/logs/230801_2225_training_jacquard/epoch_44_iou_1.00',
        saved_model_path = 'logs/230802_0918_training_jacquard/epoch_31_iou_1.00',
        # saved_model_path='/home/robot/UR_grasping_net/robotic-grasping-explosives/logs/230802_1421_training_jacquard/epoch_20_iou_1.00',
        visualize=True,
        include_rgb=True
    )
    g.generate()